@qxs-bns/components-wc 0.0.16 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/editor/blocksuite-editor.mjs +14 -68
- package/es/editor/blocksuite-editor.mjs.map +1 -1
- package/es/subject/list.mjs.map +1 -1
- package/es/subject/single.mjs.map +1 -1
- package/lib/editor/blocksuite-editor.cjs +3 -57
- package/lib/editor/blocksuite-editor.cjs.map +1 -1
- package/lib/subject/list.cjs.map +1 -1
- package/lib/subject/single.cjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"single.mjs","sources":["../../../../packages/components-wc/src/subject/single.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { safeCustomElement } from '../base/define'\nimport { uid } from '../base/uid'\nimport { SubjectType } from './types'\nimport type { AnswerType } from './types'\n\nexport interface SubjectErrorOptions {\n message: string\n code?: string\n field?: string\n row?: any\n}\n\nexport class SubjectError extends Error {\n constructor(\n message: string,\n public code: string = 'VALIDATION_ERROR',\n public field?: string,\n public row?: any,\n ) {\n super(message)\n this.name = 'SubjectError'\n }\n\n static from(options: SubjectErrorOptions): SubjectError {\n return new SubjectError(options.message, options.code, options.field, options.row)\n }\n}\n\ninterface Answer {\n title: string\n isCorrect: boolean\n customAnswerId?: string\n answerId?: string\n resultItem?: string\n orderIndex?: number\n answerRelations?: any[]\n relationType?: number | null\n}\n\nconst iconPlus = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`\nconst iconRemove = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`\nconst iconClose = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`\nconst iconArrow = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"/></svg>`\n\nfunction showToast(msg: string) {\n const el = document.createElement('div')\n el.textContent = msg\n Object.assign(el.style, {\n position: 'fixed', top: '20px', left: '50%', transform: 'translateX(-50%)',\n padding: '10px 20px', borderRadius: '4px', fontSize: '13px', color: '#fff',\n background: '#f56c6c', zIndex: '99999', boxShadow: '0 4px 12px rgba(0,0,0,.15)',\n transition: 'opacity .3s', opacity: '1',\n })\n document.body.appendChild(el)\n setTimeout(() => { el.style.opacity = '0'; setTimeout(() => el.remove(), 300) }, 2500)\n}\n\n@safeCustomElement('qxs-subject-single')\nexport class QxsSubjectSingle extends LitElement {\n static styles = css`\n :host { display: block; font-family: system-ui, -apple-system, \"PingFang SC\", \"Microsoft YaHei\", sans-serif; font-size: 12px; color: #5a5a5a; }\n *, ::before, ::after { box-sizing: border-box; }\n\n .preview { padding: 12px 0; }\n .preview .title { font-size: 14px; color: #303133; }\n .preview .title .key-badge {\n display: inline-block;\n margin-left: 8px;\n padding: 1px 6px;\n font-size: 11px;\n color: #fff;\n background: #f56c6c;\n border-radius: 3px;\n vertical-align: middle;\n }\n .preview .rich-text { margin-top: 8px; }\n .preview .rich-text img { max-width: 100%; }\n .preview-answer { display: flex; flex-direction: column; margin-top: 12px; }\n .preview-answer .radio { margin-top: 8px; padding-left: 8px; display: flex; align-items: center; gap: 6px; }\n .preview-answer .order { color: #909399; }\n .preview-answer .correct { color: #67c23a; }\n .preview-answer .result-info { color: #909399; }\n\n .flex { display: flex; }\n .flex-items-center { display: flex; align-items: center; }\n .flex-items-start { display: flex; align-items: flex-start; }\n .flex-justify-end { display: flex; justify-content: flex-end; }\n .label { min-width: 60px; font-size: 13px; color: #606266; }\n\n textarea {\n border: 1px solid #dcdfe6; border-radius: 3px; padding: 5px 11px;\n font-size: 13px; font-family: inherit; width: 100%; resize: none; transition: border-color .2s;\n line-height: 1.5; display: block; box-sizing: border-box;\n }\n textarea:focus { border-color: #3D61E3; outline: none; }\n textarea:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .el-input { position: relative; display: block; }\n .el-input textarea { padding-bottom: 24px; }\n .el-input .char-counter {\n position: absolute; right: 12px; bottom: 8px;\n font-size: 12px; color: #909399; line-height: 1; pointer-events: none;\n }\n\n .answer-list { margin-top: 12px; }\n .answer-item { display: flex; align-items: center; margin-top: 6px; border-radius: 4px; }\n .answer-item .label { min-width: 60px; font-size: 13px; color: #909399; }\n .answer-item .input { flex: 1; max-width: 360px; position: relative; display: block; }\n .answer-item .input input {\n height: 32px; padding: 0 50px 0 8px;\n font-size: 13px; line-height: 32px;\n border: 1px solid #dcdfe6; border-radius: 3px; width: 100%;\n transition: border-color .2s; box-sizing: border-box;\n }\n .answer-item .input input:focus { border-color: #3D61E3; outline: none; }\n .answer-item .input input:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .answer-item .input .char-counter {\n position: absolute; right: 8px; top: 50%; transform: translateY(-50%);\n font-size: 12px; color: #909399; line-height: 1; pointer-events: none;\n }\n\n .answer-item .correct { margin: 0 10px; color: #909399; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }\n .answer-item .correct:hover { color: #3D61E3; }\n .answer-item .correct.is-correct { color: #67c23a; }\n .answer-item .correct input { width: 14px; height: 14px; cursor: pointer; accent-color: #3D61E3; }\n\n .answer-item .icon {\n margin-left: 6px; cursor: pointer; display: inline-flex;\n align-items: center; justify-content: center;\n width: 24px; height: 24px; border-radius: 4px;\n border: 1px solid #dcdfe6; background: #fff; color: #909399;\n transition: all 0.2s;\n }\n .answer-item .icon:hover { color: #3D61E3; border-color: #3D61E3; background: #ecf5ff; }\n .answer-item .icon.disabled { color: #e4e7ed; border-color: #e4e7ed; cursor: not-allowed; }\n\n .answer-item .link { margin-left: 8px; color: #3D61E3; cursor: pointer; font-size: 12px; white-space: nowrap; }\n .answer-item .link:hover { color: #2D4CB8; }\n\n .el-select {\n width: 150px; height: 32px; border: 1px solid #dcdfe6; border-radius: 3px;\n padding: 0 8px; font-size: 13px; background: #fff; appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23c0c4cc' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");\n background-repeat: no-repeat; background-position: right 8px center;\n }\n .el-select:focus { border-color: #3D61E3; outline: none; }\n .el-select:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .el-select.sort-select {\n width: 360px; height: auto; min-height: 32px; appearance: auto;\n }\n\n .sort-badge { font-weight: bold; color: #3D61E3; margin-left: 10px; }\n\n .el-link { color: #3D61E3; cursor: pointer; font-size: 12px; }\n .el-link:hover { color: #2D4CB8; }\n .el-link.danger { color: #f56c6c; }\n\n /* Multi-select with tags (Element Plus style) */\n .multi-select-wrapper { position: relative; }\n .multi-select {\n width: 240px; height: 28px; border: 1px solid #dcdfe6; border-radius: 3px;\n padding: 0 30px 0 8px; font-size: 13px; background: #fff; cursor: pointer;\n display: flex; flex-wrap: nowrap; align-items: center; gap: 4px;\n transition: border-color .2s; position: relative; overflow: hidden;\n }\n .multi-select:hover { border-color: #c0c4cc; }\n .multi-select.focused { border-color: #3D61E3; }\n .multi-select.disabled { background: #f5f7fa; cursor: not-allowed; }\n .multi-select .placeholder { color: #c0c4cc; font-size: 13px; padding: 4px 0; }\n .multi-select .arrow {\n position: absolute; right: 8px; top: 50%; transform: translateY(-50%);\n color: #c0c4cc; display: inline-flex; transition: transform .2s;\n }\n .multi-select.focused .arrow { transform: translateY(-50%) rotate(180deg); color: #3D61E3; }\n .multi-select .tag {\n display: inline-flex; align-items: center; gap: 2px;\n background: #f0f2f5; border-radius: 3px; padding: 0 6px; height: 20px;\n font-size: 12px; color: #606266; line-height: 20px;\n }\n .multi-select .tag .tag-close {\n display: inline-flex; cursor: pointer; color: #909399; margin-left: 2px; line-height: 1;\n }\n .multi-select .tag .tag-close:hover { color: #3D61E3; }\n .multi-select-dropdown {\n position: absolute; z-index: 100; background: #fff; left: 0; top: 100%; margin-top: 4px;\n border: 1px solid #e4e7ed; border-radius: 3px;\n box-shadow: 0 4px 12px rgba(0,0,0,.12); min-width: 240px; max-height: 140px; overflow-y: auto;\n }\n .multi-select-option {\n padding: 4px 12px; font-size: 13px; color: #606266; cursor: pointer;\n transition: background .2s;\n }\n .multi-select-option:hover { background: #f5f7fa; }\n .multi-select-option.selected { color: #3D61E3; font-weight: 500; }\n\n .modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 9000; display: flex; align-items: center; justify-content: center; }\n .modal { background: #fff; border-radius: 6px; width: 520px; max-width: 90vw; box-shadow: 0 12px 32px rgba(0,0,0,.12); display: flex; flex-direction: column; }\n .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px 12px; border-bottom: 1px solid #e4e7ed; }\n .modal-title { font-size: 14px; font-weight: 600; color: #303133; }\n .modal-close { background: none; border: none; font-size: 18px; cursor: pointer; color: #909399; padding: 0; line-height: 1; }\n .modal-close:hover { color: #3D61E3; }\n .modal-body { padding: 20px; }\n .modal-body textarea { min-height: 120px; }\n .modal-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid #e4e7ed; }\n .modal-footer button { padding: 6px 16px; font-size: 12px; border-radius: 3px; cursor: pointer; border: 1px solid #dcdfe6; background: #fff; color: #606266; }\n .modal-footer button:hover { color: #3D61E3; border-color: #a0cfff; }\n .modal-footer button.primary { background: #3D61E3; border-color: #3D61E3; color: #fff; }\n .modal-footer button.primary:hover { background: #2D4CB8; border-color: #2D4CB8; }\n `\n\n @property({ type: Number, attribute: 'order-index' }) orderIndex = 0\n @property({ type: Boolean, attribute: 'is-edit' }) isEdit = false\n @property({ type: Boolean, attribute: 'is-save' }) isSave = false\n @property({ type: Boolean, attribute: 'is-set' }) isSet = false\n @property({ type: Boolean, attribute: 'is-key' }) isKey = false\n @property({ type: Boolean, attribute: 'show-action' }) showAction = true\n @property({ type: Boolean, attribute: 'show-analysis' }) showAnalysis = true\n @property({ attribute: 'question-type', reflect: true }) type: AnswerType = 'single'\n @property({ type: Number, attribute: 'answer-check-type' }) answerCheckType = 1\n @property({ type: Number, attribute: 'exam-answer-relation-type' }) examAnswerRelationType = 0\n @property({ type: String, attribute: 'rich-text-content' }) richTextContent = ''\n @property({ type: String }) analysis = ''\n @property({ type: Number, attribute: 'least-answer-count' }) leastAnswerCount = 2\n @property({ type: String, attribute: 'exam-expand' }) examExpand = ''\n @property({ type: String, attribute: 'custom-id' }) customId = ''\n @property({ type: Number, attribute: 'exam-id' }) examId = 0\n @property({ type: Object }) uploadImage: (file: File) => Promise<string> = async (file: File) => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = (e) => resolve(e.target?.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n }\n\n @property({ type: Array, attribute: 'answer-list' })\n get answerList() { return this._answers }\n\n set answerList(v: any) {\n const arr = Array.isArray(v) ? v : []\n this._answers = arr.length\n ? arr.map((a: any) => ({ ...a }))\n : [\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n ]\n this.requestUpdate('answerList')\n }\n\n // 双向绑定支持\n @property({ type: String, attribute: 'model-value' }) modelValue = ''\n @property({ type: Boolean, attribute: 'use-model' }) useModel = false\n\n @state() private _answers: Answer[] = [\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n ]\n\n @property({ type: String }) title = ''\n\n @state() private _title = ''\n @state() private _analysis = ''\n @state() private _richText = ''\n @state() private _showRichText = false\n @state() private _leastAnswerCount = 2\n @state() private _answerCheckType = 1\n @state() private _isKey = false\n @state() private _orderList: string[] = []\n @state() private _resultDialogOpen = false\n @state() private _resultDialogIndex = 0\n @state() private _resultDialogValue = ''\n @state() private _sortDropdownOpen = false\n\n private readonly TITLE_MAX = 200\n private readonly ANSWER_MAX = 100\n\n connectedCallback() {\n super.connectedCallback()\n document.addEventListener('click', this._handleDocumentClick)\n this._syncExternalProps()\n if (this.richTextContent) {\n this._richText = this.richTextContent\n this._showRichText = true\n }\n }\n\n firstUpdated() {\n this._syncExternalProps()\n if (this.richTextContent) {\n this._richText = this.richTextContent\n this._showRichText = true\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n document.removeEventListener('click', this._handleDocumentClick)\n }\n\n private _handleDocumentClick = (e: MouseEvent) => {\n const path = e.composedPath()\n const wrapper = this.shadowRoot?.querySelector('.multi-select-wrapper')\n if (wrapper && !path.includes(wrapper)) {\n this._sortDropdownOpen = false\n this.requestUpdate()\n }\n }\n\n willUpdate(changed: Map<string, unknown>) {\n if (changed.has('isEdit') && this.isEdit) { this._syncProps() }\n if (changed.has('title') || changed.has('answerList') || changed.has('analysis') || changed.has('leastAnswerCount') || changed.has('answerCheckType') || changed.has('isKey')) {\n this._syncExternalProps()\n }\n if (changed.has('examExpand') || changed.has('answerList')) { this._syncExamExpand() }\n // 当外部 modelValue 变化时同步内部状态\n if (changed.has('modelValue') && this.useModel) {\n this._title = this.modelValue\n }\n }\n\n private _syncExternalProps() {\n this._title = this.title || ''\n this._analysis = this.analysis || ''\n this._leastAnswerCount = this.leastAnswerCount || 2\n this._answerCheckType = this.answerCheckType || 1\n this._isKey = this.isKey\n if (this.richTextContent) { this._richText = this.richTextContent; this._showRichText = true }\n if (this.answerList?.length) {\n this._answers = this.answerList.map((a: any) => ({\n ...a,\n title: a.title || '',\n isCorrect: !!a.isCorrect,\n }))\n }\n }\n\n private _syncProps() {\n this._title = (this as any).title || ''\n this._analysis = this.analysis || ''\n this._leastAnswerCount = this.leastAnswerCount || 2\n this._answerCheckType = this.answerCheckType || 1\n this._isKey = this.isKey\n if (this.richTextContent) { this._richText = this.richTextContent; this._showRichText = true }\n if (this.answerList?.length) {\n this._answers = this.answerList.map((a: any) => ({\n ...a,\n title: a.title || '',\n isCorrect: !!a.isCorrect,\n }))\n }\n this._syncExamExpand()\n }\n\n private _syncExamExpand() {\n if (!this.examExpand || !this.answerList?.length) { return }\n const ids = this.examExpand.split(',')\n this._orderList = ids.map((id) => {\n const answer = (this.answerList as any[]).find(a => a.answerId?.toString() === id)\n return answer ? String.fromCharCode(65 + answer.orderIndex - 1) : id\n }).filter(Boolean)\n }\n\n private _emit(name: string, detail?: unknown) {\n this.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, detail: detail ?? null }))\n }\n\n private _label(i: number) { return String.fromCharCode(65 + i) }\n\n private get _titlePlaceholder() {\n return this.type === 'single' ? '单选题' : this.type === 'multiple' ? '多选题' : '排序题'\n }\n\n private _setCorrect(item: Answer, val: boolean) {\n if (this.type === 'single') {\n this._answers.forEach((a) => { a.isCorrect = false })\n item.isCorrect = val\n }\n else {\n item.isCorrect = val\n }\n this.requestUpdate()\n }\n\n private _onTitleInput(e: Event) {\n const el = e.target as HTMLTextAreaElement\n if (el.value.length > this.TITLE_MAX) { el.value = el.value.slice(0, this.TITLE_MAX) }\n this._title = el.value\n // 双向绑定:通知外部更新\n if (this.useModel) {\n this.dispatchEvent(new CustomEvent('update:modelValue', {\n bubbles: true,\n composed: true,\n detail: this._title,\n }))\n }\n }\n\n private _onAnswerInput(e: Event, idx: number) {\n const el = e.target as HTMLInputElement\n if (el.value.length > this.ANSWER_MAX) { el.value = el.value.slice(0, this.ANSWER_MAX) }\n this._answers[idx].title = el.value\n this.requestUpdate()\n }\n\n private _addAnswer() {\n if (this.isSave) { return }\n this._answers = [...this._answers, { title: '', isCorrect: false, customAnswerId: uid() }]\n }\n\n private _deleteAnswer(index: number) {\n if (this._answers.length < 3 || this.isSave) { return }\n this._answers = this._answers.filter((_, i) => i !== index)\n }\n\n private _toggleSortItem(letter: string) {\n const idx = this._orderList.indexOf(letter)\n if (idx >= 0) {\n this._orderList = this._orderList.filter(l => l !== letter)\n }\n else {\n this._orderList = [...this._orderList, letter]\n }\n this.requestUpdate()\n }\n\n private _removeSortItem(letter: string) {\n this._orderList = this._orderList.filter(l => l !== letter)\n this.requestUpdate()\n }\n\n private _getSortOrder(index: number): number | null {\n const pos = this._orderList.indexOf(this._label(index))\n return pos >= 0 ? pos + 1 : null\n }\n\n async toJSON(): Promise<any> {\n return new Promise((resolve, reject) => {\n const row = { customId: this.customId || undefined, answerType: this.type, orderIndex: this.orderIndex }\n\n const title = this.isEdit ? this._title : (this as any).title || ''\n const answers = this.isEdit ? this._answers : this.answerList || []\n const answerCheckType = this.isEdit ? this._answerCheckType : this.answerCheckType || 1\n const leastAnswerCount = this.isEdit ? this._leastAnswerCount : this.leastAnswerCount || 2\n const analysis = this.isEdit ? this._analysis : this.analysis || ''\n const examExpand = this.isEdit\n ? this._orderList.map((l: string) => l.charCodeAt(0) - 65 + 1).join(',')\n : ((this as any).examExpand || '')\n const showRichText = this.isEdit ? this._showRichText : !!(this.richTextContent)\n const richText = this.isEdit ? this._richText : this.richTextContent || ''\n const orderList = this.isEdit ? this._orderList : (() => {\n const expand = (this as any).examExpand\n if (!expand) return []\n return expand.split(',').map((id: string) => {\n const answer = (this.answerList as any[])?.find(a => a.answerId?.toString() === id)\n return answer ? String.fromCharCode(65 + answer.orderIndex - 1) : id\n }).filter(Boolean)\n })()\n\n if (!title) {\n reject(new SubjectError('题目标题不能为空!', 'EMPTY_TITLE', 'title', row))\n return\n }\n if (!answerCheckType) {\n reject(new SubjectError('请选择答题设置', 'NO_ANSWER_CHECK_TYPE', 'answerCheckType', row))\n return\n }\n\n let msg = ''\n let isSetCorrectAnswer = false\n let correctAnswerCount = 0\n\n if (this.type === 'multiple' || this.type === 'single') {\n answers.forEach((v: any, i: number) => {\n if (!v.title?.trim()) { msg += `选项${String.fromCharCode(65 + i)}未填写。` }\n if (v.isCorrect) { isSetCorrectAnswer = true; correctAnswerCount++ }\n })\n }\n else if (this.type === 'sort') {\n if (orderList.length) { isSetCorrectAnswer = true }\n if (isSetCorrectAnswer && orderList.length < leastAnswerCount) {\n reject(new SubjectError(`排序题至少需要设置${leastAnswerCount}项排序答案`, 'SORT_COUNT_INVALID', 'orderList', row))\n return\n }\n }\n\n if (msg) {\n reject(new SubjectError(msg, 'ANSWER_EMPTY', 'answers', row))\n return\n }\n\n const uniqueAnswer = new Set(answers.map((a: any) => a.title))\n if (uniqueAnswer.size !== answers.length) {\n reject(new SubjectError('选项不能重复', 'DUPLICATE_ANSWERS', 'answers', row))\n return\n }\n\n if (this.type === 'multiple') {\n if (correctAnswerCount === 1) {\n reject(new SubjectError('请至少设置两个支持选项', 'CORRECT_COUNT_INVALID', 'answers', row))\n return\n }\n if (isSetCorrectAnswer && correctAnswerCount < leastAnswerCount) {\n reject(new SubjectError('至少选几项与支持选项数不符', 'LEAST_ANSWER_COUNT_INVALID', 'answers', row))\n return\n }\n }\n\n if (answerCheckType === 2 || answerCheckType === 3) {\n if (!isSetCorrectAnswer) {\n reject(new SubjectError('请设置支持选项', 'NO_CORRECT_ANSWER', 'answers', row))\n return\n }\n }\n\n console.log('toJSON this.type:', this.type, typeof this.type)\n const result: any = {\n answerType: String(this.type),\n title,\n answers: answers.filter((a: any) => a.title).map((a: any, i: number) => ({ ...a, orderIndex: i + 1 })),\n examExpand,\n analysis,\n isSetCorrectAnswer,\n leastAnswerCount,\n examRichTextContent: showRichText ? richText : '',\n examAnswerRelationType: this.examAnswerRelationType,\n isKey: this._isKey,\n answerCheckType,\n }\n if (this.customId) { result.customId = this.customId }\n resolve(result)\n })\n }\n\n validate(): SubjectError[] {\n const errors: SubjectError[] = []\n const row = { customId: this.customId || undefined, answerType: this.type, orderIndex: this.orderIndex }\n\n const title = this.isEdit ? this._title : (this as any).title || ''\n const answers = this.isEdit ? this._answers : this.answerList || []\n const answerCheckType = this.isEdit ? this._answerCheckType : this.answerCheckType || 1\n const leastAnswerCount = this.isEdit ? this._leastAnswerCount : this.leastAnswerCount || 2\n const orderList = this.isEdit ? this._orderList : (() => {\n const expand = (this as any).examExpand\n if (!expand) return []\n return expand.split(',').map((id: string) => {\n const answer = (this.answerList as any[])?.find(a => a.answerId?.toString() === id)\n return answer ? String.fromCharCode(65 + answer.orderIndex - 1) : id\n }).filter(Boolean)\n })()\n\n if (!title) {\n errors.push(new SubjectError('题目标题不能为空!', 'EMPTY_TITLE', 'title', row))\n }\n if (!answerCheckType) {\n errors.push(new SubjectError('请选择答题设置', 'NO_ANSWER_CHECK_TYPE', 'answerCheckType', row))\n }\n\n let isSetCorrectAnswer = false\n let correctAnswerCount = 0\n\n if (this.type === 'multiple' || this.type === 'single') {\n answers.forEach((v: any, i: number) => {\n if (!v.title?.trim()) {\n errors.push(new SubjectError(`选项${String.fromCharCode(65 + i)}未填写`, 'ANSWER_EMPTY', 'answers', row))\n }\n if (v.isCorrect) { isSetCorrectAnswer = true; correctAnswerCount++ }\n })\n }\n else if (this.type === 'sort') {\n if (orderList.length) { isSetCorrectAnswer = true }\n if (isSetCorrectAnswer && orderList.length < leastAnswerCount) {\n errors.push(new SubjectError(`排序题至少需要设置${leastAnswerCount}项排序答案`, 'SORT_COUNT_INVALID', 'orderList', row))\n }\n }\n\n const uniqueAnswer = new Set(answers.map((a: any) => a.title))\n if (uniqueAnswer.size !== answers.length && answers.length > 0) {\n errors.push(new SubjectError('选项不能重复', 'DUPLICATE_ANSWERS', 'answers', row))\n }\n\n if (this.type === 'multiple') {\n if (correctAnswerCount === 1 && answers.length > 0) {\n errors.push(new SubjectError('请至少设置两个支持选项', 'CORRECT_COUNT_INVALID', 'answers', row))\n }\n if (isSetCorrectAnswer && correctAnswerCount < leastAnswerCount) {\n errors.push(new SubjectError('至少选几项与支持选项数不符', 'LEAST_ANSWER_COUNT_INVALID', 'answers', row))\n }\n }\n\n if (answerCheckType === 2 || answerCheckType === 3) {\n if (!isSetCorrectAnswer) {\n errors.push(new SubjectError('请设置支持选项', 'NO_CORRECT_ANSWER', 'answers', row))\n }\n }\n\n return errors\n }\n\n private _openResultDialog(idx: number) {\n this._resultDialogIndex = idx\n this._resultDialogValue = this._answers[idx].resultItem || ''\n this._resultDialogOpen = true\n }\n\n private _saveResultDialog() {\n this._answers[this._resultDialogIndex].resultItem = this._resultDialogValue\n this._resultDialogOpen = false\n this.requestUpdate()\n }\n\n private _renderResultDialog() {\n if (!this._resultDialogOpen) { return '' }\n const letter = this._label(this._resultDialogIndex)\n return html`\n <div class=\"modal-backdrop\" @click=${() => { this._resultDialogOpen = false }}>\n <div class=\"modal\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">编辑结果项 — 选项 ${letter}</span>\n <button class=\"modal-close\" @click=${() => { this._resultDialogOpen = false }}>✕</button>\n </div>\n <div class=\"modal-body\">\n <textarea rows=\"5\" .value=${this._resultDialogValue}\n @input=${(e: Event) => { this._resultDialogValue = (e.target as HTMLTextAreaElement).value }}\n placeholder=\"请输入该选项的结果项内容\"></textarea>\n </div>\n <div class=\"modal-footer\">\n <button @click=${() => { this._resultDialogOpen = false }}>取消</button>\n <button class=\"primary\" @click=${() => this._saveResultDialog()}>保存</button>\n </div>\n </div>\n </div>\n `\n }\n\n private async _save(e?: Event) {\n e?.stopImmediatePropagation()\n try {\n const data = await this.toJSON()\n this._emit('save', data)\n }\n catch (err: any) {\n showToast(err.message)\n }\n }\n\n private _renderPreview() {\n const typeSuffix = this.type === 'single'\n ? '(单选题)'\n : `(${this._titlePlaceholder}${this.leastAnswerCount ? `至少选${this.leastAnswerCount}项${this.type === 'sort' ? '并排序' : ''}` : ''})`\n const answers = this.answerList as Answer[]\n return html`\n <div class=\"preview\">\n <div><span class=\"title\">${this.orderIndex + 1}.${(this as any).title || ''}${typeSuffix}${this._isKey ? html`<span class=\"key-badge\">核心题</span>` : ''}</span></div>\n ${this.richTextContent ? html`<div class=\"rich-text\" .innerHTML=${this.richTextContent}></div>` : ''}\n <div class=\"preview-answer\">\n ${answers.map((a, i) => html`\n <label class=\"radio\">\n <input type=\"${this.type === 'sort' ? 'checkbox' : 'radio'}\" .checked=${!!a.isCorrect} disabled />\n <span class=\"order\">${this._label(i)}.</span> ${a.title}\n ${this.type !== 'sort' && a.isCorrect ? html`<span class=\"correct\">(支持选项)</span>` : ''}\n ${this.type !== 'sort' && this.examAnswerRelationType === 1 ? html`<span class=\"result-info\">${a.resultItem ? '(已设置结果项)' : '(未设置结果项)'}</span>` : ''}\n ${this.type !== 'sort' && this.examAnswerRelationType === 2 ? html`<span class=\"result-info\">${a.answerRelations?.length ? '(已设置关联)' : '(未设置关联)'}</span>` : ''}\n </label>\n `)}\n </div>\n </div>\n `\n }\n\n private _renderEdit() {\n return html`\n <div class=\"flex-items-start\">\n <div class=\"label\"><span>题目:</span></div>\n <div style=\"flex:1\">\n <div class=\"el-input\">\n <textarea rows=\"2\" .value=${this._title} ?disabled=${this.isSave}\n maxlength=${this.TITLE_MAX}\n @input=${(e: Event) => this._onTitleInput(e)}\n placeholder=\"【${this._titlePlaceholder}】请输入问题\"></textarea>\n <span class=\"char-counter\">${this._title.length}/${this.TITLE_MAX}</span>\n </div>\n </div>\n </div>\n\n ${['multiple', 'sort'].includes(this.type)\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>设置:</span></div>\n <select class=\"el-select\" .value=${String(this._leastAnswerCount)} ?disabled=${this.isSave}\n @change=${(e: Event) => { this._leastAnswerCount = Number((e.target as HTMLSelectElement).value) }}>\n ${Array.from({ length: Math.max(0, this._answers.length - 1) }, (_, i) => i + 2).map(n => html`\n <option value=${n} ?selected=${this._leastAnswerCount === n}>至少选择${n}项</option>\n `)}\n </select>\n </div>\n `\n : ''}\n\n <div class=\"answer-list\">\n ${this._answers.map((a, i) => html`\n <div class=\"answer-item\">\n <span class=\"label\">${this._label(i)}.</span>\n <div class=\"input\">\n <input type=\"text\" .value=${a.title} ?disabled=${this.isSave}\n maxlength=${this.ANSWER_MAX}\n @input=${(e: Event) => this._onAnswerInput(e, i)}\n placeholder=\"选项${this._label(i)}\" />\n <span class=\"char-counter\">${a.title.length}/${this.ANSWER_MAX}</span>\n </div>\n\n ${this.type === 'sort' && this._getSortOrder(i) !== null\n ? html`<span class=\"sort-badge\">第${this._getSortOrder(i)}位</span>`\n : ''}\n\n ${['single', 'multiple'].includes(this.type)\n ? html`\n <label class=\"correct ${a.isCorrect ? 'is-correct' : ''}\">\n <input type=\"checkbox\" .checked=${a.isCorrect} ?disabled=${this.isSave}\n @change=${(e: Event) => this._setCorrect(a, (e.target as HTMLInputElement).checked)} />\n 支持选项\n </label>\n `\n : ''}\n\n <span class=\"icon ${this.isSave ? 'disabled' : ''}\"\n @click=${() => this._addAnswer()}>\n ${iconPlus}\n </span>\n <span class=\"icon ${this.isSave || this._answers.length < 3 ? 'disabled' : ''}\"\n @click=${() => this._deleteAnswer(i)}>\n ${iconRemove}\n </span>\n\n ${this.examAnswerRelationType === 1 && this.type !== 'sort'\n ? html`\n <span class=\"link\" @click=${() => this._openResultDialog(i)}>${a.resultItem ? '编辑结果' : '添加结果'}</span>\n `\n : ''}\n ${this.examAnswerRelationType === 2 && this.type !== 'sort'\n ? html`\n <span class=\"link\">关联检查</span>\n `\n : ''}\n </div>\n `)}\n </div>\n\n ${this.type === 'sort'\n ? html`\n <div class=\"flex-items-center\" style=\"margin-top:12px\">\n <div class=\"label\"><span>排序答案:</span></div>\n <div style=\"flex:1\">\n <div class=\"multi-select-wrapper\">\n <div class=\"multi-select ${this._sortDropdownOpen ? 'focused' : ''} ${this.isSave ? 'disabled' : ''}\"\n @click=${() => { if (!this.isSave) { this._sortDropdownOpen = !this._sortDropdownOpen; this.requestUpdate() } }}>\n ${this._orderList.length > 0\n ? this._orderList.map(l => html`\n <span class=\"tag\">\n ${l}\n <span class=\"tag-close\" @click=${(e: Event) => { e.stopPropagation(); this._removeSortItem(l) }}>✕</span>\n </span>\n `)\n : html`<span class=\"placeholder\">请按顺序选择排序答案</span>`\n }\n <span class=\"arrow\">${iconArrow}</span>\n </div>\n ${this._sortDropdownOpen\n ? html`\n <div class=\"multi-select-dropdown\">\n ${this._answers.map((_, i) => html`\n <div class=\"multi-select-option ${this._orderList.includes(this._label(i)) ? 'selected' : ''}\"\n @click=${() => { this._toggleSortItem(this._label(i)); this.requestUpdate() }}>\n ${this._label(i)}\n </div>\n `)}\n </div>\n `\n : ''}\n </div>\n </div>\n </div>\n `\n : ''}\n\n ${this._showRichText\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>富文本:</span></div>\n <div style=\"flex:1\">\n <qxs-blocksuite-editor\n .content=${this._richText}\n .uploadImage=${this.uploadImage}\n ?is-edit=${true}\n @input=${(e: CustomEvent) => { this._richText = (e.target as any).getContent() }}\n ></qxs-blocksuite-editor>\n <div class=\"flex-justify-end\" style=\"margin-top:8px\"><span class=\"el-link danger\" @click=${() => { this._showRichText = false; this._richText = '' }}>删除富文本</span></div>\n </div>\n </div>\n `\n : ''}\n\n ${this.showAnalysis\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>解析:</span></div>\n <div style=\"flex:1\">\n <textarea rows=\"2\" .value=${this._analysis}\n @input=${(e: Event) => { this._analysis = (e.target as HTMLTextAreaElement).value }}\n placeholder=\"请输入题目解析\"></textarea>\n </div>\n </div>\n `\n : ''}\n `\n }\n\n render() {\n return html`\n <qxs-subject-layout ?show-edit=${this.isEdit}>\n <div slot=\"preview\">${this._renderPreview()}</div>\n <div slot=\"edit\">${this._renderEdit()}</div>\n ${this.showAction\n ? html`\n <qxs-subject-action\n ?is-edit=${this.isEdit}\n ?is-set=${this.isSet}\n ?is-key=${this._isKey}\n ?show-other-option=${this.type === 'multiple' || this.type === 'single'}\n answer-check-type=${this._answerCheckType}\n exam-answer-relation-type=${this.examAnswerRelationType}\n @delete=${() => this._emit('delete')}\n @save=${this._save}\n @edit=${() => this._emit('edit')}\n @add=${(e: CustomEvent) => this._emit('add', e.detail)}\n @set-key=${(e: CustomEvent) => { this._isKey = e.detail.value; this._emit('set-key', e.detail) }}\n @set-answer-setting=${(e: CustomEvent) => { this._answerCheckType = e.detail.value }}\n @on-show-rich-text=${() => { this._showRichText = true }}\n ></qxs-subject-action>\n `\n : ''}\n </qxs-subject-layout>\n ${this._renderResultDialog()}\n `\n }\n}\n\nexport function register() {}\n"],"names":["SubjectError","Error","constructor","message","code","arguments","length","undefined","field","row","super","this","name","from","options","iconPlus","html","iconRemove","iconArrow","QxsSubjectSingle","LitElement","orderIndex","isEdit","isSave","isSet","isKey","showAction","showAnalysis","type","answerCheckType","examAnswerRelationType","richTextContent","analysis","leastAnswerCount","examExpand","customId","examId","uploadImage","async","Promise","resolve","reject","reader","FileReader","onload","e","target","result","onerror","readAsDataURL","file","modelValue","useModel","_answers","title","isCorrect","_title","_analysis","_richText","_showRichText","_leastAnswerCount","_answerCheckType","_isKey","_orderList","_resultDialogOpen","_resultDialogIndex","_resultDialogValue","_sortDropdownOpen","TITLE_MAX","ANSWER_MAX","_handleDocumentClick","path","composedPath","wrapper","shadowRoot","querySelector","includes","requestUpdate","answerList","v","arr","Array","isArray","map","a","connectedCallback","document","addEventListener","_syncExternalProps","firstUpdated","disconnectedCallback","removeEventListener","willUpdate","changed","has","_syncProps","_syncExamExpand","ids","split","id","answer","find","answerId","toString","String","fromCharCode","filter","Boolean","_emit","detail","dispatchEvent","CustomEvent","bubbles","composed","_label","i","_titlePlaceholder","_setCorrect","item","val","forEach","_onTitleInput","el","value","slice","_onAnswerInput","idx","_addAnswer","customAnswerId","uid","_deleteAnswer","index","_","_toggleSortItem","letter","indexOf","l","_removeSortItem","_getSortOrder","pos","toJSON","answerType","answers","charCodeAt","join","showRichText","richText","orderList","expand","msg","isSetCorrectAnswer","correctAnswerCount","trim","Set","size","examRichTextContent","validate","errors","push","_openResultDialog","resultItem","_saveResultDialog","_renderResultDialog","stopPropagation","_save","stopImmediatePropagation","data","err","createElement","textContent","Object","assign","style","position","top","left","transform","padding","borderRadius","fontSize","color","background","zIndex","boxShadow","transition","opacity","body","appendChild","setTimeout","remove","showToast","_renderPreview","typeSuffix","answerRelations","_renderEdit","Number","Math","max","n","checked","getContent","render","styles","css","__decorateClass","property","attribute","prototype","reflect","state","safeCustomElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"single.mjs","sources":["../../../../packages/components-wc/src/subject/single.ts"],"sourcesContent":["import type { AnswerType } from './types'\nimport { css, html, LitElement } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { safeCustomElement } from '../base/define'\nimport { uid } from '../base/uid'\nimport { SubjectType } from './types'\n\nexport interface SubjectErrorOptions {\n message: string\n code?: string\n field?: string\n row?: any\n}\n\nexport class SubjectError extends Error {\n constructor(\n message: string,\n public code: string = 'VALIDATION_ERROR',\n public field?: string,\n public row?: any,\n ) {\n super(message)\n this.name = 'SubjectError'\n }\n\n static from(options: SubjectErrorOptions): SubjectError {\n return new SubjectError(options.message, options.code, options.field, options.row)\n }\n}\n\ninterface Answer {\n title: string\n isCorrect: boolean\n customAnswerId?: string\n answerId?: string\n resultItem?: string\n orderIndex?: number\n answerRelations?: any[]\n relationType?: number | null\n}\n\nconst iconPlus = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`\nconst iconRemove = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`\nconst iconClose = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`\nconst iconArrow = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"/></svg>`\n\nfunction showToast(msg: string) {\n const el = document.createElement('div')\n el.textContent = msg\n Object.assign(el.style, {\n position: 'fixed', top: '20px', left: '50%', transform: 'translateX(-50%)',\n padding: '10px 20px', borderRadius: '4px', fontSize: '13px', color: '#fff',\n background: '#f56c6c', zIndex: '99999', boxShadow: '0 4px 12px rgba(0,0,0,.15)',\n transition: 'opacity .3s', opacity: '1',\n })\n document.body.appendChild(el)\n setTimeout(() => { el.style.opacity = '0'; setTimeout(() => el.remove(), 300) }, 2500)\n}\n\n@safeCustomElement('qxs-subject-single')\nexport class QxsSubjectSingle extends LitElement {\n static styles = css`\n :host { display: block; font-family: system-ui, -apple-system, \"PingFang SC\", \"Microsoft YaHei\", sans-serif; font-size: 12px; color: #5a5a5a; }\n *, ::before, ::after { box-sizing: border-box; }\n\n .preview { padding: 12px 0; }\n .preview .title { font-size: 14px; color: #303133; }\n .preview .title .key-badge {\n display: inline-block;\n margin-left: 8px;\n padding: 1px 6px;\n font-size: 11px;\n color: #fff;\n background: #f56c6c;\n border-radius: 3px;\n vertical-align: middle;\n }\n .preview .rich-text { margin-top: 8px; }\n .preview .rich-text img { max-width: 100%; }\n .preview-answer { display: flex; flex-direction: column; margin-top: 12px; }\n .preview-answer .radio { margin-top: 8px; padding-left: 8px; display: flex; align-items: center; gap: 6px; }\n .preview-answer .order { color: #909399; }\n .preview-answer .correct { color: #67c23a; }\n .preview-answer .result-info { color: #909399; }\n\n .flex { display: flex; }\n .flex-items-center { display: flex; align-items: center; }\n .flex-items-start { display: flex; align-items: flex-start; }\n .flex-justify-end { display: flex; justify-content: flex-end; }\n .label { min-width: 60px; font-size: 13px; color: #606266; }\n\n textarea {\n border: 1px solid #dcdfe6; border-radius: 3px; padding: 5px 11px;\n font-size: 13px; font-family: inherit; width: 100%; resize: none; transition: border-color .2s;\n line-height: 1.5; display: block; box-sizing: border-box;\n }\n textarea:focus { border-color: #3D61E3; outline: none; }\n textarea:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .el-input { position: relative; display: block; }\n .el-input textarea { padding-bottom: 24px; }\n .el-input .char-counter {\n position: absolute; right: 12px; bottom: 8px;\n font-size: 12px; color: #909399; line-height: 1; pointer-events: none;\n }\n\n .answer-list { margin-top: 12px; }\n .answer-item { display: flex; align-items: center; margin-top: 6px; border-radius: 4px; }\n .answer-item .label { min-width: 60px; font-size: 13px; color: #909399; }\n .answer-item .input { flex: 1; max-width: 360px; position: relative; display: block; }\n .answer-item .input input {\n height: 32px; padding: 0 50px 0 8px;\n font-size: 13px; line-height: 32px;\n border: 1px solid #dcdfe6; border-radius: 3px; width: 100%;\n transition: border-color .2s; box-sizing: border-box;\n }\n .answer-item .input input:focus { border-color: #3D61E3; outline: none; }\n .answer-item .input input:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .answer-item .input .char-counter {\n position: absolute; right: 8px; top: 50%; transform: translateY(-50%);\n font-size: 12px; color: #909399; line-height: 1; pointer-events: none;\n }\n\n .answer-item .correct { margin: 0 10px; color: #909399; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }\n .answer-item .correct:hover { color: #3D61E3; }\n .answer-item .correct.is-correct { color: #67c23a; }\n .answer-item .correct input { width: 14px; height: 14px; cursor: pointer; accent-color: #3D61E3; }\n\n .answer-item .icon {\n margin-left: 6px; cursor: pointer; display: inline-flex;\n align-items: center; justify-content: center;\n width: 24px; height: 24px; border-radius: 4px;\n border: 1px solid #dcdfe6; background: #fff; color: #909399;\n transition: all 0.2s;\n }\n .answer-item .icon:hover { color: #3D61E3; border-color: #3D61E3; background: #ecf5ff; }\n .answer-item .icon.disabled { color: #e4e7ed; border-color: #e4e7ed; cursor: not-allowed; }\n\n .answer-item .link { margin-left: 8px; color: #3D61E3; cursor: pointer; font-size: 12px; white-space: nowrap; }\n .answer-item .link:hover { color: #2D4CB8; }\n\n .el-select {\n width: 150px; height: 32px; border: 1px solid #dcdfe6; border-radius: 3px;\n padding: 0 8px; font-size: 13px; background: #fff; appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23c0c4cc' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");\n background-repeat: no-repeat; background-position: right 8px center;\n }\n .el-select:focus { border-color: #3D61E3; outline: none; }\n .el-select:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .el-select.sort-select {\n width: 360px; height: auto; min-height: 32px; appearance: auto;\n }\n\n .sort-badge { font-weight: bold; color: #3D61E3; margin-left: 10px; }\n\n .el-link { color: #3D61E3; cursor: pointer; font-size: 12px; }\n .el-link:hover { color: #2D4CB8; }\n .el-link.danger { color: #f56c6c; }\n\n /* Multi-select with tags (Element Plus style) */\n .multi-select-wrapper { position: relative; }\n .multi-select {\n width: 240px; height: 28px; border: 1px solid #dcdfe6; border-radius: 3px;\n padding: 0 30px 0 8px; font-size: 13px; background: #fff; cursor: pointer;\n display: flex; flex-wrap: nowrap; align-items: center; gap: 4px;\n transition: border-color .2s; position: relative; overflow: hidden;\n }\n .multi-select:hover { border-color: #c0c4cc; }\n .multi-select.focused { border-color: #3D61E3; }\n .multi-select.disabled { background: #f5f7fa; cursor: not-allowed; }\n .multi-select .placeholder { color: #c0c4cc; font-size: 13px; padding: 4px 0; }\n .multi-select .arrow {\n position: absolute; right: 8px; top: 50%; transform: translateY(-50%);\n color: #c0c4cc; display: inline-flex; transition: transform .2s;\n }\n .multi-select.focused .arrow { transform: translateY(-50%) rotate(180deg); color: #3D61E3; }\n .multi-select .tag {\n display: inline-flex; align-items: center; gap: 2px;\n background: #f0f2f5; border-radius: 3px; padding: 0 6px; height: 20px;\n font-size: 12px; color: #606266; line-height: 20px;\n }\n .multi-select .tag .tag-close {\n display: inline-flex; cursor: pointer; color: #909399; margin-left: 2px; line-height: 1;\n }\n .multi-select .tag .tag-close:hover { color: #3D61E3; }\n .multi-select-dropdown {\n position: absolute; z-index: 100; background: #fff; left: 0; top: 100%; margin-top: 4px;\n border: 1px solid #e4e7ed; border-radius: 3px;\n box-shadow: 0 4px 12px rgba(0,0,0,.12); min-width: 240px; max-height: 140px; overflow-y: auto;\n }\n .multi-select-option {\n padding: 4px 12px; font-size: 13px; color: #606266; cursor: pointer;\n transition: background .2s;\n }\n .multi-select-option:hover { background: #f5f7fa; }\n .multi-select-option.selected { color: #3D61E3; font-weight: 500; }\n\n .modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 9000; display: flex; align-items: center; justify-content: center; }\n .modal { background: #fff; border-radius: 6px; width: 520px; max-width: 90vw; box-shadow: 0 12px 32px rgba(0,0,0,.12); display: flex; flex-direction: column; }\n .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px 12px; border-bottom: 1px solid #e4e7ed; }\n .modal-title { font-size: 14px; font-weight: 600; color: #303133; }\n .modal-close { background: none; border: none; font-size: 18px; cursor: pointer; color: #909399; padding: 0; line-height: 1; }\n .modal-close:hover { color: #3D61E3; }\n .modal-body { padding: 20px; }\n .modal-body textarea { min-height: 120px; }\n .modal-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid #e4e7ed; }\n .modal-footer button { padding: 6px 16px; font-size: 12px; border-radius: 3px; cursor: pointer; border: 1px solid #dcdfe6; background: #fff; color: #606266; }\n .modal-footer button:hover { color: #3D61E3; border-color: #a0cfff; }\n .modal-footer button.primary { background: #3D61E3; border-color: #3D61E3; color: #fff; }\n .modal-footer button.primary:hover { background: #2D4CB8; border-color: #2D4CB8; }\n `\n\n @property({ type: Number, attribute: 'order-index' }) orderIndex = 0\n @property({ type: Boolean, attribute: 'is-edit' }) isEdit = false\n @property({ type: Boolean, attribute: 'is-save' }) isSave = false\n @property({ type: Boolean, attribute: 'is-set' }) isSet = false\n @property({ type: Boolean, attribute: 'is-key' }) isKey = false\n @property({ type: Boolean, attribute: 'show-action' }) showAction = true\n @property({ type: Boolean, attribute: 'show-analysis' }) showAnalysis = true\n @property({ attribute: 'question-type', reflect: true }) type: AnswerType = 'single'\n @property({ type: Number, attribute: 'answer-check-type' }) answerCheckType = 1\n @property({ type: Number, attribute: 'exam-answer-relation-type' }) examAnswerRelationType = 0\n @property({ type: String, attribute: 'rich-text-content' }) richTextContent = ''\n @property({ type: String }) analysis = ''\n @property({ type: Number, attribute: 'least-answer-count' }) leastAnswerCount = 2\n @property({ type: String, attribute: 'exam-expand' }) examExpand = ''\n @property({ type: String, attribute: 'custom-id' }) customId = ''\n @property({ type: Number, attribute: 'exam-id' }) examId = 0\n @property({ type: Object }) uploadImage: (file: File) => Promise<string> = async (file: File) => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = e => resolve(e.target?.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n }\n\n @property({ type: Array, attribute: 'answer-list' })\n get answerList() { return this._answers }\n\n set answerList(v: any) {\n const arr = Array.isArray(v) ? v : []\n this._answers = arr.length\n ? arr.map((a: any) => ({ ...a }))\n : [\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n ]\n this.requestUpdate('answerList')\n }\n\n // 双向绑定支持\n @property({ type: String, attribute: 'model-value' }) modelValue = ''\n @property({ type: Boolean, attribute: 'use-model' }) useModel = false\n\n @state() private _answers: Answer[] = [\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n ]\n\n @property({ type: String }) title = ''\n\n @state() private _title = ''\n @state() private _analysis = ''\n @state() private _richText = ''\n @state() private _showRichText = false\n @state() private _leastAnswerCount = 2\n @state() private _answerCheckType = 1\n @state() private _isKey = false\n @state() private _orderList: string[] = []\n @state() private _resultDialogOpen = false\n @state() private _resultDialogIndex = 0\n @state() private _resultDialogValue = ''\n @state() private _sortDropdownOpen = false\n\n private readonly TITLE_MAX = 200\n private readonly ANSWER_MAX = 100\n\n connectedCallback() {\n super.connectedCallback()\n document.addEventListener('click', this._handleDocumentClick)\n this._syncExternalProps()\n if (this.richTextContent) {\n this._richText = this.richTextContent\n this._showRichText = true\n }\n }\n\n firstUpdated() {\n this._syncExternalProps()\n if (this.richTextContent) {\n this._richText = this.richTextContent\n this._showRichText = true\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n document.removeEventListener('click', this._handleDocumentClick)\n }\n\n private _handleDocumentClick = (e: MouseEvent) => {\n const path = e.composedPath()\n const wrapper = this.shadowRoot?.querySelector('.multi-select-wrapper')\n if (wrapper && !path.includes(wrapper)) {\n this._sortDropdownOpen = false\n this.requestUpdate()\n }\n }\n\n willUpdate(changed: Map<string, unknown>) {\n if (changed.has('isEdit') && this.isEdit) { this._syncProps() }\n if (changed.has('title') || changed.has('answerList') || changed.has('analysis') || changed.has('leastAnswerCount') || changed.has('answerCheckType') || changed.has('isKey')) {\n this._syncExternalProps()\n }\n if (changed.has('examExpand') || changed.has('answerList')) { this._syncExamExpand() }\n // 当外部 modelValue 变化时同步内部状态\n if (changed.has('modelValue') && this.useModel) {\n this._title = this.modelValue\n }\n }\n\n private _syncExternalProps() {\n this._title = this.title || ''\n this._analysis = this.analysis || ''\n this._leastAnswerCount = this.leastAnswerCount || 2\n this._answerCheckType = this.answerCheckType || 1\n this._isKey = this.isKey\n if (this.richTextContent) { this._richText = this.richTextContent; this._showRichText = true }\n if (this.answerList?.length) {\n this._answers = this.answerList.map((a: any) => ({\n ...a,\n title: a.title || '',\n isCorrect: !!a.isCorrect,\n }))\n }\n }\n\n private _syncProps() {\n this._title = (this as any).title || ''\n this._analysis = this.analysis || ''\n this._leastAnswerCount = this.leastAnswerCount || 2\n this._answerCheckType = this.answerCheckType || 1\n this._isKey = this.isKey\n if (this.richTextContent) { this._richText = this.richTextContent; this._showRichText = true }\n if (this.answerList?.length) {\n this._answers = this.answerList.map((a: any) => ({\n ...a,\n title: a.title || '',\n isCorrect: !!a.isCorrect,\n }))\n }\n this._syncExamExpand()\n }\n\n private _syncExamExpand() {\n if (!this.examExpand || !this.answerList?.length) { return }\n const ids = this.examExpand.split(',')\n this._orderList = ids.map((id) => {\n const answer = (this.answerList as any[]).find(a => a.answerId?.toString() === id)\n return answer ? String.fromCharCode(65 + answer.orderIndex - 1) : id\n }).filter(Boolean)\n }\n\n private _emit(name: string, detail?: unknown) {\n this.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, detail: detail ?? null }))\n }\n\n private _label(i: number) { return String.fromCharCode(65 + i) }\n\n private get _titlePlaceholder() {\n return this.type === 'single' ? '单选题' : this.type === 'multiple' ? '多选题' : '排序题'\n }\n\n private _setCorrect(item: Answer, val: boolean) {\n if (this.type === 'single') {\n this._answers.forEach((a) => { a.isCorrect = false })\n item.isCorrect = val\n }\n else {\n item.isCorrect = val\n }\n this.requestUpdate()\n }\n\n private _onTitleInput(e: Event) {\n const el = e.target as HTMLTextAreaElement\n if (el.value.length > this.TITLE_MAX) { el.value = el.value.slice(0, this.TITLE_MAX) }\n this._title = el.value\n // 双向绑定:通知外部更新\n if (this.useModel) {\n this.dispatchEvent(new CustomEvent('update:modelValue', {\n bubbles: true,\n composed: true,\n detail: this._title,\n }))\n }\n }\n\n private _onAnswerInput(e: Event, idx: number) {\n const el = e.target as HTMLInputElement\n if (el.value.length > this.ANSWER_MAX) { el.value = el.value.slice(0, this.ANSWER_MAX) }\n this._answers[idx].title = el.value\n this.requestUpdate()\n }\n\n private _addAnswer() {\n if (this.isSave) { return }\n this._answers = [...this._answers, { title: '', isCorrect: false, customAnswerId: uid() }]\n }\n\n private _deleteAnswer(index: number) {\n if (this._answers.length < 3 || this.isSave) { return }\n this._answers = this._answers.filter((_, i) => i !== index)\n }\n\n private _toggleSortItem(letter: string) {\n const idx = this._orderList.indexOf(letter)\n if (idx >= 0) {\n this._orderList = this._orderList.filter(l => l !== letter)\n }\n else {\n this._orderList = [...this._orderList, letter]\n }\n this.requestUpdate()\n }\n\n private _removeSortItem(letter: string) {\n this._orderList = this._orderList.filter(l => l !== letter)\n this.requestUpdate()\n }\n\n private _getSortOrder(index: number): number | null {\n const pos = this._orderList.indexOf(this._label(index))\n return pos >= 0 ? pos + 1 : null\n }\n\n async toJSON(): Promise<any> {\n return new Promise((resolve, reject) => {\n const row = { customId: this.customId || undefined, answerType: this.type, orderIndex: this.orderIndex }\n\n const title = this.isEdit ? this._title : (this as any).title || ''\n const answers = this.isEdit ? this._answers : this.answerList || []\n const answerCheckType = this.isEdit ? this._answerCheckType : this.answerCheckType || 1\n const leastAnswerCount = this.isEdit ? this._leastAnswerCount : this.leastAnswerCount || 2\n const analysis = this.isEdit ? this._analysis : this.analysis || ''\n const examExpand = this.isEdit\n ? this._orderList.map((l: string) => l.charCodeAt(0) - 65 + 1).join(',')\n : ((this as any).examExpand || '')\n const showRichText = this.isEdit ? this._showRichText : !!(this.richTextContent)\n const richText = this.isEdit ? this._richText : this.richTextContent || ''\n const orderList = this.isEdit\n ? this._orderList\n : (() => {\n const expand = (this as any).examExpand\n if (!expand) { return [] }\n return expand.split(',').map((id: string) => {\n const answer = (this.answerList as any[])?.find(a => a.answerId?.toString() === id)\n return answer ? String.fromCharCode(65 + answer.orderIndex - 1) : id\n }).filter(Boolean)\n })()\n\n if (!title) {\n reject(new SubjectError('题目标题不能为空!', 'EMPTY_TITLE', 'title', row))\n return\n }\n if (!answerCheckType) {\n reject(new SubjectError('请选择答题设置', 'NO_ANSWER_CHECK_TYPE', 'answerCheckType', row))\n return\n }\n\n let msg = ''\n let isSetCorrectAnswer = false\n let correctAnswerCount = 0\n\n if (this.type === 'multiple' || this.type === 'single') {\n answers.forEach((v: any, i: number) => {\n if (!v.title?.trim()) { msg += `选项${String.fromCharCode(65 + i)}未填写。` }\n if (v.isCorrect) { isSetCorrectAnswer = true; correctAnswerCount++ }\n })\n }\n else if (this.type === 'sort') {\n if (orderList.length) { isSetCorrectAnswer = true }\n if (isSetCorrectAnswer && orderList.length < leastAnswerCount) {\n reject(new SubjectError(`排序题至少需要设置${leastAnswerCount}项排序答案`, 'SORT_COUNT_INVALID', 'orderList', row))\n return\n }\n }\n\n if (msg) {\n reject(new SubjectError(msg, 'ANSWER_EMPTY', 'answers', row))\n return\n }\n\n const uniqueAnswer = new Set(answers.map((a: any) => a.title))\n if (uniqueAnswer.size !== answers.length) {\n reject(new SubjectError('选项不能重复', 'DUPLICATE_ANSWERS', 'answers', row))\n return\n }\n\n if (this.type === 'multiple') {\n if (correctAnswerCount === 1) {\n reject(new SubjectError('请至少设置两个支持选项', 'CORRECT_COUNT_INVALID', 'answers', row))\n return\n }\n if (isSetCorrectAnswer && correctAnswerCount < leastAnswerCount) {\n reject(new SubjectError('至少选几项与支持选项数不符', 'LEAST_ANSWER_COUNT_INVALID', 'answers', row))\n return\n }\n }\n\n if (answerCheckType === 2 || answerCheckType === 3) {\n if (!isSetCorrectAnswer) {\n reject(new SubjectError('请设置支持选项', 'NO_CORRECT_ANSWER', 'answers', row))\n return\n }\n }\n\n const result: any = {\n answerType: String(this.type),\n title,\n answers: answers.filter((a: any) => a.title).map((a: any, i: number) => ({ ...a, orderIndex: i + 1 })),\n examExpand,\n analysis,\n isSetCorrectAnswer,\n leastAnswerCount,\n examRichTextContent: showRichText ? richText : '',\n examAnswerRelationType: this.examAnswerRelationType,\n isKey: this._isKey,\n answerCheckType,\n }\n if (this.customId) { result.customId = this.customId }\n resolve(result)\n })\n }\n\n validate(): SubjectError[] {\n const errors: SubjectError[] = []\n const row = { customId: this.customId || undefined, answerType: this.type, orderIndex: this.orderIndex }\n\n const title = this.isEdit ? this._title : (this as any).title || ''\n const answers = this.isEdit ? this._answers : this.answerList || []\n const answerCheckType = this.isEdit ? this._answerCheckType : this.answerCheckType || 1\n const leastAnswerCount = this.isEdit ? this._leastAnswerCount : this.leastAnswerCount || 2\n const orderList = this.isEdit\n ? this._orderList\n : (() => {\n const expand = (this as any).examExpand\n if (!expand) { return [] }\n return expand.split(',').map((id: string) => {\n const answer = (this.answerList as any[])?.find(a => a.answerId?.toString() === id)\n return answer ? String.fromCharCode(65 + answer.orderIndex - 1) : id\n }).filter(Boolean)\n })()\n\n if (!title) {\n errors.push(new SubjectError('题目标题不能为空!', 'EMPTY_TITLE', 'title', row))\n }\n if (!answerCheckType) {\n errors.push(new SubjectError('请选择答题设置', 'NO_ANSWER_CHECK_TYPE', 'answerCheckType', row))\n }\n\n let isSetCorrectAnswer = false\n let correctAnswerCount = 0\n\n if (this.type === 'multiple' || this.type === 'single') {\n answers.forEach((v: any, i: number) => {\n if (!v.title?.trim()) {\n errors.push(new SubjectError(`选项${String.fromCharCode(65 + i)}未填写`, 'ANSWER_EMPTY', 'answers', row))\n }\n if (v.isCorrect) { isSetCorrectAnswer = true; correctAnswerCount++ }\n })\n }\n else if (this.type === 'sort') {\n if (orderList.length) { isSetCorrectAnswer = true }\n if (isSetCorrectAnswer && orderList.length < leastAnswerCount) {\n errors.push(new SubjectError(`排序题至少需要设置${leastAnswerCount}项排序答案`, 'SORT_COUNT_INVALID', 'orderList', row))\n }\n }\n\n const uniqueAnswer = new Set(answers.map((a: any) => a.title))\n if (uniqueAnswer.size !== answers.length && answers.length > 0) {\n errors.push(new SubjectError('选项不能重复', 'DUPLICATE_ANSWERS', 'answers', row))\n }\n\n if (this.type === 'multiple') {\n if (correctAnswerCount === 1 && answers.length > 0) {\n errors.push(new SubjectError('请至少设置两个支持选项', 'CORRECT_COUNT_INVALID', 'answers', row))\n }\n if (isSetCorrectAnswer && correctAnswerCount < leastAnswerCount) {\n errors.push(new SubjectError('至少选几项与支持选项数不符', 'LEAST_ANSWER_COUNT_INVALID', 'answers', row))\n }\n }\n\n if (answerCheckType === 2 || answerCheckType === 3) {\n if (!isSetCorrectAnswer) {\n errors.push(new SubjectError('请设置支持选项', 'NO_CORRECT_ANSWER', 'answers', row))\n }\n }\n\n return errors\n }\n\n private _openResultDialog(idx: number) {\n this._resultDialogIndex = idx\n this._resultDialogValue = this._answers[idx].resultItem || ''\n this._resultDialogOpen = true\n }\n\n private _saveResultDialog() {\n this._answers[this._resultDialogIndex].resultItem = this._resultDialogValue\n this._resultDialogOpen = false\n this.requestUpdate()\n }\n\n private _renderResultDialog() {\n if (!this._resultDialogOpen) { return '' }\n const letter = this._label(this._resultDialogIndex)\n return html`\n <div class=\"modal-backdrop\" @click=${() => { this._resultDialogOpen = false }}>\n <div class=\"modal\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">编辑结果项 — 选项 ${letter}</span>\n <button class=\"modal-close\" @click=${() => { this._resultDialogOpen = false }}>✕</button>\n </div>\n <div class=\"modal-body\">\n <textarea rows=\"5\" .value=${this._resultDialogValue}\n @input=${(e: Event) => { this._resultDialogValue = (e.target as HTMLTextAreaElement).value }}\n placeholder=\"请输入该选项的结果项内容\"></textarea>\n </div>\n <div class=\"modal-footer\">\n <button @click=${() => { this._resultDialogOpen = false }}>取消</button>\n <button class=\"primary\" @click=${() => this._saveResultDialog()}>保存</button>\n </div>\n </div>\n </div>\n `\n }\n\n private async _save(e?: Event) {\n e?.stopImmediatePropagation()\n try {\n const data = await this.toJSON()\n this._emit('save', data)\n }\n catch (err: any) {\n showToast(err.message)\n }\n }\n\n private _renderPreview() {\n const typeSuffix = this.type === 'single'\n ? '(单选题)'\n : `(${this._titlePlaceholder}${this.leastAnswerCount ? `至少选${this.leastAnswerCount}项${this.type === 'sort' ? '并排序' : ''}` : ''})`\n const answers = this.answerList as Answer[]\n return html`\n <div class=\"preview\">\n <div><span class=\"title\">${this.orderIndex + 1}.${(this as any).title || ''}${typeSuffix}${this._isKey ? html`<span class=\"key-badge\">核心题</span>` : ''}</span></div>\n ${this.richTextContent ? html`<div class=\"rich-text\" .innerHTML=${this.richTextContent}></div>` : ''}\n <div class=\"preview-answer\">\n ${answers.map((a, i) => html`\n <label class=\"radio\">\n <input type=\"${this.type === 'sort' ? 'checkbox' : 'radio'}\" .checked=${!!a.isCorrect} disabled />\n <span class=\"order\">${this._label(i)}.</span> ${a.title}\n ${this.type !== 'sort' && a.isCorrect ? html`<span class=\"correct\">(支持选项)</span>` : ''}\n ${this.type !== 'sort' && this.examAnswerRelationType === 1 ? html`<span class=\"result-info\">${a.resultItem ? '(已设置结果项)' : '(未设置结果项)'}</span>` : ''}\n ${this.type !== 'sort' && this.examAnswerRelationType === 2 ? html`<span class=\"result-info\">${a.answerRelations?.length ? '(已设置关联)' : '(未设置关联)'}</span>` : ''}\n </label>\n `)}\n </div>\n </div>\n `\n }\n\n private _renderEdit() {\n return html`\n <div class=\"flex-items-start\">\n <div class=\"label\"><span>题目:</span></div>\n <div style=\"flex:1\">\n <div class=\"el-input\">\n <textarea rows=\"2\" .value=${this._title} ?disabled=${this.isSave}\n maxlength=${this.TITLE_MAX}\n @input=${(e: Event) => this._onTitleInput(e)}\n placeholder=\"【${this._titlePlaceholder}】请输入问题\"></textarea>\n <span class=\"char-counter\">${this._title.length}/${this.TITLE_MAX}</span>\n </div>\n </div>\n </div>\n\n ${['multiple', 'sort'].includes(this.type)\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>设置:</span></div>\n <select class=\"el-select\" .value=${String(this._leastAnswerCount)} ?disabled=${this.isSave}\n @change=${(e: Event) => { this._leastAnswerCount = Number((e.target as HTMLSelectElement).value) }}>\n ${Array.from({ length: Math.max(0, this._answers.length - 1) }, (_, i) => i + 2).map(n => html`\n <option value=${n} ?selected=${this._leastAnswerCount === n}>至少选择${n}项</option>\n `)}\n </select>\n </div>\n `\n : ''}\n\n <div class=\"answer-list\">\n ${this._answers.map((a, i) => html`\n <div class=\"answer-item\">\n <span class=\"label\">${this._label(i)}.</span>\n <div class=\"input\">\n <input type=\"text\" .value=${a.title} ?disabled=${this.isSave}\n maxlength=${this.ANSWER_MAX}\n @input=${(e: Event) => this._onAnswerInput(e, i)}\n placeholder=\"选项${this._label(i)}\" />\n <span class=\"char-counter\">${a.title.length}/${this.ANSWER_MAX}</span>\n </div>\n\n ${this.type === 'sort' && this._getSortOrder(i) !== null\n ? html`<span class=\"sort-badge\">第${this._getSortOrder(i)}位</span>`\n : ''}\n\n ${['single', 'multiple'].includes(this.type)\n ? html`\n <label class=\"correct ${a.isCorrect ? 'is-correct' : ''}\">\n <input type=\"checkbox\" .checked=${a.isCorrect} ?disabled=${this.isSave}\n @change=${(e: Event) => this._setCorrect(a, (e.target as HTMLInputElement).checked)} />\n 支持选项\n </label>\n `\n : ''}\n\n <span class=\"icon ${this.isSave ? 'disabled' : ''}\"\n @click=${() => this._addAnswer()}>\n ${iconPlus}\n </span>\n <span class=\"icon ${this.isSave || this._answers.length < 3 ? 'disabled' : ''}\"\n @click=${() => this._deleteAnswer(i)}>\n ${iconRemove}\n </span>\n\n ${this.examAnswerRelationType === 1 && this.type !== 'sort'\n ? html`\n <span class=\"link\" @click=${() => this._openResultDialog(i)}>${a.resultItem ? '编辑结果' : '添加结果'}</span>\n `\n : ''}\n ${this.examAnswerRelationType === 2 && this.type !== 'sort'\n ? html`\n <span class=\"link\">关联检查</span>\n `\n : ''}\n </div>\n `)}\n </div>\n\n ${this.type === 'sort'\n ? html`\n <div class=\"flex-items-center\" style=\"margin-top:12px\">\n <div class=\"label\"><span>排序答案:</span></div>\n <div style=\"flex:1\">\n <div class=\"multi-select-wrapper\">\n <div class=\"multi-select ${this._sortDropdownOpen ? 'focused' : ''} ${this.isSave ? 'disabled' : ''}\"\n @click=${() => { if (!this.isSave) { this._sortDropdownOpen = !this._sortDropdownOpen; this.requestUpdate() } }}>\n ${this._orderList.length > 0\n ? this._orderList.map(l => html`\n <span class=\"tag\">\n ${l}\n <span class=\"tag-close\" @click=${(e: Event) => { e.stopPropagation(); this._removeSortItem(l) }}>✕</span>\n </span>\n `)\n : html`<span class=\"placeholder\">请按顺序选择排序答案</span>`\n }\n <span class=\"arrow\">${iconArrow}</span>\n </div>\n ${this._sortDropdownOpen\n ? html`\n <div class=\"multi-select-dropdown\">\n ${this._answers.map((_, i) => html`\n <div class=\"multi-select-option ${this._orderList.includes(this._label(i)) ? 'selected' : ''}\"\n @click=${() => { this._toggleSortItem(this._label(i)); this.requestUpdate() }}>\n ${this._label(i)}\n </div>\n `)}\n </div>\n `\n : ''}\n </div>\n </div>\n </div>\n `\n : ''}\n\n ${this._showRichText\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>富文本:</span></div>\n <div style=\"flex:1\">\n <qxs-blocksuite-editor\n .content=${this._richText}\n .uploadImage=${this.uploadImage}\n ?is-edit=${true}\n @input=${(e: CustomEvent) => { this._richText = (e.target as any).getContent() }}\n ></qxs-blocksuite-editor>\n <div class=\"flex-justify-end\" style=\"margin-top:8px\"><span class=\"el-link danger\" @click=${() => { this._showRichText = false; this._richText = '' }}>删除富文本</span></div>\n </div>\n </div>\n `\n : ''}\n\n ${this.showAnalysis\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>解析:</span></div>\n <div style=\"flex:1\">\n <textarea rows=\"2\" .value=${this._analysis}\n @input=${(e: Event) => { this._analysis = (e.target as HTMLTextAreaElement).value }}\n placeholder=\"请输入题目解析\"></textarea>\n </div>\n </div>\n `\n : ''}\n `\n }\n\n render() {\n return html`\n <qxs-subject-layout ?show-edit=${this.isEdit}>\n <div slot=\"preview\">${this._renderPreview()}</div>\n <div slot=\"edit\">${this._renderEdit()}</div>\n ${this.showAction\n ? html`\n <qxs-subject-action\n ?is-edit=${this.isEdit}\n ?is-set=${this.isSet}\n ?is-key=${this._isKey}\n ?show-other-option=${this.type === 'multiple' || this.type === 'single'}\n answer-check-type=${this._answerCheckType}\n exam-answer-relation-type=${this.examAnswerRelationType}\n @delete=${() => this._emit('delete')}\n @save=${this._save}\n @edit=${() => this._emit('edit')}\n @add=${(e: CustomEvent) => this._emit('add', e.detail)}\n @set-key=${(e: CustomEvent) => { this._isKey = e.detail.value; this._emit('set-key', e.detail) }}\n @set-answer-setting=${(e: CustomEvent) => { this._answerCheckType = e.detail.value }}\n @on-show-rich-text=${() => { this._showRichText = true }}\n ></qxs-subject-action>\n `\n : ''}\n </qxs-subject-layout>\n ${this._renderResultDialog()}\n `\n }\n}\n\nexport function register() {}\n"],"names":["SubjectError","Error","constructor","message","code","arguments","length","undefined","field","row","super","this","name","from","options","iconPlus","html","iconRemove","iconArrow","QxsSubjectSingle","LitElement","orderIndex","isEdit","isSave","isSet","isKey","showAction","showAnalysis","type","answerCheckType","examAnswerRelationType","richTextContent","analysis","leastAnswerCount","examExpand","customId","examId","uploadImage","async","Promise","resolve","reject","reader","FileReader","onload","e","target","result","onerror","readAsDataURL","file","modelValue","useModel","_answers","title","isCorrect","_title","_analysis","_richText","_showRichText","_leastAnswerCount","_answerCheckType","_isKey","_orderList","_resultDialogOpen","_resultDialogIndex","_resultDialogValue","_sortDropdownOpen","TITLE_MAX","ANSWER_MAX","_handleDocumentClick","path","composedPath","wrapper","shadowRoot","querySelector","includes","requestUpdate","answerList","v","arr","Array","isArray","map","a","connectedCallback","document","addEventListener","_syncExternalProps","firstUpdated","disconnectedCallback","removeEventListener","willUpdate","changed","has","_syncProps","_syncExamExpand","ids","split","id","answer","find","answerId","toString","String","fromCharCode","filter","Boolean","_emit","detail","dispatchEvent","CustomEvent","bubbles","composed","_label","i","_titlePlaceholder","_setCorrect","item","val","forEach","_onTitleInput","el","value","slice","_onAnswerInput","idx","_addAnswer","customAnswerId","uid","_deleteAnswer","index","_","_toggleSortItem","letter","indexOf","l","_removeSortItem","_getSortOrder","pos","toJSON","answerType","answers","charCodeAt","join","showRichText","richText","orderList","expand","msg","isSetCorrectAnswer","correctAnswerCount","trim","Set","size","examRichTextContent","validate","errors","push","_openResultDialog","resultItem","_saveResultDialog","_renderResultDialog","stopPropagation","_save","stopImmediatePropagation","data","err","createElement","textContent","Object","assign","style","position","top","left","transform","padding","borderRadius","fontSize","color","background","zIndex","boxShadow","transition","opacity","body","appendChild","setTimeout","remove","showToast","_renderPreview","typeSuffix","answerRelations","_renderEdit","Number","Math","max","n","checked","getContent","render","styles","css","__decorateClass","property","attribute","prototype","reflect","state","safeCustomElement"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var e=require("@tiptap/core"),t=require("@tiptap/extension-blockquote"),i=require("@tiptap/extension-bold"),o=require("@tiptap/extension-bullet-list"),r=require("@tiptap/extension-code"),s=require("@tiptap/extension-document"),l=require("@tiptap/extension-heading"),n=require("@tiptap/extension-history"),a=require("@tiptap/extension-horizontal-rule"),d=require("@tiptap/extension-image"),c=require("@tiptap/extension-italic"),h=require("@tiptap/extension-link"),p=require("@tiptap/extension-list-item"),b=require("@tiptap/extension-ordered-list"),u=require("@tiptap/extension-paragraph"),g=require("@tiptap/extension-strike"),x=require("@tiptap/extension-table"),m=require("@tiptap/extension-table-cell"),y=require("@tiptap/extension-table-header"),v=require("@tiptap/extension-table-row"),f=require("@tiptap/extension-text"),_=require("@tiptap/extension-text-align"),w=require("@tiptap/extension-underline"),k=require("@tiptap/extension-placeholder"),C=require("lit"),M=require("../node_modules/.pnpm/@lit_reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/property.cjs"),T=require("../node_modules/.pnpm/@lit_reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/state.cjs"),A=require("../base/define.cjs"),$=Object.defineProperty,B=Object.getOwnPropertyDescriptor,E=(e,t,i,o)=>{for(var r,s=o>1?void 0:o?B(t,i):t,l=e.length-1;l>=0;l--)(r=e[l])&&(s=(o?r(t,i,s):r(s))||s);return o&&s&&$(t,i,s),s};exports.QxsBlocksuiteEditor=class extends C.LitElement{constructor(){super(...arguments),this.content="",this.modelValue="",this.useModelAttr="false",this.autoSyncAttr="true",this.readonlyAttr="false",this.previewAttr="false",this.isEditAttr="false",this.customStylesAttr="",this._injectedStyleEl=null,this.uploadImage=async e=>new Promise((t,i)=>{const o=new FileReader;o.onload=e=>t(e.target?.result),o.onerror=i,o.readAsDataURL(e)}),this._editor=null,this._pendingContent=null,this._tableRows=3,this._tableCols=3,this._hoverRow=0,this._hoverCol=0,this._tableDropdownOpen=!1,this._tableCellToolbar={x:0,y:0,visible:!1,cellRow:0,cellCol:0},this._tableEdgeHover={type:null,index:0,position:{x:0,y:0}},this._imageToolbar={x:0,y:0,visible:!1},this._imageMoreMenuVisible=!1,this._hasSlashCommand=!1,this._tableEdgeDetectionSetup=!1}get customStyles(){return this.customStylesAttr}set customStyles(e){this.customStylesAttr=e}_injectCustomStyles(){const e=this.shadowRoot;if(!e)return;if(this._injectedStyleEl&&(this._injectedStyleEl.remove(),this._injectedStyleEl=null),!this.customStylesAttr)return;const t=document.createElement("style");t.textContent=this.customStylesAttr,e.appendChild(t),this._injectedStyleEl=t}get useModel(){return"true"===this.useModelAttr||""===this.useModelAttr||this.hasAttribute("use-model")}set useModel(e){this.useModelAttr=String(e)}get autoSync(){return"false"!==this.autoSyncAttr}set autoSync(e){this.autoSyncAttr=String(e)}get readonly(){return"false"!==this.readonlyAttr}set readonly(e){this.readonlyAttr=String(e)}get preview(){return"false"!==this.previewAttr}set preview(e){this.previewAttr=String(e)}get isEdit(){return"true"===this.isEditAttr}set isEdit(e){this.isEditAttr=String(e)}_initEditor(){if(this._editor)return;const C=this.shadowRoot?.querySelector(".editor-content");if(!C)return void requestAnimationFrame(()=>this._initEditor());for(;C.firstChild;)C.removeChild(C.firstChild);const M=this.useModel||this.hasAttribute("use-model"),T=this.getAttribute("model-value")??this.modelValue,A=this.content,$=M?(this._pendingContent??T)||"<p></p>":(this._pendingContent??A)||"<p></p>",B=[s,u,f,i,c,w,g,r,l.configure({levels:[1,2,3]}),o,b,p,t,a,n,d.configure({inline:!1,allowBase64:!0}),h.configure({openOnClick:!1,HTMLAttributes:{rel:"noopener noreferrer"}}),_.configure({types:["heading","paragraph"]}),x.Table.configure({resizable:!0}),v.TableRow,m.TableCell,y.TableHeader,k.configure({placeholder:"输入 / 唤出快捷命令"}),e.Extension.create({name:"clearMarksOnEnter",addKeyboardShortcuts(){return{Enter:()=>(this.editor.chain().focus().unsetAllMarks().clearNodes().run(),!1)}}})];this._editor=new e.Editor({element:C,extensions:B,editable:!this.readonly,content:$}),this._pendingContent=null,this._editor.on("selectionUpdate",()=>{this.requestUpdate(),this._updateBubbleMenuPosition(),this._editor?.isActive("table")?this._showTableCellToolbar():this._hideTableCellToolbar();const e=this._editor;if(e){const{selection:t}=e.state,{$from:i}=t;if("image"===i.node(i.depth).type.name){const t=e.view.coordsAtPos(i.start()),o=this.shadowRoot?.querySelector(".editor-wrapper")?.getBoundingClientRect();if(o){const e=t.left-o.left+(t.right-t.left)/2,i=t.top-o.top-40;this._showImageToolbar({x:e,y:i})}}else this._hideImageToolbar()}}),this._editor.on("transaction",()=>{this.requestUpdate(),this._editor?.isActive("table")?this._showTableCellToolbar():this._hideTableCellToolbar(),this._checkSlashCommand(),this._setupTableEdgeDetection(),this._emitContentChange()}),this._editor.on("update",()=>{this._emitContentChange()})}_emitContentChange(){if(!this._editor)return;const e=this._editor.getHTML();this.dispatchEvent(new CustomEvent("content-change",{detail:e,bubbles:!0,composed:!0})),this.autoSync&&(this.modelValue=e)}_setupTableEdgeDetection(){const e=this.shadowRoot?.querySelector(".editor-content"),t=this.shadowRoot?.querySelector(".editor-wrapper");if(!e||this._tableEdgeDetectionSetup)return;this._tableEdgeDetectionSetup=!0,e.addEventListener("mousemove",e=>{this._handleTableEdgeMouseMove(e)}),e.addEventListener("mouseleave",()=>{this._tableEdgeHover={type:null,index:0,position:{x:0,y:0}}});const i=()=>{this._editor?.chain().focus().run()};e.addEventListener("click",i),t?.addEventListener("click",i)}_handleTableEdgeMouseMove(e){if(!this._editor?.isActive("table"))return this._tableEdgeHover={type:null,index:0,position:{x:0,y:0}},void this.requestUpdate();const t=e.target.closest("table");if(!t)return this._tableEdgeHover={type:null,index:0,position:{x:0,y:0}},void this.requestUpdate();const i=t.getBoundingClientRect(),o=this.shadowRoot?.querySelector(".editor-wrapper");if(!o)return;const r=o.getBoundingClientRect(),s=e.clientX-r.left,l=e.clientY-r.top,n=10,a=i.height/t.rows.length;for(let o=0;o<t.rows.length;o++){const t=i.top+o*a,l=t+a;if(e.clientY>=t-n&&e.clientY<=t+n)return this._tableEdgeHover={type:"row",index:o,position:{x:s,y:t-r.top}},void this.requestUpdate();if(e.clientY>=l-n&&e.clientY<=l+n)return this._tableEdgeHover={type:"row",index:o+1,position:{x:s,y:l-r.top}},void this.requestUpdate()}const d=i.width/t.rows[0]?.cells.length||1;for(let o=0;o<(t.rows[0]?.cells.length||0);o++){const t=i.left+o*d,s=t+d;if(e.clientX>=t-n&&e.clientX<=t+n)return this._tableEdgeHover={type:"col",index:o,position:{x:t-r.left,y:l}},void this.requestUpdate();if(e.clientX>=s-n&&e.clientX<=s+n)return this._tableEdgeHover={type:"col",index:o+1,position:{x:s-r.left,y:l}},void this.requestUpdate()}this._tableEdgeHover={type:null,index:0,position:{x:0,y:0}},this.requestUpdate()}_checkSlashCommand(){if(!this._editor)return;const{selection:e}=this._editor.state,t=this._editor.state.doc.textBetween(Math.max(0,e.from-10),e.from," ");this._hasSlashCommand=t.endsWith("/")}firstUpdated(){this._injectCustomStyles(),this._initEditor()}updated(e){if(e.has("customStylesAttr")&&this._injectCustomStyles(),this._editor){if(e.has("content")||e.has("modelValue")&&this.useModel){const e=this.useModel?this.modelValue:this.content;e!==this._editor.getHTML()&&this._editor.commands.setContent(e||"<p></p>")}e.has("readonly")&&this._editor.setEditable(!this.readonly)}else e.has("content")&&(this._pendingContent=this.content),e.has("modelValue")&&this.useModel&&(this._pendingContent=this.modelValue)}disconnectedCallback(){super.disconnectedCallback(),this._editor?.destroy(),this._editor=null}getContent(){return this._editor?.getHTML()??""}forceUpdate(){if(this.requestUpdate(),this._editor){const e=this.useModel?this.modelValue:this.content;e!==this._editor.getHTML()&&this._editor.commands.setContent(e||"<p></p>")}}forceSync(){this.forceUpdate()}_applyFormat(e){if(this._hasSlashCommand&&this._editor){const{selection:e}=this._editor.state;this._editor.chain().focus().deleteRange({from:e.from-1,to:e.from}).run(),this._hasSlashCommand=!1}e()}_toggleBold(){this._applyFormat(()=>this._editor?.chain().focus().toggleBold().run())}_toggleItalic(){this._applyFormat(()=>this._editor?.chain().focus().toggleItalic().run())}_toggleUnderline(){this._applyFormat(()=>this._editor?.chain().focus().toggleUnderline().run())}_toggleStrike(){this._applyFormat(()=>this._editor?.chain().focus().toggleStrike().run())}_toggleCode(){this._applyFormat(()=>this._editor?.chain().focus().toggleCode().run())}_setHeading(e){this._applyFormat(()=>this._editor?.chain().focus().toggleHeading({level:e}).run())}_setParagraph(){this._applyFormat(()=>this._editor?.chain().focus().setParagraph().run())}_toggleBulletList(){this._applyFormat(()=>this._editor?.chain().focus().toggleBulletList().run())}_toggleOrderedList(){this._applyFormat(()=>this._editor?.chain().focus().toggleOrderedList().run())}_toggleBlockquote(){this._applyFormat(()=>this._editor?.chain().focus().toggleBlockquote().run())}_setTextAlign(e){this._applyFormat(()=>this._editor?.chain().focus().setTextAlign(e).run())}_setLink(){const e=window.prompt("请输入链接地址:");e&&this._applyFormat(()=>this._editor?.chain().focus().setLink({href:e}).run())}_unsetLink(){this._applyFormat(()=>this._editor?.chain().focus().unsetLink().run())}_insertTable(e,t){this._editor?.chain().focus().insertTable({rows:e??this._tableRows,cols:t??this._tableCols,withHeaderRow:!0}).run()}async _handleImageUpload(e){const t=e.target,i=t.files?.[0];if(i)try{const e=await this.uploadImage(i);this._editor?.chain().focus().setImage({src:e}).run()}catch(e){}t.value=""}_triggerImageUpload(){const e=this.shadowRoot?.querySelector(".image-input");e?.click()}_insertTableByClick(e,t){if(this._hasSlashCommand&&this._editor){const{selection:e}=this._editor.state;this._editor.chain().focus().deleteRange({from:e.from-1,to:e.from}).run(),this._hasSlashCommand=!1}this._tableRows=e,this._tableCols=t,this._insertTable(e,t)}_insertHorizontalRule(){this._editor?.chain().focus().setHorizontalRule().run()}_showTableCellToolbar(){if(!this._editor?.isActive("table"))return;const{state:e}=this._editor,{selection:t}=e,i=this._editor.view.coordsAtPos(t.from),o=this.shadowRoot?.querySelector(".editor-wrapper");if(!o)return;const r=o.getBoundingClientRect(),s=this._getTableCellRow(),l=this._getTableCellCol();(0===s||0===l)&&(this._tableCellToolbar={x:i.left-r.left,y:i.bottom-r.top+8,visible:!0,cellRow:s,cellCol:l})}_getTableCellRow(){if(!this._editor)return 0;const{selection:e}=this._editor.state,t=this._editor.state.doc.resolve(e.from);for(let e=t.depth;e>0;e--){if("tableCell"===t.node(e).type.name)return t.index(e-1)}return 0}_getTableCellCol(){if(!this._editor)return 0;const{selection:e}=this._editor.state,t=this._editor.state.doc.resolve(e.from);for(let e=t.depth;e>0;e--){if("tableCell"===t.node(e).type.name)return t.index(e)}return 0}_hideTableCellToolbar(){this._tableCellToolbar={...this._tableCellToolbar,visible:!1}}_addTableRowAbove(){this._editor?.chain().focus().addRowBefore().run(),this._hideTableCellToolbar()}_addTableRowBelow(){this._editor?.chain().focus().addRowAfter().run(),this._hideTableCellToolbar()}_addTableColumnLeft(){this._editor?.chain().focus().addColumnBefore().run(),this._hideTableCellToolbar()}_addTableColumnRight(){this._editor?.chain().focus().addColumnAfter().run(),this._hideTableCellToolbar()}_deleteTableRow(){this._editor?.chain().focus().deleteRow().run(),this._hideTableCellToolbar()}_deleteTableColumn(){this._editor?.chain().focus().deleteColumn().run(),this._hideTableCellToolbar()}_deleteTable(){this._editor?.chain().focus().deleteTable().run(),this._hideTableCellToolbar()}_showImageToolbar(e){this._imageToolbar={x:e.x,y:e.y,visible:!0},this._imageMoreMenuVisible=!1}_hideImageToolbar(){this._imageToolbar={...this._imageToolbar,visible:!1},this._imageMoreMenuVisible=!1}_toggleImageMoreMenu(){this._imageMoreMenuVisible=!this._imageMoreMenuVisible}_deleteImage(){this._editor?.chain().focus().deleteNode("image").run(),this._hideImageToolbar()}_insertImageAfter(){this._triggerImageUpload(),this._imageMoreMenuVisible=!1}_setImageAlignLeft(){const e=this._editor;if(e){const{selection:t}=e.state,i=t.from;e.chain().focus().setNodeSelection(i).run();const o=this.shadowRoot?.querySelector(".ProseMirror img.ProseMirror-selectednode");o&&(o.style.display="block",o.style.margin="0 auto 0 0")}this._imageMoreMenuVisible=!1}_setImageAlignCenter(){const e=this._editor;if(e){const{selection:t}=e.state,i=t.from;e.chain().focus().setNodeSelection(i).run();const o=this.shadowRoot?.querySelector(".ProseMirror img.ProseMirror-selectednode");o&&(o.style.display="block",o.style.margin="0 auto")}this._imageMoreMenuVisible=!1}_setImageAlignRight(){const e=this._editor;if(e){const{selection:t}=e.state,i=t.from;e.chain().focus().setNodeSelection(i).run();const o=this.shadowRoot?.querySelector(".ProseMirror img.ProseMirror-selectednode");o&&(o.style.display="block",o.style.margin="0 0 0 auto")}this._imageMoreMenuVisible=!1}_updateImageToolbarPosition(){requestAnimationFrame(()=>{const e=this._editor;if(!e)return;const{selection:t}=e.state,{$from:i}=t;if("image"===i.node(i.depth).type.name?i.node(i.depth):null){const t=e.view.coordsAtPos(i.start()),o=this.shadowRoot?.querySelector(".editor-wrapper")?.getBoundingClientRect();if(o){const e=t.left-o.left+(t.right-t.left)/2,i=t.top-o.top-40;this._showImageToolbar({x:e,y:i})}}else this._hideImageToolbar()})}_getTextLabel(){const e=this._editor;return e?e.isActive("heading",{level:1})?"标题 1":e.isActive("heading",{level:2})?"标题 2":e.isActive("heading",{level:3})?"标题 3":"正文":"正文"}_getAlignLabel(){const e=this._editor;return e?e.isActive({textAlign:"center"})?"居中":e.isActive({textAlign:"right"})?"右对齐":"左对齐":"对齐"}_updateBubbleMenuPosition(){requestAnimationFrame(()=>{const e=this.shadowRoot?.querySelector(".bubble-menu"),t=this.shadowRoot?.querySelector(".ProseMirror"),i=this.shadowRoot?.querySelector(".editor-wrapper");if(!e||!t||!i)return;const o=this._editor,r=o?.isActive("table")??!1,{selection:s}=o?.state??{selection:null};if(r&&s&&!s.empty&&o){const{from:t,to:i}=s,r=o.state.doc.resolve(t),l=o.state.doc.resolve(i);let n=!1;for(let e=r.depth;e>=0;e--)if("table"===r.node(e).type.name){n=!0;break}const a=r.node(r.depth),d=l.node(l.depth);if("table"!==a.type.name&&"table"!==d.type.name||(n=!0),n)return e.style.opacity="0",void(e.style.visibility="hidden")}if(s&&!s.empty);else if(!s||s.empty&&!this._hasSlashCommand)return e.style.opacity="0",void(e.style.visibility="hidden");const l=i.getBoundingClientRect(),n=e.getBoundingClientRect(),{from:a}=s,d=this._editor?.view.coordsAtPos(a);if(!d)return;let c=d.left-l.left,h=d.top-l.top-40;c+n.width>l.width&&(c=l.width-n.width-8),c<0&&(c=8),h<0&&(h=d.bottom-l.top+8),e.style.left=`${c}px`,e.style.top=`${h}px`,e.style.opacity="1",e.style.visibility="visible"})}render(){const e=this._editor;return C.html`
|
|
1
|
+
"use strict";var e=require("@tiptap/core"),t=require("@tiptap/extension-blockquote"),i=require("@tiptap/extension-bold"),o=require("@tiptap/extension-bullet-list"),r=require("@tiptap/extension-code"),l=require("@tiptap/extension-document"),s=require("@tiptap/extension-heading"),n=require("@tiptap/extension-history"),a=require("@tiptap/extension-horizontal-rule"),d=require("@tiptap/extension-image"),c=require("@tiptap/extension-italic"),h=require("@tiptap/extension-link"),b=require("@tiptap/extension-list-item"),p=require("@tiptap/extension-ordered-list"),u=require("@tiptap/extension-paragraph"),g=require("@tiptap/extension-strike"),x=require("@tiptap/extension-table"),m=require("@tiptap/extension-table-cell"),v=require("@tiptap/extension-table-header"),y=require("@tiptap/extension-table-row"),f=require("@tiptap/extension-text"),_=require("@tiptap/extension-text-align"),w=require("@tiptap/extension-underline"),k=require("@tiptap/extension-placeholder"),C=require("lit"),M=require("../node_modules/.pnpm/@lit_reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/property.cjs"),T=require("../node_modules/.pnpm/@lit_reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/state.cjs"),$=require("../base/define.cjs"),A=Object.defineProperty,B=Object.getOwnPropertyDescriptor,q=(e,t,i,o)=>{for(var r,l=o>1?void 0:o?B(t,i):t,s=e.length-1;s>=0;s--)(r=e[s])&&(l=(o?r(t,i,l):r(l))||l);return o&&l&&A(t,i,l),l};exports.QxsBlocksuiteEditor=class extends C.LitElement{constructor(){super(...arguments),this.content="",this.modelValue="",this.useModelAttr="false",this.readonlyAttr="false",this.previewAttr="false",this.customStylesAttr="",this._injectedStyleEl=null,this.uploadImage=async e=>new Promise((t,i)=>{const o=new FileReader;o.onload=e=>t(e.target?.result),o.onerror=i,o.readAsDataURL(e)}),this._editor=null,this._pendingContent=null,this._tableRows=3,this._tableCols=3,this._hoverRow=0,this._hoverCol=0,this._tableDropdownOpen=!1,this._tableCellToolbar={x:0,y:0,visible:!1,cellRow:0,cellCol:0},this._imageToolbar={x:0,y:0,visible:!1},this._imageMoreMenuVisible=!1,this._hasSlashCommand=!1,this._tableEdgeDetectionSetup=!1}_injectCustomStyles(){const e=this.shadowRoot;if(!e)return;if(this._injectedStyleEl&&(this._injectedStyleEl.remove(),this._injectedStyleEl=null),!this.customStylesAttr)return;const t=document.createElement("style");t.textContent=this.customStylesAttr,e.appendChild(t),this._injectedStyleEl=t}get useModel(){return"true"===this.useModelAttr||""===this.useModelAttr||this.hasAttribute("use-model")}set useModel(e){this.useModelAttr=String(e)}get readonly(){return"false"!==this.readonlyAttr}set readonly(e){this.readonlyAttr=String(e)}get preview(){return"false"!==this.previewAttr}set preview(e){this.previewAttr=String(e)}_initEditor(){if(this._editor)return;const C=this.shadowRoot?.querySelector(".editor-content");if(!C)return void requestAnimationFrame(()=>this._initEditor());for(;C.firstChild;)C.removeChild(C.firstChild);const M=this.useModel||this.hasAttribute("use-model"),T=this.getAttribute("model-value")??this.modelValue,$=this.content,A=M?(this._pendingContent??T)||"<p></p>":(this._pendingContent??$)||"<p></p>",B=[l,u,f,i,c,w,g,r,s.configure({levels:[1,2,3]}),o,p,b,t,a,n,d.configure({inline:!1,allowBase64:!0}),h.configure({openOnClick:!1,HTMLAttributes:{rel:"noopener noreferrer"}}),_.configure({types:["heading","paragraph"]}),x.Table.configure({resizable:!0}),y.TableRow,m.TableCell,v.TableHeader,k.configure({placeholder:"输入 / 唤出快捷命令"}),e.Extension.create({name:"clearMarksOnEnter",addKeyboardShortcuts(){return{Enter:()=>(this.editor.chain().focus().unsetAllMarks().clearNodes().run(),!1)}}})];this._editor=new e.Editor({element:C,extensions:B,editable:!this.readonly,content:A}),this._pendingContent=null,this._editor.on("selectionUpdate",()=>{this.requestUpdate(),this._updateBubbleMenuPosition(),this._editor?.isActive("table")?this._showTableCellToolbar():this._hideTableCellToolbar();const e=this._editor;if(e){const{selection:t}=e.state,{$from:i}=t;if("image"===i.node(i.depth).type.name){const t=e.view.coordsAtPos(i.start()),o=this.shadowRoot?.querySelector(".editor-wrapper")?.getBoundingClientRect();if(o){const e=t.left-o.left+(t.right-t.left)/2,i=t.top-o.top-40;this._showImageToolbar({x:e,y:i})}}else this._hideImageToolbar()}}),this._editor.on("transaction",()=>{this.requestUpdate(),this._editor?.isActive("table")?this._showTableCellToolbar():this._hideTableCellToolbar(),this._checkSlashCommand(),this._setupTableEdgeDetection()}),this._editor.on("update",()=>{this._emitContentChange()})}_emitContentChange(){if(!this._editor)return;const e=this._editor.getHTML();this.dispatchEvent(new CustomEvent("content-change",{detail:e,bubbles:!0,composed:!0}))}_setupTableEdgeDetection(){const e=this.shadowRoot?.querySelector(".editor-content"),t=this.shadowRoot?.querySelector(".editor-wrapper");if(!e||this._tableEdgeDetectionSetup)return;this._tableEdgeDetectionSetup=!0;const i=()=>{this._editor?.chain().focus().run()};e.addEventListener("click",i),t?.addEventListener("click",i)}_checkSlashCommand(){if(!this._editor)return;const{selection:e}=this._editor.state,t=this._editor.state.doc.textBetween(Math.max(0,e.from-10),e.from," ");this._hasSlashCommand=t.endsWith("/")}firstUpdated(){this._injectCustomStyles(),this._initEditor()}updated(e){if(e.has("customStylesAttr")&&this._injectCustomStyles(),this._editor){if(e.has("content")||e.has("modelValue")&&this.useModel){const e=this.useModel?this.modelValue:this.content;e!==this._editor.getHTML()&&this._editor.commands.setContent(e||"<p></p>")}e.has("readonly")&&this._editor.setEditable(!this.readonly)}else e.has("content")&&(this._pendingContent=this.content),e.has("modelValue")&&this.useModel&&(this._pendingContent=this.modelValue)}disconnectedCallback(){super.disconnectedCallback(),this._editor?.destroy(),this._editor=null}getContent(){return this._editor?.getHTML()??""}forceUpdate(){if(this.requestUpdate(),this._editor){const e=this.useModel?this.modelValue:this.content;e!==this._editor.getHTML()&&this._editor.commands.setContent(e||"<p></p>")}}_applyFormat(e){if(this._hasSlashCommand&&this._editor){const{selection:e}=this._editor.state;this._editor.chain().focus().deleteRange({from:e.from-1,to:e.from}).run(),this._hasSlashCommand=!1}e()}_toggleBold(){this._applyFormat(()=>this._editor?.chain().focus().toggleBold().run())}_toggleItalic(){this._applyFormat(()=>this._editor?.chain().focus().toggleItalic().run())}_toggleUnderline(){this._applyFormat(()=>this._editor?.chain().focus().toggleUnderline().run())}_toggleStrike(){this._applyFormat(()=>this._editor?.chain().focus().toggleStrike().run())}_toggleCode(){this._applyFormat(()=>this._editor?.chain().focus().toggleCode().run())}_setHeading(e){this._applyFormat(()=>this._editor?.chain().focus().toggleHeading({level:e}).run())}_setParagraph(){this._applyFormat(()=>this._editor?.chain().focus().setParagraph().run())}_toggleBulletList(){this._applyFormat(()=>this._editor?.chain().focus().toggleBulletList().run())}_toggleOrderedList(){this._applyFormat(()=>this._editor?.chain().focus().toggleOrderedList().run())}_toggleBlockquote(){this._applyFormat(()=>this._editor?.chain().focus().toggleBlockquote().run())}_setTextAlign(e){this._applyFormat(()=>this._editor?.chain().focus().setTextAlign(e).run())}_setLink(){const e=window.prompt("请输入链接地址:");e&&this._applyFormat(()=>this._editor?.chain().focus().setLink({href:e}).run())}_insertTable(e,t){this._editor?.chain().focus().insertTable({rows:e??this._tableRows,cols:t??this._tableCols,withHeaderRow:!0}).run()}async _handleImageUpload(e){const t=e.target,i=t.files?.[0];if(i)try{const e=await this.uploadImage(i);this._editor?.chain().focus().setImage({src:e}).run()}catch(e){}t.value=""}_triggerImageUpload(){const e=this.shadowRoot?.querySelector(".image-input");e?.click()}_insertTableByClick(e,t){if(this._hasSlashCommand&&this._editor){const{selection:e}=this._editor.state;this._editor.chain().focus().deleteRange({from:e.from-1,to:e.from}).run(),this._hasSlashCommand=!1}this._tableRows=e,this._tableCols=t,this._insertTable(e,t)}_showTableCellToolbar(){if(!this._editor?.isActive("table"))return;const{state:e}=this._editor,{selection:t}=e,i=this._editor.view.coordsAtPos(t.from),o=this.shadowRoot?.querySelector(".editor-wrapper");if(!o)return;const r=o.getBoundingClientRect(),l=this._getTableCellRow(),s=this._getTableCellCol();(0===l||0===s)&&(this._tableCellToolbar={x:i.left-r.left,y:i.bottom-r.top+8,visible:!0,cellRow:l,cellCol:s})}_getTableCellRow(){if(!this._editor)return 0;const{selection:e}=this._editor.state,t=this._editor.state.doc.resolve(e.from);for(let e=t.depth;e>0;e--){if("tableCell"===t.node(e).type.name)return t.index(e-1)}return 0}_getTableCellCol(){if(!this._editor)return 0;const{selection:e}=this._editor.state,t=this._editor.state.doc.resolve(e.from);for(let e=t.depth;e>0;e--){if("tableCell"===t.node(e).type.name)return t.index(e)}return 0}_hideTableCellToolbar(){this._tableCellToolbar={...this._tableCellToolbar,visible:!1}}_addTableRowAbove(){this._editor?.chain().focus().addRowBefore().run(),this._hideTableCellToolbar()}_addTableRowBelow(){this._editor?.chain().focus().addRowAfter().run(),this._hideTableCellToolbar()}_addTableColumnLeft(){this._editor?.chain().focus().addColumnBefore().run(),this._hideTableCellToolbar()}_addTableColumnRight(){this._editor?.chain().focus().addColumnAfter().run(),this._hideTableCellToolbar()}_deleteTableRow(){this._editor?.chain().focus().deleteRow().run(),this._hideTableCellToolbar()}_deleteTableColumn(){this._editor?.chain().focus().deleteColumn().run(),this._hideTableCellToolbar()}_deleteTable(){this._editor?.chain().focus().deleteTable().run(),this._hideTableCellToolbar()}_showImageToolbar(e){this._imageToolbar={x:e.x,y:e.y,visible:!0},this._imageMoreMenuVisible=!1}_hideImageToolbar(){this._imageToolbar={...this._imageToolbar,visible:!1},this._imageMoreMenuVisible=!1}_toggleImageMoreMenu(){this._imageMoreMenuVisible=!this._imageMoreMenuVisible}_deleteImage(){this._editor?.chain().focus().deleteNode("image").run(),this._hideImageToolbar()}_insertImageAfter(){this._triggerImageUpload(),this._imageMoreMenuVisible=!1}_setImageAlignLeft(){const e=this._editor;if(e){const{selection:t}=e.state,i=t.from;e.chain().focus().setNodeSelection(i).run();const o=this.shadowRoot?.querySelector(".ProseMirror img.ProseMirror-selectednode");o&&(o.style.display="block",o.style.margin="0 auto 0 0")}this._imageMoreMenuVisible=!1}_setImageAlignCenter(){const e=this._editor;if(e){const{selection:t}=e.state,i=t.from;e.chain().focus().setNodeSelection(i).run();const o=this.shadowRoot?.querySelector(".ProseMirror img.ProseMirror-selectednode");o&&(o.style.display="block",o.style.margin="0 auto")}this._imageMoreMenuVisible=!1}_setImageAlignRight(){const e=this._editor;if(e){const{selection:t}=e.state,i=t.from;e.chain().focus().setNodeSelection(i).run();const o=this.shadowRoot?.querySelector(".ProseMirror img.ProseMirror-selectednode");o&&(o.style.display="block",o.style.margin="0 0 0 auto")}this._imageMoreMenuVisible=!1}_getTextLabel(){const e=this._editor;return e?e.isActive("heading",{level:1})?"标题 1":e.isActive("heading",{level:2})?"标题 2":e.isActive("heading",{level:3})?"标题 3":"正文":"正文"}_getAlignLabel(){const e=this._editor;return e?e.isActive({textAlign:"center"})?"居中":e.isActive({textAlign:"right"})?"右对齐":"左对齐":"对齐"}_updateBubbleMenuPosition(){requestAnimationFrame(()=>{const e=this.shadowRoot?.querySelector(".bubble-menu"),t=this.shadowRoot?.querySelector(".ProseMirror"),i=this.shadowRoot?.querySelector(".editor-wrapper");if(!e||!t||!i)return;const o=this._editor,r=o?.isActive("table")??!1,{selection:l}=o?.state??{selection:null};if(r&&l&&!l.empty&&o){const{from:t,to:i}=l,r=o.state.doc.resolve(t),s=o.state.doc.resolve(i);let n=!1;for(let e=r.depth;e>=0;e--)if("table"===r.node(e).type.name){n=!0;break}const a=r.node(r.depth),d=s.node(s.depth);if("table"!==a.type.name&&"table"!==d.type.name||(n=!0),n)return e.style.opacity="0",void(e.style.visibility="hidden")}if(l&&!l.empty);else if(!l||l.empty&&!this._hasSlashCommand)return e.style.opacity="0",void(e.style.visibility="hidden");const s=i.getBoundingClientRect(),n=e.getBoundingClientRect(),{from:a}=l,d=this._editor?.view.coordsAtPos(a);if(!d)return;let c=d.left-s.left,h=d.top-s.top-40;c+n.width>s.width&&(c=s.width-n.width-8),c<0&&(c=8),h<0&&(h=d.bottom-s.top+8),e.style.left=`${c}px`,e.style.top=`${h}px`,e.style.opacity="1",e.style.visibility="visible"})}render(){const e=this._editor;return C.html`
|
|
2
2
|
<div class="editor-wrapper ${e?"":"loading"} ${this.preview?"preview":""}">
|
|
3
3
|
${e?"":C.html`
|
|
4
4
|
<div class="loading-placeholder">
|
|
@@ -319,12 +319,6 @@
|
|
|
319
319
|
background: transparent;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
.editor-wrapper.is-edit {
|
|
323
|
-
border: 1px solid #dcdfe6;
|
|
324
|
-
border-radius: 3px;
|
|
325
|
-
background: #fff;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
322
|
.editor-wrapper.preview .editor-content {
|
|
329
323
|
padding: 8px 12px;
|
|
330
324
|
min-height: unset;
|
|
@@ -594,49 +588,7 @@
|
|
|
594
588
|
color: #f56c6c;
|
|
595
589
|
}
|
|
596
590
|
|
|
597
|
-
/*
|
|
598
|
-
.table-edge-add {
|
|
599
|
-
position: absolute;
|
|
600
|
-
z-index: 40;
|
|
601
|
-
display: none;
|
|
602
|
-
width: 20px;
|
|
603
|
-
height: 20px;
|
|
604
|
-
align-items: center;
|
|
605
|
-
justify-content: center;
|
|
606
|
-
background: #fff;
|
|
607
|
-
border: 1px solid #e3e3e3;
|
|
608
|
-
border-radius: 4px;
|
|
609
|
-
cursor: pointer;
|
|
610
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
611
|
-
color: #606266;
|
|
612
|
-
transition: all 0.15s;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
.table-edge-add:hover {
|
|
616
|
-
background: #ecf5ff;
|
|
617
|
-
border-color: var(--qxs-color-primary, #3D61E3);
|
|
618
|
-
color: var(--qxs-color-primary, #3D61E3);
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
.table-edge-add.visible {
|
|
622
|
-
display: flex;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
.table-edge-add-row {
|
|
626
|
-
width: 100%;
|
|
627
|
-
height: 8px;
|
|
628
|
-
left: 0;
|
|
629
|
-
border-radius: 0 0 4px 4px;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
.table-edge-add-col {
|
|
633
|
-
height: 100%;
|
|
634
|
-
width: 8px;
|
|
635
|
-
top: 0;
|
|
636
|
-
border-radius: 0 4px 4px 0;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
/* Bubble Menu - 企业级风格 */
|
|
591
|
+
/* Bubble Menu */
|
|
640
592
|
.bubble-menu {
|
|
641
593
|
position: absolute;
|
|
642
594
|
display: flex;
|
|
@@ -661,12 +613,6 @@
|
|
|
661
613
|
transform: translateY(0);
|
|
662
614
|
}
|
|
663
615
|
|
|
664
|
-
.bubble-menu.is-visible {
|
|
665
|
-
opacity: 1;
|
|
666
|
-
visibility: visible;
|
|
667
|
-
transform: translateY(0);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
616
|
.bubble-btn {
|
|
671
617
|
display: flex;
|
|
672
618
|
align-items: center;
|
|
@@ -942,5 +888,5 @@
|
|
|
942
888
|
outline: 2px solid var(--qxs-color-primary, #3D61E3);
|
|
943
889
|
outline-offset: 2px;
|
|
944
890
|
}
|
|
945
|
-
`,
|
|
891
|
+
`,q([M.property({type:String,attribute:"content"})],exports.QxsBlocksuiteEditor.prototype,"content",2),q([M.property({type:String,attribute:"model-value"})],exports.QxsBlocksuiteEditor.prototype,"modelValue",2),q([M.property({type:String,attribute:"use-model"})],exports.QxsBlocksuiteEditor.prototype,"useModelAttr",2),q([M.property({type:String,attribute:"readonly"})],exports.QxsBlocksuiteEditor.prototype,"readonlyAttr",2),q([M.property({type:String,attribute:"preview"})],exports.QxsBlocksuiteEditor.prototype,"previewAttr",2),q([M.property({type:String,attribute:"custom-styles"})],exports.QxsBlocksuiteEditor.prototype,"customStylesAttr",2),q([M.property({type:Object,attribute:"upload-image"})],exports.QxsBlocksuiteEditor.prototype,"uploadImage",2),q([T.state()],exports.QxsBlocksuiteEditor.prototype,"_editor",2),q([T.state()],exports.QxsBlocksuiteEditor.prototype,"_pendingContent",2),q([T.state()],exports.QxsBlocksuiteEditor.prototype,"_hoverRow",2),q([T.state()],exports.QxsBlocksuiteEditor.prototype,"_hoverCol",2),q([T.state()],exports.QxsBlocksuiteEditor.prototype,"_tableDropdownOpen",2),q([T.state()],exports.QxsBlocksuiteEditor.prototype,"_tableCellToolbar",2),q([T.state()],exports.QxsBlocksuiteEditor.prototype,"_imageToolbar",2),q([T.state()],exports.QxsBlocksuiteEditor.prototype,"_imageMoreMenuVisible",2),q([T.state()],exports.QxsBlocksuiteEditor.prototype,"_hasSlashCommand",2),exports.QxsBlocksuiteEditor=q([$.safeCustomElement("qxs-blocksuite-editor")],exports.QxsBlocksuiteEditor),exports.register=function(){};
|
|
946
892
|
//# sourceMappingURL=blocksuite-editor.cjs.map
|