import removeClass from 'tui-code-snippet/domUtil/removeClass'; import addClass from 'tui-code-snippet/domUtil/addClass'; import { HookCallback } from '@t/editor'; import { Emitter } from '@t/event'; import { ExecCommand, HidePopup, TabInfo } from '@t/ui'; import i18n from '@/i18n/i18n'; import { cls } from '@/utils/dom'; import { Component } from '@/ui/vdom/component'; import html from '@/ui/vdom/template'; import { Tabs } from '../tabs'; const TYPE_UI = 'ui'; type TabType = 'url' | 'file'; interface Props { show: boolean; eventEmitter: Emitter; execCommand: ExecCommand; hidePopup: HidePopup; } interface State { activeTab: TabType; file: File | null; fileNameElClassName: string; } export class ImagePopupBody extends Component { private tabs: TabInfo[]; constructor(props: Props) { super(props); this.state = { activeTab: 'file', file: null, fileNameElClassName: '' }; this.tabs = [ { name: 'file', text: 'File' }, { name: 'url', text: 'URL' }, ]; } private initialize = (activeTab: TabType = 'file') => { const urlEl = this.refs.url as HTMLInputElement; urlEl.value = ''; (this.refs.altText as HTMLInputElement).value = ''; (this.refs.file as HTMLInputElement).value = ''; removeClass(urlEl, 'wrong'); this.setState({ activeTab, file: null, fileNameElClassName: '' }); }; private emitAddImageBlob() { const { files } = this.refs.file as HTMLInputElement; const altTextEl = this.refs.altText as HTMLInputElement; let fileNameElClassName = ' wrong'; if (files?.length) { fileNameElClassName = ''; const imageFile = files.item(0)!; const hookCallback: HookCallback = (url, text) => this.props.execCommand('addImage', { imageUrl: url, altText: text || altTextEl.value }); this.props.eventEmitter.emit('addImageBlobHook', imageFile, hookCallback, TYPE_UI); } this.setState({ fileNameElClassName }); } private emitAddImage() { const imageUrlEl = this.refs.url as HTMLInputElement; const altTextEl = this.refs.altText as HTMLInputElement; const imageUrl = imageUrlEl.value; const altText = altTextEl.value || 'image'; removeClass(imageUrlEl, 'wrong'); if (!imageUrl.length) { addClass(imageUrlEl, 'wrong'); return; } if (imageUrl) { this.props.execCommand('addImage', { imageUrl, altText }); } } private execCommand = () => { if (this.state.activeTab === 'file') { this.emitAddImageBlob(); } else { this.emitAddImage(); } }; private toggleTab = (_: MouseEvent, activeTab: TabType) => { if (activeTab !== this.state.activeTab) { this.initialize(activeTab); } }; private showFileSelectBox = () => { this.refs.file.click(); }; private changeFile = (ev: Event) => { const { files } = ev.target as HTMLInputElement; if (files?.length) { this.setState({ file: files[0] }); } }; private preventSelectStart(ev: Event) { ev.preventDefault(); } updated() { if (!this.props.show) { this.initialize(); } } render() { const { activeTab, file, fileNameElClassName } = this.state; return html`
<${Tabs} tabs=${this.tabs} activeTab=${activeTab} onClick=${this.toggleTab} />
(this.refs.url = el)} />
${file ? file.name : i18n.get('No file')} (this.refs.file = el)} />
(this.refs.altText = el)} />
`; } }