@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,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeleap/web",
3
- "version": "3.21.2",
3
+ "version": "3.21.3",
4
4
  "main": "src/index.ts",
5
5
  "repository": {
6
6
  "url": "https://github.com/codeleap-uk/internal-libs-monorepo.git",
@@ -1,9 +1,9 @@
1
- import { useCallback, useDefaultComponentStyle } from '@codeleap/common'
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 style={{ ...variantStyles.wrapper, ...style }}>
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 TextEditorComposition = 'wrapper' | 'floatingMenu' | 'bubbleMenu' | 'bubbleMenuInnerWrapper' | 'floatingMenuInnerWrapper'
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(() => ({ wrapper: styles })))
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>>