Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions packages/renderless/src/rich-text-edtior/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
export const handleChange = (editor) => {
return (event) => {
const file = event.target.files[0]
if (!file.type.match("image.*")) {
console.log("请选择图片文件!")
return
}
const reader = new FileReader()
reader.onload = function (e) {
editor.value.chain().focus().setImage({ src: e.target?.result }).run()
}
reader.readAsDataURL(file)
}
}
export const setLink = (editor) => {
return () => {
const previousUrl = editor.value.getAttributes('link').href
const url = window.prompt('URL', previousUrl)
if (url === null) {
return
}
if (url === '') {
editor.value
.chain()
.focus()
.extendMarkRange('link')
.unsetLink()
.run()
return
}
editor.value
.chain()
.focus()
.extendMarkRange('link')
.setLink({ href: url })
.run()
}
}
// table 处理逻辑
export const handleMove = (state, box) => {
return (e) => {
let { x, y } = box.value.getBoundingClientRect()
state.flagX = Math.ceil((e.x - x) / 30) // 后期改变30就可以
state.flagY = Math.ceil((e.y - y) / 30)
}
}
export const handleClickOutside = (state, box) => {
return (e) => {
if (!box.value?.contains(e.target)) {
state.isShow = false
removeClickOutside(state, box)()
}
}

}
export const removeClickOutside = (state, box) => {
return () => {
window.removeEventListener('click', handleClickOutside(state, box))
}
}
export const handleClick = (state, box) => {
return (e) => {
e.stopPropagation();
if (state.isShow) {
if (state.flagX && state.flagY) {
state.editor.chain().focus().insertTable({ rows: state.flagX, cols: state.flagY, withHeaderRow: true }).run()
}
state.flagX = 0
state.flagY = 0
removeClickOutside(state, box)()
} else {
window.addEventListener('click', handleClickOutside(state, box))
}
state.isShow = !state.isShow
}
}
// bubble菜单
export const shouldShow = ({ editor, view, state, oldState, from, to }) => {
// 仅在无序列表选中的时候才显示 气泡菜单
return editor.isActive("table");
};
84 changes: 9 additions & 75 deletions packages/renderless/src/rich-text-edtior/vue.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { handleChange, setLink, handleMove, handleClickOutside, removeClickOutside, handleClick, shouldShow } from './index'
export const api = ['state', 'setLink', 'handleChange', 'box', 'handleMove', 'handleClickOutside', 'removeClickOutside', 'handleClick', 'shouldShow']
export const renderless = (
props,
Expand Down Expand Up @@ -47,74 +48,7 @@ export const renderless = (
editable: true,
injectCSS: false,
})
const handleChange = (event) => {
const file = event.target.files[0]
if (!file.type.match("image.*")) {
console.log("请选择图片文件!")
return
}
const reader = new FileReader()
reader.onload = function (e) {
editor.value.chain().focus().setImage({ src: e.target?.result }).run()
}
reader.readAsDataURL(file)
}
const setLink = () => {
const previousUrl = editor.value.getAttributes('link').href
const url = window.prompt('URL', previousUrl)
if (url === null) {
return
}
if (url === '') {
editor.value
.chain()
.focus()
.extendMarkRange('link')
.unsetLink()
.run()
return
}
editor.value
.chain()
.focus()
.extendMarkRange('link')
.setLink({ href: url })
.run()
}
// table 处理逻辑
const handleMove = (e) => {
let { x, y } = box.value.getBoundingClientRect()
state.flagX = Math.ceil((e.x - x) / 30) // 后期改变30就可以
state.flagY = Math.ceil((e.y - y) / 30)
}
const handleClickOutside = (e) => {
if (!box.value?.contains(e.target)) {
state.isShow = false
removeClickOutside()
}
}
const removeClickOutside = () => {
window.removeEventListener('click', handleClickOutside)
}
const handleClick = (e) => {
e.stopPropagation();
if (state.isShow) {
if (state.flagX && state.flagY) {
state.editor.chain().focus().insertTable({ rows: state.flagX, cols: state.flagY, withHeaderRow: true }).run()
}
state.flagX = 0
state.flagY = 0
removeClickOutside()
} else {
window.addEventListener('click', handleClickOutside)
}
state.isShow = !state.isShow
}
// bubble菜单
const shouldShow = ({ editor, view, state, oldState, from, to }) => {
// 仅在无序列表选中的时候才显示 气泡菜单
return editor.isActive("table");
};

const box = ref(null)
const state = reactive({
editor: null,
Expand All @@ -126,16 +60,16 @@ export const renderless = (
state.editor = editor
const api = {
state,
setLink,
handleChange,
setLink: setLink(editor),
handleChange: handleChange(editor),
// table处理函数
box,
handleMove,
handleClickOutside,
removeClickOutside,
handleClick,
handleMove: handleMove(state, box),
handleClickOutside: handleClickOutside(state, box),
removeClickOutside: removeClickOutside(state, box),
handleClick: handleClick(state, box),
// bubble 菜单
shouldShow,
shouldShow: shouldShow,
}
onBeforeUnmount(() => {
state.editor.destroy()
Expand Down
14 changes: 9 additions & 5 deletions packages/theme/src/rich-text-editor/index.less
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
@import './vars.less';

.tiny-rich-text-editor {
.component-css-vars-rich-text-editor();

width: 500px;
height: 350px;
margin: 0 auto;
outline: 3px solid rgb(203, 203, 203);
outline: 3px solid var(--ti-rich-text-editor-box-outline-color);
border-radius: 8px 8px 0 0;

&:hover {
outline: 3px solid black;
outline: 3px solid var(--ti-rich-text-editor-box-outline-hover-color);
}

.button-area {
Expand All @@ -26,18 +30,18 @@
cursor: pointer;

&:hover {
background-color: #d2e4ff;
background-color: var(--ti-rich-text-editor-button-hover);
}
}

button:disabled {
// color: rgba(34, 47, 62, .5);
background-color: rgba(203, 203, 203, .3);
background-color: var(--ti-rich-text-editor-button-disabled);
cursor: not-allowed;
}

button.is-active {
background-color: #d2e4ff;
background-color: var(--ti-rich-text-editor-button-active);
}

.tiny-svg {
Expand Down
10 changes: 9 additions & 1 deletion packages/theme/src/rich-text-editor/vars.less
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
.component-css-vars-roles() {}
.component-css-vars-rich-text-editor() {
--ti-rich-text-editor-box-outline-color: var(--ti-common-color-line-normal);
--ti-rich-text-editor-box-outline-hover-color: var(--ti-common-color-line-hover);
--ti-rich-text-editor-button-hover: var(--ti-base-color-brand-8);
--ti-rich-text-editor-button-disabled: var(--ti-common-color-primary-disabled-bgcolor);
--ti-rich-text-editor-button-active: var(--ti-base-color-brand-8);
--ti-rich-text-editor-poplist-item-selected-bg-color: var(--ti-common-color-selected-background);
--ti-rich-text-editor-poplist-item-selected-text-color: var(--ti-common-color-selected-text-color);
}