@codeleap/web 3.21.2 → 3.21.3
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
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { onUpdate, useCallback, useDefaultComponentStyle, useState, useValidate } from '@codeleap/common'
|
|
2
3
|
import { BubbleMenu, FloatingMenu, EditorContent } from '@tiptap/react'
|
|
3
|
-
import { FileInput, View } from '../components'
|
|
4
|
+
import { FileInput, Text, View } from '../components'
|
|
4
5
|
import { TextEditorProps } from './types'
|
|
5
6
|
import { TextEditorPresets } from './styles'
|
|
6
|
-
|
|
7
7
|
export * from './styles'
|
|
8
8
|
export * from './types'
|
|
9
9
|
|
|
@@ -19,13 +19,43 @@ export const TextEditor = (props: TextEditorProps) => {
|
|
|
19
19
|
floatingMenuProps,
|
|
20
20
|
toolbarComponent,
|
|
21
21
|
fileInputRef,
|
|
22
|
+
_error,
|
|
23
|
+
validate,
|
|
22
24
|
} = props
|
|
25
|
+
|
|
26
|
+
const [_isFocused, setIsFocused] = useState(false)
|
|
27
|
+
const validation = useValidate(editor?.getText() ?? '', validate)
|
|
28
|
+
|
|
29
|
+
const hasError = !validation.isValid || _error
|
|
30
|
+
const errorMessage = validation.message || _error
|
|
31
|
+
const isDisabled = !editor?.isEditable ?? null
|
|
32
|
+
|
|
23
33
|
const variantStyles = useDefaultComponentStyle<'u:TextEditor', typeof TextEditorPresets>('u:TextEditor', {
|
|
24
34
|
variants,
|
|
25
35
|
styles,
|
|
26
36
|
responsiveVariants,
|
|
27
37
|
})
|
|
28
38
|
|
|
39
|
+
const handleBlur = React.useCallback(() => {
|
|
40
|
+
validation?.onInputBlurred()
|
|
41
|
+
setIsFocused(false)
|
|
42
|
+
}, [validation?.onInputBlurred])
|
|
43
|
+
|
|
44
|
+
const handleFocus = React.useCallback(() => {
|
|
45
|
+
validation?.onInputFocused()
|
|
46
|
+
setIsFocused(true)
|
|
47
|
+
}, [validation?.onInputFocused])
|
|
48
|
+
|
|
49
|
+
onUpdate(() => {
|
|
50
|
+
editor?.on('blur', handleBlur)
|
|
51
|
+
editor?.on('focus', handleFocus)
|
|
52
|
+
|
|
53
|
+
return () => {
|
|
54
|
+
editor?.off('blur', handleBlur)
|
|
55
|
+
editor?.off('focus', handleFocus)
|
|
56
|
+
}
|
|
57
|
+
}, [editor, handleBlur, handleFocus])
|
|
58
|
+
|
|
29
59
|
const _BubbleMenu = useCallback(() => {
|
|
30
60
|
return (
|
|
31
61
|
<BubbleMenu css={[variantStyles.bubbleMenu]} {...bubbleMenuProps} editor={editor}>
|
|
@@ -46,14 +76,30 @@ export const TextEditor = (props: TextEditorProps) => {
|
|
|
46
76
|
)
|
|
47
77
|
}, [editor])
|
|
48
78
|
|
|
79
|
+
const editorStyles = [
|
|
80
|
+
variantStyles.editor,
|
|
81
|
+
hasError && variantStyles['editor:error'],
|
|
82
|
+
isDisabled && variantStyles['editor:disabled'],
|
|
83
|
+
]
|
|
84
|
+
|
|
49
85
|
if (!editor) return null
|
|
50
86
|
return (
|
|
51
|
-
<View
|
|
87
|
+
<View
|
|
88
|
+
css={[
|
|
89
|
+
variantStyles.wrapper,
|
|
90
|
+
hasError && variantStyles['wrapper:error'],
|
|
91
|
+
{
|
|
92
|
+
'.tiptap': editorStyles,
|
|
93
|
+
},
|
|
94
|
+
style,
|
|
95
|
+
]}
|
|
96
|
+
>
|
|
52
97
|
{toolbarComponent}
|
|
53
98
|
{children}
|
|
54
|
-
<_BubbleMenu/>
|
|
55
|
-
<_FloatingMenu/>
|
|
56
|
-
<EditorContent editor={editor}/>
|
|
99
|
+
<_BubbleMenu />
|
|
100
|
+
<_FloatingMenu />
|
|
101
|
+
<EditorContent editor={editor} />
|
|
102
|
+
{hasError ? <Text text={errorMessage} css={variantStyles['errorMessage:error']} /> : null}
|
|
57
103
|
<FileInput
|
|
58
104
|
ref={fileInputRef}
|
|
59
105
|
/>
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
|
|
2
2
|
|
|
3
|
-
export type
|
|
3
|
+
export type TextEditorStates = 'error' | 'disabled'
|
|
4
|
+
export type TextEditorParts = 'wrapper' | 'editor' | 'floatingMenu' | 'bubbleMenu' | 'bubbleMenuInnerWrapper' | 'floatingMenuInnerWrapper' | 'errorMessage'
|
|
5
|
+
|
|
6
|
+
export type TextEditorComposition = `${TextEditorParts}:${TextEditorStates}` | TextEditorParts
|
|
4
7
|
|
|
5
8
|
const createTextEditorStyle = createDefaultVariantFactory<TextEditorComposition>()
|
|
6
9
|
|
|
7
|
-
export const TextEditorPresets = includePresets((styles) => createTextEditorStyle(() => ({
|
|
10
|
+
export const TextEditorPresets = includePresets((styles) => createTextEditorStyle(() => ({
|
|
11
|
+
wrapper: styles,
|
|
12
|
+
})))
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RefObject } from 'react'
|
|
2
|
-
import { ComponentVariants, StylesOf } from '@codeleap/common'
|
|
2
|
+
import { ComponentVariants, FormTypes, StylesOf, yup } from '@codeleap/common'
|
|
3
3
|
import { BubbleMenuProps, Editor, FloatingMenuProps } from '@tiptap/react'
|
|
4
4
|
import { FileInputRef } from '../FileInput'
|
|
5
5
|
import { TextEditorComposition, TextEditorPresets } from './styles'
|
|
@@ -8,8 +8,10 @@ export type TextEditorProps = React.PropsWithChildren<{
|
|
|
8
8
|
editor: Editor
|
|
9
9
|
styles?: StylesOf<TextEditorComposition>
|
|
10
10
|
style?: React.CSSProperties
|
|
11
|
-
bubbleMenuProps?: BubbleMenuProps & {renderContent: React.ReactNode}
|
|
12
|
-
floatingMenuProps?: FloatingMenuProps & {renderContent: React.ReactNode}
|
|
11
|
+
bubbleMenuProps?: BubbleMenuProps & { renderContent: React.ReactNode }
|
|
12
|
+
floatingMenuProps?: FloatingMenuProps & { renderContent: React.ReactNode }
|
|
13
13
|
toolbarComponent?: JSX.Element
|
|
14
14
|
fileInputRef?: RefObject<FileInputRef>
|
|
15
|
+
_error?: boolean
|
|
16
|
+
validate?: FormTypes.ValidatorWithoutForm<string> | yup.SchemaOf<string>
|
|
15
17
|
} & ComponentVariants<typeof TextEditorPresets>>
|