@yorkjs/hive-ui 2.2.7 → 2.2.8
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/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
.block
|
|
17
17
|
position relative
|
|
18
18
|
border-radius 10PX
|
|
19
|
-
halfBorder(top right bottom left, var(--lineBorder),
|
|
19
|
+
halfBorder(top right bottom left, var(--lineBorder), 20PX)
|
|
20
20
|
|
|
21
21
|
.delete-btn
|
|
22
22
|
position absolute
|
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
display block
|
|
39
39
|
|
|
40
40
|
.text-block
|
|
41
|
+
background-color var(--containerCard)
|
|
42
|
+
border-radius 10PX
|
|
41
43
|
padding 15PX 15PX 6PX
|
|
42
44
|
|
|
43
45
|
.textarea-wrap
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
font-size 14PX
|
|
50
52
|
line-height 1.6
|
|
51
53
|
color var(--textTitle)
|
|
54
|
+
overflow hidden
|
|
52
55
|
|
|
53
56
|
&.is-align-left
|
|
54
57
|
:global(.taro-textarea)
|
|
@@ -77,8 +80,13 @@
|
|
|
77
80
|
.image-block
|
|
78
81
|
overflow hidden
|
|
79
82
|
border-radius 10PX
|
|
83
|
+
background-color var(--containerCard)
|
|
84
|
+
user-select none
|
|
80
85
|
|
|
81
86
|
.image
|
|
82
87
|
display block
|
|
83
88
|
width 100%
|
|
84
89
|
height auto
|
|
90
|
+
pointer-events none
|
|
91
|
+
user-select none
|
|
92
|
+
-webkit-user-drag none
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useMemo, useRef } from 'react'
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
|
|
2
2
|
import { View, Textarea, Image, BaseEventOrig, ITouchEvent } from '@tarojs/components'
|
|
3
3
|
|
|
4
4
|
import { useTheme } from '../../config'
|
|
@@ -49,6 +49,18 @@ export interface RichTextEditorProps {
|
|
|
49
49
|
|
|
50
50
|
const ALIGN_OPTIONS: RichTextAlign[] = ['left', 'center', 'right']
|
|
51
51
|
|
|
52
|
+
const getNativeTextarea = (instance: any): HTMLTextAreaElement | null => {
|
|
53
|
+
if (!instance) {
|
|
54
|
+
return null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (instance.tagName === 'TEXTAREA') {
|
|
58
|
+
return instance
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return instance.querySelector?.('textarea') || instance.textareaRef || null
|
|
62
|
+
}
|
|
63
|
+
|
|
52
64
|
const focusTextarea = (instance: any) => {
|
|
53
65
|
if (!instance) {
|
|
54
66
|
return
|
|
@@ -59,7 +71,18 @@ const focusTextarea = (instance: any) => {
|
|
|
59
71
|
return
|
|
60
72
|
}
|
|
61
73
|
|
|
62
|
-
instance
|
|
74
|
+
getNativeTextarea(instance)?.focus?.()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const syncTextareaAutoHeight = (instance: any) => {
|
|
78
|
+
const textarea = getNativeTextarea(instance)
|
|
79
|
+
if (!textarea) {
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
textarea.style.overflow = 'hidden'
|
|
84
|
+
textarea.style.height = 'auto'
|
|
85
|
+
textarea.style.height = `${textarea.scrollHeight}px`
|
|
63
86
|
}
|
|
64
87
|
|
|
65
88
|
const RichTextEditor: React.FC<RichTextEditorProps> = (props) => {
|
|
@@ -72,6 +95,7 @@ const RichTextEditor: React.FC<RichTextEditorProps> = (props) => {
|
|
|
72
95
|
|
|
73
96
|
const { themeSelect } = useTheme()
|
|
74
97
|
const textareaRefs = useRef<Record<number, any>>({})
|
|
98
|
+
const skipHeightSyncRef = useRef(false)
|
|
75
99
|
|
|
76
100
|
const deleteBtnStyle = useMemo(() => ({
|
|
77
101
|
backgroundColor: themeSelect('rgba(0, 0, 0, 0.5)', 'rgba(255, 255, 255, 0.5)'),
|
|
@@ -92,7 +116,17 @@ const RichTextEditor: React.FC<RichTextEditorProps> = (props) => {
|
|
|
92
116
|
index: number,
|
|
93
117
|
e: BaseEventOrig<{ value: string }>
|
|
94
118
|
) => {
|
|
119
|
+
skipHeightSyncRef.current = true
|
|
95
120
|
updateBlock(index, { content: e.detail.value })
|
|
121
|
+
|
|
122
|
+
const eventTarget = (e as any).target
|
|
123
|
+
const textarea = eventTarget?.tagName === 'TEXTAREA'
|
|
124
|
+
? eventTarget
|
|
125
|
+
: textareaRefs.current[index]
|
|
126
|
+
syncTextareaAutoHeight(textarea)
|
|
127
|
+
requestAnimationFrame(() => {
|
|
128
|
+
syncTextareaAutoHeight(textareaRefs.current[index])
|
|
129
|
+
})
|
|
96
130
|
}, [updateBlock])
|
|
97
131
|
|
|
98
132
|
const handleAlignChange = useCallback((index: number, align: RichTextAlign) => {
|
|
@@ -103,6 +137,35 @@ const RichTextEditor: React.FC<RichTextEditorProps> = (props) => {
|
|
|
103
137
|
focusTextarea(textareaRefs.current[index])
|
|
104
138
|
}, [])
|
|
105
139
|
|
|
140
|
+
const handleImageDragStart = useCallback((e: React.DragEvent<HTMLImageElement>) => {
|
|
141
|
+
e.preventDefault()
|
|
142
|
+
e.stopPropagation()
|
|
143
|
+
}, [])
|
|
144
|
+
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
if (skipHeightSyncRef.current) {
|
|
147
|
+
skipHeightSyncRef.current = false
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const syncAll = () => {
|
|
152
|
+
value.forEach((block, index) => {
|
|
153
|
+
if (block.type !== 'text') {
|
|
154
|
+
return
|
|
155
|
+
}
|
|
156
|
+
syncTextareaAutoHeight(textareaRefs.current[index])
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const rafId = requestAnimationFrame(syncAll)
|
|
161
|
+
const timer = setTimeout(syncAll, 0)
|
|
162
|
+
|
|
163
|
+
return () => {
|
|
164
|
+
cancelAnimationFrame(rafId)
|
|
165
|
+
clearTimeout(timer)
|
|
166
|
+
}
|
|
167
|
+
}, [value])
|
|
168
|
+
|
|
106
169
|
return (
|
|
107
170
|
<View className={formatClassNames(styles['rich-text-editor'], className)}>
|
|
108
171
|
{value.map((block, index) => (
|
|
@@ -182,6 +245,10 @@ const RichTextEditor: React.FC<RichTextEditorProps> = (props) => {
|
|
|
182
245
|
className={styles['image']}
|
|
183
246
|
src={block.url}
|
|
184
247
|
mode='widthFix'
|
|
248
|
+
imgProps={{
|
|
249
|
+
draggable: false,
|
|
250
|
+
onDragStart: handleImageDragStart,
|
|
251
|
+
}}
|
|
185
252
|
/>
|
|
186
253
|
</View>
|
|
187
254
|
)
|