diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index dbbac6f..50d6730 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -135,9 +135,9 @@ jobs:
with:
path: |
**/ios/Pods
- key: ${{ runner.os }}-cocoapods-v2-${{ hashFiles('example/ios/Podfile.lock') }}
+ key: ${{ runner.os }}-cocoapods-v3-${{ hashFiles('example/ios/Podfile.lock') }}
restore-keys: |
- ${{ runner.os }}-cocoapods-v2-
+ ${{ runner.os }}-cocoapods-v3-
- name: Install cocoapods
if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true'
diff --git a/example/src/App.tsx b/example/src/App.tsx
index ce261de..99a54f9 100644
--- a/example/src/App.tsx
+++ b/example/src/App.tsx
@@ -9,7 +9,7 @@ import { Basic } from './Examples/Basic';
import { CustomKeyboardExample } from './Examples/CustomKeyboardExample';
import { EditorStickToKeyboardExample } from './Examples/EditorStickToKeyboardExample';
import { Advanced } from './Examples/Advanced/AdvancedRichText';
-import { Compose } from './Examples/Compose';
+import { Compose } from './Examples/Compose/Compose';
const examples = [
{
diff --git a/example/src/Examples/Compose.tsx b/example/src/Examples/Compose/Compose.tsx
similarity index 66%
rename from example/src/Examples/Compose.tsx
rename to example/src/Examples/Compose/Compose.tsx
index f363671..77606d2 100644
--- a/example/src/Examples/Compose.tsx
+++ b/example/src/Examples/Compose/Compose.tsx
@@ -1,14 +1,13 @@
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
-import React, { useRef } from 'react';
+import React from 'react';
import {
SafeAreaView,
View,
- KeyboardAvoidingView,
- Platform,
StyleSheet,
TouchableOpacity,
Text,
TextInput,
+ Alert,
} from 'react-native';
import {
ColorBridge,
@@ -16,17 +15,13 @@ import {
HighlightBridge,
ImageBridge,
LinkBridge,
- RichText,
TaskListBridge,
TenTapStartKit,
- Toolbar,
UnderlineBridge,
useNativeEditor,
- type EditorInstance,
} from 'tentap';
-import { ColorKeyboard } from '../../../src/RichText/Keyboard/ColorKeyboard';
-import { CustomKeyboard } from '../../../src/RichText/Keyboard';
-import { Icon } from './Icon';
+import { Icon } from '../Icon';
+import { ComposeRichText } from './ComposeRichText';
export const Compose = ({
navigation,
@@ -47,6 +42,7 @@ export const Compose = ({
const onSendClick = async () => {
const mailContent = await editor.getContent();
+ Alert.alert('Mail Content', mailContent);
console.log('Send Clicked! Mail content: ', mailContent);
};
@@ -83,64 +79,19 @@ export const Compose = ({
/>
-
+
);
};
-interface ComposeEditorProps {
- editor: EditorInstance;
-}
-const ComposeEditor = ({ editor }: ComposeEditorProps) => {
- const TapRef = useRef(null);
- const [activeKeyboard, setActiveKeyboard] = React.useState();
-
- return (
- <>
-
-
-
-
-
-
-
-
-
- >
- );
-};
-
const exampleStyles = StyleSheet.create({
- header: {
- paddingHorizontal: 14,
- backgroundColor: 'white',
- },
- compose: {
- flex: 1,
- paddingHorizontal: 14,
- },
fullScreen: {
flex: 1,
backgroundColor: 'white',
},
- keyboardAvoidingView: {
- position: 'absolute',
- width: '100%',
- bottom: 0,
+ header: {
+ paddingHorizontal: 14,
+ backgroundColor: 'white',
},
topBar: {
flexDirection: 'row',
diff --git a/example/src/Examples/Compose/ComposeRichText.tsx b/example/src/Examples/Compose/ComposeRichText.tsx
new file mode 100644
index 0000000..e9cea54
--- /dev/null
+++ b/example/src/Examples/Compose/ComposeRichText.tsx
@@ -0,0 +1,193 @@
+import React, { useEffect, useMemo, useRef, useState } from 'react';
+import {
+ View,
+ KeyboardAvoidingView,
+ Platform,
+ StyleSheet,
+ TouchableOpacity,
+} from 'react-native';
+import { RichText, useNativeEditorState } from '../../../../src/RichText';
+import { CustomKeyboard } from '../../../../src/RichText/Keyboard';
+import { ColorKeyboard } from '../../../../src/RichText/Keyboard/ColorKeyboard';
+import type { EditorInstance } from '../../../../src/types';
+import { icons } from '../../assets';
+import { Icon } from '../Icon';
+import { useKeyboard } from '../../../../src/utils';
+
+interface ComposeRichTextProps {
+ editor: EditorInstance;
+ onSendClick: () => void;
+}
+export const ComposeRichText = ({
+ editor,
+ onSendClick,
+}: ComposeRichTextProps) => {
+ const rootRef = useRef(null);
+ const [activeKeyboard, setActiveKeyboard] = React.useState();
+
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ );
+};
+
+interface ComposeToolbarProps {
+ editor: EditorInstance;
+ activeKeyboard: string | undefined;
+ setActiveKeyboard: (keyboard: string) => void;
+ onSendClick: () => void;
+}
+interface CustomToolbarAction {
+ isActive: boolean;
+ isDisabled: boolean;
+ onPress: () => void;
+ icon: keyof typeof icons;
+}
+enum ToolbarType {
+ Main,
+ Link,
+ Formatting,
+}
+const ComposeToolbar = ({ editor, onSendClick }: ComposeToolbarProps) => {
+ const editorState = useNativeEditorState(editor);
+ const { isKeyboardUp } = useKeyboard();
+ const [toolbarType, setToolbar] = useState(ToolbarType.Main);
+
+ const hideToolbar = !isKeyboardUp || !editorState.isFocused;
+
+ useEffect(() => {
+ if (hideToolbar) {
+ setToolbar(ToolbarType.Main);
+ }
+ }, [hideToolbar]);
+
+ const formattingOptions: CustomToolbarAction[] = useMemo(
+ () => [
+ {
+ isActive: true,
+ isDisabled: false,
+ onPress: () => {
+ setToolbar(ToolbarType.Main);
+ },
+ icon: 'formatting',
+ },
+ {
+ isActive: editorState.isBoldActive,
+ isDisabled: !editorState.canToggleBold,
+ onPress: editor.toggleBold,
+ icon: 'bold',
+ },
+ {
+ isActive: editorState.headingLevel === 1,
+ isDisabled: !editorState.canToggleHeading,
+ onPress: () => editor.toggleHeading(1),
+ icon: 'h1',
+ },
+ ],
+ [editor, editorState]
+ );
+
+ if (toolbarType === ToolbarType.Main) {
+ return (
+
+ setToolbar(ToolbarType.Formatting)}>
+
+
+
+
+
+
+ );
+ }
+
+ return (
+
+ {formattingOptions.map(({ isDisabled, isActive, icon, onPress }) => (
+
+
+
+ ))}
+
+ );
+};
+
+const composeStyles = StyleSheet.create({
+ compose: {
+ flex: 1,
+ paddingHorizontal: 14,
+ backgroundColor: 'white',
+ },
+ keyboardAvoidingView: {
+ position: 'absolute',
+ width: '100%',
+ bottom: 0,
+ },
+ mainToolbar: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ paddingHorizontal: 8,
+ paddingVertical: 4,
+ backgroundColor: 'white',
+ borderTopWidth: 1,
+ borderTopColor: 'lightgray',
+ },
+ formattingToolbar: {
+ flexDirection: 'row',
+ justifyContent: 'flex-start',
+ backgroundColor: 'white',
+ borderTopWidth: 1,
+ paddingVertical: 4,
+ paddingHorizontal: 8,
+ gap: 4,
+ borderTopColor: 'lightgray',
+ },
+ button: {
+ width: 24,
+ margin: 4,
+ padding: 5,
+ },
+ activeButton: {
+ backgroundColor: 'lightblue',
+ borderRadius: 10,
+ },
+ hidden: {
+ display: 'none',
+ },
+});
diff --git a/example/src/assets/bold.svg b/example/src/assets/bold.svg
new file mode 100644
index 0000000..0814a2e
--- /dev/null
+++ b/example/src/assets/bold.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/example/src/assets/formatting.svg b/example/src/assets/formatting.svg
new file mode 100644
index 0000000..8c1fde1
--- /dev/null
+++ b/example/src/assets/formatting.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/example/src/assets/h1.svg b/example/src/assets/h1.svg
new file mode 100644
index 0000000..0df41f6
--- /dev/null
+++ b/example/src/assets/h1.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/example/src/assets/index.ts b/example/src/assets/index.ts
index f65ab45..2bff67e 100644
--- a/example/src/assets/index.ts
+++ b/example/src/assets/index.ts
@@ -1,7 +1,13 @@
import close from './close.svg';
import send from './send.svg';
+import formatting from './formatting.svg';
+import bold from './bold.svg';
+import h1 from './h1.svg';
export const icons = {
close,
send,
+ formatting,
+ bold,
+ h1,
};