feat: add table td border type
This commit is contained in:
@@ -419,6 +419,16 @@ Usage:
|
|||||||
instance.command.executeTableBorderType(payload: TableBorder)
|
instance.command.executeTableBorderType(payload: TableBorder)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## executeTableTdBorderType
|
||||||
|
|
||||||
|
Feature: Table td border type
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
instance.command.executeTableTdBorderType(payload: TableBorder)
|
||||||
|
```
|
||||||
|
|
||||||
## executeTableTdBackgroundColor
|
## executeTableTdBackgroundColor
|
||||||
|
|
||||||
Feature: Table cell background color
|
Feature: Table cell background color
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ interface ILang {
|
|||||||
borderAll: string
|
borderAll: string
|
||||||
borderEmpty: string
|
borderEmpty: string
|
||||||
borderExternal: string
|
borderExternal: string
|
||||||
|
borderTd: string
|
||||||
|
borderTdBottom: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
datePicker: {
|
datePicker: {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ interface IElement {
|
|||||||
rowspan: number;
|
rowspan: number;
|
||||||
verticalAlign?: VerticalAlign;
|
verticalAlign?: VerticalAlign;
|
||||||
backgroundColor?: string;
|
backgroundColor?: string;
|
||||||
|
borderType?: TdBorder;
|
||||||
value: IElement[];
|
value: IElement[];
|
||||||
}[];
|
}[];
|
||||||
}[];
|
}[];
|
||||||
|
|||||||
@@ -419,6 +419,16 @@ instance.command.executeTableTdVerticalAlign(payload: VerticalAlign)
|
|||||||
instance.command.executeTableBorderType(payload: TableBorder)
|
instance.command.executeTableBorderType(payload: TableBorder)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## executeTableTdBorderType
|
||||||
|
|
||||||
|
功能:表格单元格边框类型
|
||||||
|
|
||||||
|
用法:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
instance.command.executeTableTdBorderType(payload: TdBorder)
|
||||||
|
```
|
||||||
|
|
||||||
## executeTableTdBackgroundColor
|
## executeTableTdBackgroundColor
|
||||||
|
|
||||||
功能:表格单元格背景色
|
功能:表格单元格背景色
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ interface ILang {
|
|||||||
borderAll: string
|
borderAll: string
|
||||||
borderEmpty: string
|
borderEmpty: string
|
||||||
borderExternal: string
|
borderExternal: string
|
||||||
|
borderTd: string
|
||||||
|
borderTdBottom: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
datePicker: {
|
datePicker: {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ interface IElement {
|
|||||||
rowspan: number;
|
rowspan: number;
|
||||||
verticalAlign?: VerticalAlign;
|
verticalAlign?: VerticalAlign;
|
||||||
backgroundColor?: string;
|
backgroundColor?: string;
|
||||||
|
borderType?: TdBorder;
|
||||||
value: IElement[];
|
value: IElement[];
|
||||||
}[];
|
}[];
|
||||||
}[];
|
}[];
|
||||||
|
|||||||
@@ -158,3 +158,11 @@
|
|||||||
.ce-contextmenu-border-external {
|
.ce-contextmenu-border-external {
|
||||||
background-image: url(../../../assets/images/table-border-external.svg);
|
background-image: url(../../../assets/images/table-border-external.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ce-contextmenu-border-td {
|
||||||
|
background-image: url(../../../assets/images/table-border-td.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-contextmenu-border-td-bottom {
|
||||||
|
background-image: url(../../../assets/images/table-border-td-bottom.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="#AAACB0"/><path stroke="#3D4757" d="M2.5 8.5 h12"/></svg>
|
||||||
|
After Width: | Height: | Size: 228 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="#AAACB0"/><path stroke="#3D4757" d="M8.5 2.5 v6 h-6"/></svg>
|
||||||
|
After Width: | Height: | Size: 231 B |
@@ -43,6 +43,7 @@ export class Command {
|
|||||||
public executeCancelMergeTableCell: CommandAdapt['cancelMergeTableCell']
|
public executeCancelMergeTableCell: CommandAdapt['cancelMergeTableCell']
|
||||||
public executeTableTdVerticalAlign: CommandAdapt['tableTdVerticalAlign']
|
public executeTableTdVerticalAlign: CommandAdapt['tableTdVerticalAlign']
|
||||||
public executeTableBorderType: CommandAdapt['tableBorderType']
|
public executeTableBorderType: CommandAdapt['tableBorderType']
|
||||||
|
public executeTableTdBorderType: CommandAdapt['tableTdBorderType']
|
||||||
public executeTableTdBackgroundColor: CommandAdapt['tableTdBackgroundColor']
|
public executeTableTdBackgroundColor: CommandAdapt['tableTdBackgroundColor']
|
||||||
public executeTableSelectAll: CommandAdapt['tableSelectAll']
|
public executeTableSelectAll: CommandAdapt['tableSelectAll']
|
||||||
public executeImage: CommandAdapt['image']
|
public executeImage: CommandAdapt['image']
|
||||||
@@ -143,6 +144,7 @@ export class Command {
|
|||||||
this.executeCancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt)
|
this.executeCancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt)
|
||||||
this.executeTableTdVerticalAlign = adapt.tableTdVerticalAlign.bind(adapt)
|
this.executeTableTdVerticalAlign = adapt.tableTdVerticalAlign.bind(adapt)
|
||||||
this.executeTableBorderType = adapt.tableBorderType.bind(adapt)
|
this.executeTableBorderType = adapt.tableBorderType.bind(adapt)
|
||||||
|
this.executeTableTdBorderType = adapt.tableTdBorderType.bind(adapt)
|
||||||
this.executeTableTdBackgroundColor =
|
this.executeTableTdBackgroundColor =
|
||||||
adapt.tableTdBackgroundColor.bind(adapt)
|
adapt.tableTdBackgroundColor.bind(adapt)
|
||||||
this.executeTableSelectAll = adapt.tableSelectAll.bind(adapt)
|
this.executeTableSelectAll = adapt.tableSelectAll.bind(adapt)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { ElementType } from '../../dataset/enum/Element'
|
|||||||
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
|
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
|
||||||
import { ListStyle, ListType } from '../../dataset/enum/List'
|
import { ListStyle, ListType } from '../../dataset/enum/List'
|
||||||
import { RowFlex } from '../../dataset/enum/Row'
|
import { RowFlex } from '../../dataset/enum/Row'
|
||||||
import { TableBorder } from '../../dataset/enum/table/Table'
|
import { TableBorder, TdBorder } from '../../dataset/enum/table/Table'
|
||||||
import { TitleLevel } from '../../dataset/enum/Title'
|
import { TitleLevel } from '../../dataset/enum/Title'
|
||||||
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
||||||
import { ICatalog } from '../../interface/Catalog'
|
import { ICatalog } from '../../interface/Catalog'
|
||||||
@@ -1227,6 +1227,27 @@ export class CommandAdapt {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public tableTdBorderType(payload: TdBorder) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
|
const rowCol = this.draw.getTableParticle().getRangeRowCol()
|
||||||
|
if (!rowCol) return
|
||||||
|
const tdList = rowCol.flat()
|
||||||
|
// 存在则设置边框类型,否则取消设置
|
||||||
|
const isSetBorderType = tdList.some(td => td.borderType !== payload)
|
||||||
|
tdList.forEach(td => {
|
||||||
|
if (isSetBorderType) {
|
||||||
|
td.borderType = payload
|
||||||
|
} else {
|
||||||
|
delete td.borderType
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const { endIndex } = this.range.getRange()
|
||||||
|
this.draw.render({
|
||||||
|
curIndex: endIndex
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public tableTdBackgroundColor(payload: string) {
|
public tableTdBackgroundColor(payload: string) {
|
||||||
const isReadonly = this.draw.isReadonly()
|
const isReadonly = this.draw.isReadonly()
|
||||||
if (isReadonly) return
|
if (isReadonly) return
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
|
import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
|
||||||
import { TableBorder } from '../../../dataset/enum/table/Table'
|
import { TableBorder, TdBorder } 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'
|
||||||
|
|
||||||
@@ -37,6 +37,21 @@ export const tableMenus: IRegisterContextMenu[] = [
|
|||||||
callback: (command: Command) => {
|
callback: (command: Command) => {
|
||||||
command.executeTableBorderType(TableBorder.EXTERNAL)
|
command.executeTableBorderType(TableBorder.EXTERNAL)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.borderTd',
|
||||||
|
icon: 'border-td',
|
||||||
|
when: () => true,
|
||||||
|
childMenus: [
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.borderTdBottom',
|
||||||
|
icon: 'border-td-bottom',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeTableTdBorderType(TdBorder.BOTTOM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ElementType, IElement, TableBorder } from '../../../..'
|
import { ElementType, IElement, TableBorder } from '../../../..'
|
||||||
|
import { TdBorder } from '../../../../dataset/enum/table/Table'
|
||||||
import { IEditorOption } from '../../../../interface/Editor'
|
import { IEditorOption } from '../../../../interface/Editor'
|
||||||
import { ITd } from '../../../../interface/table/Td'
|
import { ITd } from '../../../../interface/table/Td'
|
||||||
import { ITr } from '../../../../interface/table/Tr'
|
import { ITr } from '../../../../interface/table/Tr'
|
||||||
@@ -122,40 +123,55 @@ export class TableParticle {
|
|||||||
startY: number
|
startY: number
|
||||||
) {
|
) {
|
||||||
const { colgroup, trList, borderType } = element
|
const { colgroup, trList, borderType } = element
|
||||||
if (!colgroup || !trList || borderType === TableBorder.EMPTY) return
|
if (!colgroup || !trList) 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 isEmptyBorderType = borderType === TableBorder.EMPTY
|
||||||
|
// 仅外边框
|
||||||
const isExternalBorderType = borderType === TableBorder.EXTERNAL
|
const isExternalBorderType = borderType === TableBorder.EXTERNAL
|
||||||
ctx.save()
|
ctx.save()
|
||||||
// 渲染边框
|
// 渲染边框
|
||||||
this._drawOuterBorder({
|
if (!isEmptyBorderType) {
|
||||||
ctx,
|
this._drawOuterBorder({
|
||||||
startX,
|
ctx,
|
||||||
startY,
|
startX,
|
||||||
width: tableWidth,
|
startY,
|
||||||
height: tableHeight,
|
width: tableWidth,
|
||||||
isDrawFullBorder: isExternalBorderType
|
height: tableHeight,
|
||||||
})
|
isDrawFullBorder: isExternalBorderType
|
||||||
if (!isExternalBorderType) {
|
})
|
||||||
// 渲染表格
|
}
|
||||||
for (let t = 0; t < trList.length; t++) {
|
// 渲染单元格
|
||||||
const tr = trList[t]
|
for (let t = 0; t < trList.length; t++) {
|
||||||
for (let d = 0; d < tr.tdList.length; d++) {
|
const tr = trList[t]
|
||||||
const td = tr.tdList[d]
|
for (let d = 0; d < tr.tdList.length; d++) {
|
||||||
const width = td.width! * scale
|
const td = tr.tdList[d]
|
||||||
const height = td.height! * scale
|
// 没有设置单元格边框 && 没有设置表格边框则忽略
|
||||||
const x = Math.round(td.x! * scale + startX + width)
|
if (!td.borderType && (isEmptyBorderType || isExternalBorderType)) {
|
||||||
const y = Math.round(td.y! * scale + startY)
|
continue
|
||||||
ctx.translate(0.5, 0.5)
|
}
|
||||||
// 绘制线条
|
const width = td.width! * scale
|
||||||
ctx.beginPath()
|
const height = td.height! * scale
|
||||||
|
const x = Math.round(td.x! * scale + startX + width)
|
||||||
|
const y = Math.round(td.y! * scale + startY)
|
||||||
|
ctx.translate(0.5, 0.5)
|
||||||
|
// 绘制线条
|
||||||
|
ctx.beginPath()
|
||||||
|
if (td.borderType === TdBorder.BOTTOM) {
|
||||||
|
ctx.moveTo(x, y + height)
|
||||||
|
ctx.lineTo(x - width, y + height)
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
if (!isEmptyBorderType && !isExternalBorderType) {
|
||||||
|
ctx.moveTo(x, y + height)
|
||||||
ctx.moveTo(x, y)
|
ctx.moveTo(x, y)
|
||||||
ctx.lineTo(x, y + height)
|
ctx.lineTo(x, y + height)
|
||||||
ctx.lineTo(x - width, y + height)
|
ctx.lineTo(x - width, y + height)
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
ctx.translate(-0.5, -0.5)
|
|
||||||
}
|
}
|
||||||
|
ctx.translate(-0.5, -0.5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
|
|||||||
@@ -43,7 +43,9 @@
|
|||||||
"border": "Table border",
|
"border": "Table border",
|
||||||
"borderAll": "All",
|
"borderAll": "All",
|
||||||
"borderEmpty": "Empty",
|
"borderEmpty": "Empty",
|
||||||
"borderExternal": "External"
|
"borderExternal": "External",
|
||||||
|
"borderTd": "Table cell border",
|
||||||
|
"borderTdBottom": "Bottom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"datePicker": {
|
"datePicker": {
|
||||||
|
|||||||
@@ -43,7 +43,9 @@
|
|||||||
"border": "表格边框",
|
"border": "表格边框",
|
||||||
"borderAll": "所有框线",
|
"borderAll": "所有框线",
|
||||||
"borderEmpty": "无框线",
|
"borderEmpty": "无框线",
|
||||||
"borderExternal": "外侧框线"
|
"borderExternal": "外侧框线",
|
||||||
|
"borderTd": "单元格边框",
|
||||||
|
"borderTdBottom": "下边框"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"datePicker": {
|
"datePicker": {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ElementType } from '../enum/Element'
|
import { ElementType } from '../enum/Element'
|
||||||
import { IElement } from '../../interface/Element'
|
import { IElement } from '../../interface/Element'
|
||||||
|
import { ITd } from '../../interface/table/Td'
|
||||||
|
|
||||||
export const EDITOR_ELEMENT_STYLE_ATTR: Array<keyof IElement> = [
|
export const EDITOR_ELEMENT_STYLE_ATTR: Array<keyof IElement> = [
|
||||||
'bold',
|
'bold',
|
||||||
@@ -61,6 +62,12 @@ export const EDITOR_ELEMENT_ZIP_ATTR: Array<keyof IElement> = [
|
|||||||
'groupIds'
|
'groupIds'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export const TABLE_TD_ZIP_ATTR: Array<keyof ITd> = [
|
||||||
|
'verticalAlign',
|
||||||
|
'backgroundColor',
|
||||||
|
'borderType'
|
||||||
|
]
|
||||||
|
|
||||||
export const TABLE_CONTEXT_ATTR: Array<keyof IElement> = [
|
export const TABLE_CONTEXT_ATTR: Array<keyof IElement> = [
|
||||||
'tdId',
|
'tdId',
|
||||||
'trId',
|
'trId',
|
||||||
|
|||||||
@@ -3,3 +3,7 @@ export enum TableBorder {
|
|||||||
EMPTY = 'empty',
|
EMPTY = 'empty',
|
||||||
EXTERNAL = 'external'
|
EXTERNAL = 'external'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum TdBorder {
|
||||||
|
BOTTOM = 'bottom'
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -44,7 +44,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'
|
import { TableBorder, TdBorder } from './dataset/enum/table/Table'
|
||||||
import { IFooter } from './interface/Footer'
|
import { IFooter } from './interface/Footer'
|
||||||
import { defaultFooterOption } from './dataset/constant/Footer'
|
import { defaultFooterOption } from './dataset/constant/Footer'
|
||||||
import { MaxHeightRatio, NumberType } from './dataset/enum/Common'
|
import { MaxHeightRatio, NumberType } from './dataset/enum/Common'
|
||||||
@@ -259,6 +259,7 @@ export {
|
|||||||
BlockType,
|
BlockType,
|
||||||
PaperDirection,
|
PaperDirection,
|
||||||
TableBorder,
|
TableBorder,
|
||||||
|
TdBorder,
|
||||||
MaxHeightRatio,
|
MaxHeightRatio,
|
||||||
NumberType,
|
NumberType,
|
||||||
TitleLevel,
|
TitleLevel,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
||||||
|
import { TdBorder } from '../../dataset/enum/table/Table'
|
||||||
import { IElement, IElementPosition } from '../Element'
|
import { IElement, IElementPosition } from '../Element'
|
||||||
import { IRow } from '../Row'
|
import { IRow } from '../Row'
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ export interface ITd {
|
|||||||
positionList?: IElementPosition[]
|
positionList?: IElementPosition[]
|
||||||
verticalAlign?: VerticalAlign
|
verticalAlign?: VerticalAlign
|
||||||
backgroundColor?: string
|
backgroundColor?: string
|
||||||
|
borderType?: TdBorder
|
||||||
mainHeight?: number // 内容 + 内边距高度
|
mainHeight?: number // 内容 + 内边距高度
|
||||||
realHeight?: number // 真实高度(包含跨列)
|
realHeight?: number // 真实高度(包含跨列)
|
||||||
realMinHeight?: number // 真实最小高度(包含跨列)
|
realMinHeight?: number // 真实最小高度(包含跨列)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
EDITOR_ELEMENT_ZIP_ATTR,
|
EDITOR_ELEMENT_ZIP_ATTR,
|
||||||
INLINE_NODE_NAME,
|
INLINE_NODE_NAME,
|
||||||
TABLE_CONTEXT_ATTR,
|
TABLE_CONTEXT_ATTR,
|
||||||
|
TABLE_TD_ZIP_ATTR,
|
||||||
TEXTLIKE_ELEMENT_TYPE
|
TEXTLIKE_ELEMENT_TYPE
|
||||||
} from '../dataset/constant/Element'
|
} from '../dataset/constant/Element'
|
||||||
import {
|
import {
|
||||||
@@ -483,12 +484,13 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
|||||||
rowspan: td.rowspan,
|
rowspan: td.rowspan,
|
||||||
value: zipElementList(td.value)
|
value: zipElementList(td.value)
|
||||||
}
|
}
|
||||||
if (td.verticalAlign) {
|
// 压缩单元格属性
|
||||||
zipTd.verticalAlign = td.verticalAlign
|
TABLE_TD_ZIP_ATTR.forEach(attr => {
|
||||||
}
|
const value = td[attr] as never
|
||||||
if (td.backgroundColor) {
|
if (value !== undefined) {
|
||||||
zipTd.backgroundColor = td.backgroundColor
|
zipTd[attr] = value
|
||||||
}
|
}
|
||||||
|
})
|
||||||
tr.tdList[d] = zipTd
|
tr.tdList[d] = zipTd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user