commit
4dff6ab039
@ -0,0 +1,54 @@
|
|||||||
|
import Editor, { ControlType, ElementType } from '../../../src/editor'
|
||||||
|
|
||||||
|
describe('控件-列举型', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('http://localhost:3000/canvas-editor/')
|
||||||
|
|
||||||
|
cy.get('canvas').first().as('canvas').should('have.length', 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
const text = `有`
|
||||||
|
const elementType: ElementType = <ElementType>'control'
|
||||||
|
const controlType: ControlType = <ControlType>'select'
|
||||||
|
|
||||||
|
it('列举型', () => {
|
||||||
|
cy.getEditor().then((editor: Editor) => {
|
||||||
|
editor.listener.saved = function (payload) {
|
||||||
|
const data = payload.data[0]
|
||||||
|
|
||||||
|
expect(data.control!.value![0].value).to.be.eq(text)
|
||||||
|
|
||||||
|
expect(data.control!.code).to.be.eq('98175')
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.command.executeSelectAll()
|
||||||
|
|
||||||
|
editor.command.executeBackspace()
|
||||||
|
|
||||||
|
editor.command.executeInsertElementList([{
|
||||||
|
type: elementType,
|
||||||
|
value: '',
|
||||||
|
control: {
|
||||||
|
type: controlType,
|
||||||
|
value: null,
|
||||||
|
placeholder: '列举型',
|
||||||
|
valueSets: [{
|
||||||
|
value: '有',
|
||||||
|
code: '98175'
|
||||||
|
}, {
|
||||||
|
value: '无',
|
||||||
|
code: '98176'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
|
||||||
|
cy.get('@canvas').type(`{leftArrow}`)
|
||||||
|
|
||||||
|
cy.get('.select-control-popup li').eq(0).click()
|
||||||
|
|
||||||
|
cy.get('@canvas').type('{ctrl}s')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
import Editor, { ControlType, ElementType } from '../../../src/editor'
|
||||||
|
|
||||||
|
describe('控件-文本型', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('http://localhost:3000/canvas-editor/')
|
||||||
|
|
||||||
|
cy.get('canvas').first().as('canvas').should('have.length', 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
const text = `canvas-editor`
|
||||||
|
const elementType: ElementType = <ElementType>'control'
|
||||||
|
const controlType: ControlType = <ControlType>'text'
|
||||||
|
|
||||||
|
it('文本型', () => {
|
||||||
|
cy.getEditor().then((editor: Editor) => {
|
||||||
|
editor.listener.saved = function (payload) {
|
||||||
|
const data = payload.data[0]
|
||||||
|
|
||||||
|
expect(data.control!.value![0].value).to.be.eq(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.command.executeSelectAll()
|
||||||
|
|
||||||
|
editor.command.executeBackspace()
|
||||||
|
|
||||||
|
editor.command.executeInsertElementList([{
|
||||||
|
type: elementType,
|
||||||
|
value: '',
|
||||||
|
control: {
|
||||||
|
type: controlType,
|
||||||
|
value: null,
|
||||||
|
placeholder: '文本型'
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
|
||||||
|
cy.get('@canvas').type(`{leftArrow}`)
|
||||||
|
|
||||||
|
cy.get('.inputarea').type(text)
|
||||||
|
|
||||||
|
cy.get('@canvas').type('{ctrl}s')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
.select-control-popup {
|
||||||
|
max-width: 160px;
|
||||||
|
min-width: 69px;
|
||||||
|
max-height: 225px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 5px 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-control-popup ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 3px 0;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-control-popup ul li {
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 0 20px;
|
||||||
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: #666;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-control-popup ul li:hover {
|
||||||
|
background-color: #EEF2FD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-control-popup ul li.active {
|
||||||
|
color: var(--COLOR-HOVER, #5175f4);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
@ -0,0 +1,278 @@
|
|||||||
|
import { ControlComponent, ControlType } from '../../../dataset/enum/Control'
|
||||||
|
import { ElementType } from '../../../dataset/enum/Element'
|
||||||
|
import { IControlInitOption, IControlInstance, IControlOption } from '../../../interface/Control'
|
||||||
|
import { IElement, IElementPosition } from '../../../interface/Element'
|
||||||
|
import { RangeManager } from '../../range/RangeManager'
|
||||||
|
import { Draw } from '../Draw'
|
||||||
|
import { SelectControl } from './select/SelectControl'
|
||||||
|
import { TextControl } from './text/TextControl'
|
||||||
|
|
||||||
|
interface IMoveCursorResult {
|
||||||
|
newIndex: number;
|
||||||
|
newElement: IElement;
|
||||||
|
}
|
||||||
|
export class Control {
|
||||||
|
|
||||||
|
private draw: Draw
|
||||||
|
private range: RangeManager
|
||||||
|
private options: IControlOption
|
||||||
|
private activeControl: IControlInstance | null
|
||||||
|
|
||||||
|
constructor(draw: Draw) {
|
||||||
|
this.draw = draw
|
||||||
|
this.range = draw.getRange()
|
||||||
|
this.options = draw.getOptions().control
|
||||||
|
this.activeControl = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断选区部分在控件边界外
|
||||||
|
public isPartRangeInControlOutside(): boolean {
|
||||||
|
const { startIndex, endIndex } = this.getRange()
|
||||||
|
if (!~startIndex && !~endIndex) return false
|
||||||
|
const elementList = this.getElementList()
|
||||||
|
const startElement = elementList[startIndex]
|
||||||
|
const endElement = elementList[endIndex]
|
||||||
|
if (
|
||||||
|
(startElement.type === ElementType.CONTROL || endElement.type === ElementType.CONTROL)
|
||||||
|
&& startElement.controlId !== endElement.controlId
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
public getContainer(): HTMLDivElement {
|
||||||
|
return this.draw.getContainer()
|
||||||
|
}
|
||||||
|
|
||||||
|
public getElementList(): IElement[] {
|
||||||
|
return this.draw.getElementList()
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPosition(): IElementPosition | null {
|
||||||
|
const positionList = this.draw.getPosition().getPositionList()
|
||||||
|
const { endIndex } = this.range.getRange()
|
||||||
|
return positionList[endIndex] || null
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPreY(): number {
|
||||||
|
const height = this.draw.getHeight()
|
||||||
|
const pageGap = this.draw.getPageGap()
|
||||||
|
return this.draw.getPageNo() * (height + pageGap)
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRange() {
|
||||||
|
return this.range.getRange()
|
||||||
|
}
|
||||||
|
|
||||||
|
public shrinkBoundary() {
|
||||||
|
this.range.shrinkBoundary()
|
||||||
|
}
|
||||||
|
|
||||||
|
public getActiveControl(): IControlInstance | null {
|
||||||
|
return this.activeControl
|
||||||
|
}
|
||||||
|
|
||||||
|
public initControl() {
|
||||||
|
const elementList = this.getElementList()
|
||||||
|
const range = this.getRange()
|
||||||
|
const element = elementList[range.startIndex]
|
||||||
|
// 判断控件是否已经激活
|
||||||
|
if (this.activeControl) {
|
||||||
|
// 列举控件唤醒下拉弹窗
|
||||||
|
if (this.activeControl instanceof SelectControl) {
|
||||||
|
this.activeControl.awake()
|
||||||
|
}
|
||||||
|
const controlElement = this.activeControl.getElement()
|
||||||
|
if (element.controlId === controlElement.controlId) return
|
||||||
|
}
|
||||||
|
// 销毁旧激活控件
|
||||||
|
this.destroyControl()
|
||||||
|
// 激活控件
|
||||||
|
const control = element.control!
|
||||||
|
if (control.type === ControlType.TEXT) {
|
||||||
|
this.activeControl = new TextControl(element, this)
|
||||||
|
} else if (control.type === ControlType.SELECT) {
|
||||||
|
const selectControl = new SelectControl(element, this)
|
||||||
|
this.activeControl = selectControl
|
||||||
|
selectControl.awake()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public destroyControl() {
|
||||||
|
if (this.activeControl) {
|
||||||
|
if (this.activeControl instanceof SelectControl) {
|
||||||
|
this.activeControl.destroy()
|
||||||
|
}
|
||||||
|
this.activeControl = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public repaintControl(curIndex: number) {
|
||||||
|
this.range.setRange(curIndex, curIndex)
|
||||||
|
this.draw.render({
|
||||||
|
curIndex
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public moveCursor(position: IControlInitOption): IMoveCursorResult {
|
||||||
|
const { index, trIndex, tdIndex, tdValueIndex } = position
|
||||||
|
let elementList = this.draw.getOriginalElementList()
|
||||||
|
let element: IElement
|
||||||
|
const newIndex = position.isTable ? tdValueIndex! : index
|
||||||
|
if (position.isTable) {
|
||||||
|
elementList = elementList[index!].trList![trIndex!].tdList[tdIndex!].value
|
||||||
|
element = elementList[tdValueIndex!]
|
||||||
|
} else {
|
||||||
|
element = elementList[index]
|
||||||
|
}
|
||||||
|
if (element.controlComponent === ControlComponent.VALUE) {
|
||||||
|
// VALUE-无需移动
|
||||||
|
return {
|
||||||
|
newIndex,
|
||||||
|
newElement: element
|
||||||
|
}
|
||||||
|
} else if (element.controlComponent === ControlComponent.POSTFIX) {
|
||||||
|
// POSTFIX-移动到最后一个后缀字符后
|
||||||
|
let startIndex = index + 1
|
||||||
|
while (startIndex < elementList.length) {
|
||||||
|
const nextElement = elementList[startIndex]
|
||||||
|
if (nextElement.controlId !== element.controlId) {
|
||||||
|
return {
|
||||||
|
newIndex: startIndex - 1,
|
||||||
|
newElement: elementList[startIndex - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startIndex++
|
||||||
|
}
|
||||||
|
} else if (element.controlComponent === ControlComponent.PREFIX) {
|
||||||
|
// PREFIX-移动到最后一个前缀字符后
|
||||||
|
let startIndex = index + 1
|
||||||
|
while (startIndex < elementList.length) {
|
||||||
|
const nextElement = elementList[startIndex]
|
||||||
|
if (
|
||||||
|
nextElement.controlId !== element.controlId
|
||||||
|
|| nextElement.controlComponent !== ControlComponent.PREFIX
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
newIndex: startIndex - 1,
|
||||||
|
newElement: elementList[startIndex - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startIndex++
|
||||||
|
}
|
||||||
|
} else if (element.controlComponent === ControlComponent.PLACEHOLDER) {
|
||||||
|
// PLACEHOLDER-移动到第一个前缀后
|
||||||
|
let startIndex = index - 1
|
||||||
|
while (startIndex > 0) {
|
||||||
|
const preElement = elementList[startIndex]
|
||||||
|
if (
|
||||||
|
preElement.controlId !== element.controlId
|
||||||
|
|| preElement.controlComponent === ControlComponent.PREFIX
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
newIndex: startIndex,
|
||||||
|
newElement: elementList[startIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startIndex--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
newIndex,
|
||||||
|
newElement: element
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeControl(startIndex: number): number {
|
||||||
|
const elementList = this.getElementList()
|
||||||
|
const startElement = elementList[startIndex]
|
||||||
|
let leftIndex = -1
|
||||||
|
let rightIndex = -1
|
||||||
|
// 向左查找
|
||||||
|
let preIndex = startIndex
|
||||||
|
while (preIndex > 0) {
|
||||||
|
const preElement = elementList[preIndex]
|
||||||
|
if (preElement.controlId !== startElement.controlId) {
|
||||||
|
leftIndex = preIndex
|
||||||
|
break
|
||||||
|
}
|
||||||
|
preIndex--
|
||||||
|
}
|
||||||
|
// 向右查找
|
||||||
|
let nextIndex = startIndex + 1
|
||||||
|
while (nextIndex < elementList.length) {
|
||||||
|
const nextElement = elementList[nextIndex]
|
||||||
|
if (nextElement.controlId !== startElement.controlId) {
|
||||||
|
rightIndex = nextIndex - 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
nextIndex++
|
||||||
|
}
|
||||||
|
if (!~leftIndex || !~rightIndex) return startIndex
|
||||||
|
// 删除元素
|
||||||
|
elementList.splice(leftIndex + 1, rightIndex - leftIndex)
|
||||||
|
return leftIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
public removePlaceholder(startIndex: number) {
|
||||||
|
const elementList = this.getElementList()
|
||||||
|
const startElement = elementList[startIndex]
|
||||||
|
const nextElement = elementList[startIndex + 1]
|
||||||
|
if (
|
||||||
|
startElement.controlComponent === ControlComponent.PLACEHOLDER ||
|
||||||
|
nextElement.controlComponent === ControlComponent.PLACEHOLDER
|
||||||
|
) {
|
||||||
|
let index = startIndex
|
||||||
|
while (index < elementList.length) {
|
||||||
|
const curElement = elementList[index]
|
||||||
|
if (curElement.controlId !== startElement.controlId) break
|
||||||
|
if (curElement.controlComponent === ControlComponent.PLACEHOLDER) {
|
||||||
|
elementList.splice(index, 1)
|
||||||
|
} else {
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public addPlaceholder(startIndex: number) {
|
||||||
|
const elementList = this.getElementList()
|
||||||
|
const startElement = elementList[startIndex]
|
||||||
|
const control = startElement.control!
|
||||||
|
const placeholderStrList = control.placeholder.split('')
|
||||||
|
for (let p = 0; p < placeholderStrList.length; p++) {
|
||||||
|
const value = placeholderStrList[p]
|
||||||
|
elementList.splice(startIndex + p + 1, 0, {
|
||||||
|
value,
|
||||||
|
controlId: startElement.controlId,
|
||||||
|
type: ElementType.CONTROL,
|
||||||
|
control: startElement.control,
|
||||||
|
controlComponent: ControlComponent.PLACEHOLDER,
|
||||||
|
color: this.options.placeholderColor
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public setValue(data: IElement[]): number {
|
||||||
|
if (!this.activeControl) {
|
||||||
|
throw new Error('active control is null')
|
||||||
|
}
|
||||||
|
return this.activeControl.setValue(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
public keydown(evt: KeyboardEvent): number {
|
||||||
|
if (!this.activeControl) {
|
||||||
|
throw new Error('active control is null')
|
||||||
|
}
|
||||||
|
return this.activeControl.keydown(evt)
|
||||||
|
}
|
||||||
|
|
||||||
|
public cut(): number {
|
||||||
|
if (!this.activeControl) {
|
||||||
|
throw new Error('active control is null')
|
||||||
|
}
|
||||||
|
return this.activeControl.cut()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,167 @@
|
|||||||
|
import { ControlComponent } from '../../../../dataset/enum/Control'
|
||||||
|
import { KeyMap } from '../../../../dataset/enum/Keymap'
|
||||||
|
import { IControlInstance } from '../../../../interface/Control'
|
||||||
|
import { IElement } from '../../../../interface/Element'
|
||||||
|
import { Control } from '../Control'
|
||||||
|
|
||||||
|
export class TextControl implements IControlInstance {
|
||||||
|
|
||||||
|
private element: IElement
|
||||||
|
private control: Control
|
||||||
|
|
||||||
|
constructor(element: IElement, control: Control) {
|
||||||
|
this.element = element
|
||||||
|
this.control = control
|
||||||
|
}
|
||||||
|
|
||||||
|
public getElement(): IElement {
|
||||||
|
return this.element
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValue(): IElement[] {
|
||||||
|
const elementList = this.control.getElementList()
|
||||||
|
const { startIndex } = this.control.getRange()
|
||||||
|
const startElement = elementList[startIndex]
|
||||||
|
const data: IElement[] = []
|
||||||
|
// 向左查找
|
||||||
|
let preIndex = startIndex
|
||||||
|
while (preIndex > 0) {
|
||||||
|
const preElement = elementList[preIndex]
|
||||||
|
if (
|
||||||
|
preElement.controlId !== startElement.controlId ||
|
||||||
|
preElement.controlComponent === ControlComponent.PREFIX
|
||||||
|
) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (preElement.controlComponent === ControlComponent.VALUE) {
|
||||||
|
data.unshift(preElement)
|
||||||
|
}
|
||||||
|
preIndex--
|
||||||
|
}
|
||||||
|
// 向右查找
|
||||||
|
let nextIndex = startIndex + 1
|
||||||
|
while (nextIndex < elementList.length) {
|
||||||
|
const nextElement = elementList[nextIndex]
|
||||||
|
if (
|
||||||
|
nextElement.controlId !== startElement.controlId ||
|
||||||
|
nextElement.controlComponent === ControlComponent.POSTFIX
|
||||||
|
) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (nextElement.controlComponent === ControlComponent.VALUE) {
|
||||||
|
data.push(nextElement)
|
||||||
|
}
|
||||||
|
nextIndex++
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
public setValue(data: IElement[]): number {
|
||||||
|
const elementList = this.control.getElementList()
|
||||||
|
const range = this.control.getRange()
|
||||||
|
// 收缩边界到Value内
|
||||||
|
this.control.shrinkBoundary()
|
||||||
|
const { startIndex, endIndex } = range
|
||||||
|
// 移除选区元素
|
||||||
|
if (startIndex !== endIndex) {
|
||||||
|
elementList.splice(startIndex + 1, endIndex - startIndex)
|
||||||
|
} else {
|
||||||
|
// 移除空白占位符
|
||||||
|
this.control.removePlaceholder(startIndex)
|
||||||
|
}
|
||||||
|
// 插入
|
||||||
|
const startElement = elementList[startIndex]
|
||||||
|
const start = range.startIndex + 1
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
elementList.splice(start + i, 0, {
|
||||||
|
...startElement,
|
||||||
|
...data[i],
|
||||||
|
controlComponent: ControlComponent.VALUE
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return start + data.length - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
public keydown(evt: KeyboardEvent): number {
|
||||||
|
const elementList = this.control.getElementList()
|
||||||
|
const range = this.control.getRange()
|
||||||
|
// 收缩边界到Value内
|
||||||
|
this.control.shrinkBoundary()
|
||||||
|
const { startIndex, endIndex } = range
|
||||||
|
const startElement = elementList[startIndex]
|
||||||
|
const endElement = elementList[endIndex]
|
||||||
|
// backspace
|
||||||
|
if (evt.key === KeyMap.Backspace) {
|
||||||
|
// 移除选区元素
|
||||||
|
if (startIndex !== endIndex) {
|
||||||
|
elementList.splice(startIndex + 1, endIndex - startIndex)
|
||||||
|
const value = this.getValue()
|
||||||
|
if (!value.length) {
|
||||||
|
this.control.addPlaceholder(startIndex)
|
||||||
|
}
|
||||||
|
return startIndex
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
startElement.controlComponent === ControlComponent.PREFIX ||
|
||||||
|
endElement.controlComponent === ControlComponent.POSTFIX ||
|
||||||
|
startElement.controlComponent === ControlComponent.PLACEHOLDER
|
||||||
|
) {
|
||||||
|
// 前缀、后缀、占位符
|
||||||
|
return this.control.removeControl(startIndex)
|
||||||
|
} else {
|
||||||
|
// 文本
|
||||||
|
elementList.splice(startIndex, 1)
|
||||||
|
const value = this.getValue()
|
||||||
|
if (!value.length) {
|
||||||
|
this.control.addPlaceholder(startIndex - 1)
|
||||||
|
}
|
||||||
|
return startIndex - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (evt.key === KeyMap.Delete) {
|
||||||
|
// 移除选区元素
|
||||||
|
if (startIndex !== endIndex) {
|
||||||
|
elementList.splice(startIndex + 1, endIndex - startIndex)
|
||||||
|
const value = this.getValue()
|
||||||
|
if (!value.length) {
|
||||||
|
this.control.addPlaceholder(startIndex)
|
||||||
|
}
|
||||||
|
return startIndex
|
||||||
|
} else {
|
||||||
|
const endNextElement = elementList[endIndex + 1]
|
||||||
|
if (startElement.controlComponent === ControlComponent.PREFIX ||
|
||||||
|
endNextElement.controlComponent === ControlComponent.POSTFIX ||
|
||||||
|
startElement.controlComponent === ControlComponent.PLACEHOLDER
|
||||||
|
) {
|
||||||
|
// 前缀、后缀、占位符
|
||||||
|
return this.control.removeControl(startIndex)
|
||||||
|
} else {
|
||||||
|
// 文本
|
||||||
|
elementList.splice(startIndex + 1, 1)
|
||||||
|
const value = this.getValue()
|
||||||
|
if (!value.length) {
|
||||||
|
this.control.addPlaceholder(startIndex)
|
||||||
|
}
|
||||||
|
return startIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return endIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
public cut(): number {
|
||||||
|
this.control.shrinkBoundary()
|
||||||
|
const { startIndex, endIndex } = this.control.getRange()
|
||||||
|
if (startIndex === endIndex) {
|
||||||
|
return startIndex
|
||||||
|
}
|
||||||
|
const elementList = this.control.getElementList()
|
||||||
|
elementList.splice(startIndex + 1, endIndex - startIndex)
|
||||||
|
const value = this.getValue()
|
||||||
|
if (!value.length) {
|
||||||
|
this.control.addPlaceholder(startIndex)
|
||||||
|
}
|
||||||
|
return startIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { IControlOption } from '../../interface/Control'
|
||||||
|
|
||||||
|
export const defaultControlOption: Readonly<Required<IControlOption>> = {
|
||||||
|
placeholderColor: '#9c9b9b',
|
||||||
|
bracketColor: '#000000',
|
||||||
|
prefix: '{',
|
||||||
|
postfix: '}'
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
export enum ControlType {
|
||||||
|
TEXT = 'text',
|
||||||
|
SELECT = 'select'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ControlComponent {
|
||||||
|
PREFIX = 'prefix',
|
||||||
|
POSTFIX = 'postfix',
|
||||||
|
PLACEHOLDER = 'placeholder',
|
||||||
|
VALUE = 'value'
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
import { ControlType } from '../dataset/enum/Control'
|
||||||
|
import { IElement } from './Element'
|
||||||
|
|
||||||
|
export interface IValueSet {
|
||||||
|
value: string;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IControlSelect {
|
||||||
|
code: string | null;
|
||||||
|
valueSets: IValueSet[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IControlBasic {
|
||||||
|
type: ControlType;
|
||||||
|
value: IElement[] | null;
|
||||||
|
placeholder: string;
|
||||||
|
conceptId?: string;
|
||||||
|
prefix?: string;
|
||||||
|
postfix?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IControl = IControlBasic & Partial<IControlSelect>
|
||||||
|
|
||||||
|
export interface IControlOption {
|
||||||
|
placeholderColor?: string;
|
||||||
|
bracketColor?: string;
|
||||||
|
prefix?: string;
|
||||||
|
postfix?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IControlInitOption {
|
||||||
|
index: number;
|
||||||
|
isTable?: boolean;
|
||||||
|
trIndex?: number;
|
||||||
|
tdIndex?: number;
|
||||||
|
tdValueIndex?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IControlInitResult {
|
||||||
|
newIndex: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IControlInstance {
|
||||||
|
getElement(): IElement;
|
||||||
|
|
||||||
|
getValue(): IElement[];
|
||||||
|
|
||||||
|
setValue(data: IElement[]): number;
|
||||||
|
|
||||||
|
keydown(evt: KeyboardEvent): number;
|
||||||
|
|
||||||
|
cut(): number;
|
||||||
|
}
|
||||||
Loading…
Reference in new issue