Skip to content

Commit

Permalink
fix: dark example
Browse files Browse the repository at this point in the history
  • Loading branch information
17Amir17 committed Feb 15, 2024
1 parent 45a558b commit 7beb4a4
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 25 deletions.
5 changes: 5 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { WithKeyboard } from './Examples/WithKeyboard';
import { CustomCss } from './Examples/CustomCss';
import { ConfigureExtensions } from './Examples/ConfigureExtentions';
import { NavigationHeader } from './Examples/NavigationHeader';
import { DarkEditor } from './Examples/DarkEditor';

const examples = [
{
Expand All @@ -36,6 +37,10 @@ const examples = [
name: 'CustomKeyboard',
component: CustomKeyboardExample,
},
{
name: 'Dark Editor',
component: DarkEditor,
},
{
name: 'EditorStickToKeyboardExample',
component: EditorStickToKeyboardExample,
Expand Down
141 changes: 141 additions & 0 deletions example/src/Examples/DarkEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
import React, { useRef } from 'react';
import {
SafeAreaView,
View,
KeyboardAvoidingView,
Platform,
StyleSheet,
} from 'react-native';
import {
RichText,
Toolbar,
useEditorBridge,
ColorKeyboard,
CustomKeyboard,
DEFAULT_TOOLBAR_ITEMS,
useKeyboard,
type EditorBridge,
useBridgeState,
TenTapStartKit,
CoreBridge,
darkEditorTheme,
} from '@10play/tentap-editor';
import { Images } from '../../../src/assets';

const BACKGROUND_COLOR = '#1C1C1E';
const DEFAULT_TEXT_COLOR = 'white';
const darkEditorCss = `
* {
background-color: ${BACKGROUND_COLOR};
color: ${DEFAULT_TEXT_COLOR};
}
`;

export const DarkEditor = ({}: NativeStackScreenProps<any, any, any>) => {
const editor = useEditorBridge({
autofocus: true,
avoidIosKeyboard: true,
initialContent,
bridgeExtensions: [
...TenTapStartKit,
CoreBridge.configureCSS(darkEditorCss),
],
theme: darkEditorTheme,
});

const rootRef = useRef(null);
const [activeKeyboard, setActiveKeyboard] = React.useState<string>();

return (
<SafeAreaView
style={{ ...exampleStyles.fullScreen, backgroundColor: BACKGROUND_COLOR }}
ref={rootRef}
>
<View
style={{
...exampleStyles.fullScreen,
paddingHorizontal: 12,
backgroundColor: BACKGROUND_COLOR,
}}
>
<RichText
editor={editor}
style={{ backgroundColor: BACKGROUND_COLOR }}
/>
</View>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={exampleStyles.keyboardAvoidingView}
>
<ToolbarWithColor
editor={editor}
activeKeyboard={activeKeyboard}
setActiveKeyboard={setActiveKeyboard}
/>
<CustomKeyboard
rootRef={rootRef}
activeKeyboardID={activeKeyboard}
setActiveKeyboardID={setActiveKeyboard}
keyboards={[ColorKeyboard]}
editor={editor}
/>
</KeyboardAvoidingView>
</SafeAreaView>
);
};

interface ToolbarWithColorProps {
editor: EditorBridge;
activeKeyboard: string | undefined;
setActiveKeyboard: (id: string | undefined) => void;
}
const ToolbarWithColor = ({
editor,
activeKeyboard,
setActiveKeyboard,
}: ToolbarWithColorProps) => {
// Get updates of editor state
const editorState = useBridgeState(editor);

const { isKeyboardUp: isNativeKeyboardUp } = useKeyboard();
const customKeyboardOpen = activeKeyboard !== undefined;
const isKeyboardUp = isNativeKeyboardUp || customKeyboardOpen;

// Here we make sure not to hide the keyboard if our custom keyboard is visible
const hideToolbar =
!isKeyboardUp || (!editorState.isFocused && !customKeyboardOpen);

return (
<Toolbar
editor={editor}
hidden={hideToolbar}
items={[
{
onPress: () => () => {
const isActive = activeKeyboard === ColorKeyboard.id;
if (isActive) editor.focus();
setActiveKeyboard(isActive ? undefined : ColorKeyboard.id);
},
active: () => activeKeyboard === ColorKeyboard.id,
disabled: () => false,
image: () => Images.palette,
},
...DEFAULT_TOOLBAR_ITEMS,
]}
/>
);
};

const exampleStyles = StyleSheet.create({
fullScreen: {
flex: 1,
},
keyboardAvoidingView: {
position: 'absolute',
width: '100%',
bottom: 0,
},
});

const initialContent = `<p>DARK EDITOR</p>`;
3 changes: 1 addition & 2 deletions example/src/Examples/WithKeyboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
useBridgeState,
TenTapStartKit,
CoreBridge,
darkEditorTheme,
} from '@10play/tentap-editor';
import { Images } from '../../../src/assets';
import { customFont } from './font';
Expand All @@ -36,9 +35,9 @@ export const WithKeyboard = ({}: NativeStackScreenProps<any, any, any>) => {
* {
font-family: 'Protest Riot', sans-serif;
}
`),
],
theme: darkEditorTheme,
});

const rootRef = useRef(null);
Expand Down
26 changes: 15 additions & 11 deletions src/RichText/EditorHelper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useState } from 'react';
import type { EditorBridge } from '../types';
import type { Subscription } from '../types/Subscription';

Expand Down Expand Up @@ -28,19 +28,23 @@ class _EditorHelper {
export const EditorHelper = new _EditorHelper();

export const useRemoteEditorBridge = () => {
const [editor, setEditor] = useState<EditorBridge | undefined>(
const [editor, _setEditor] = useState<EditorBridge | undefined>(
EditorHelper.editorLastInstance
);

useEffect(() => {
const unsubscribe = EditorHelper.subscribe((editor) => {
setEditor(editor);
});

return () => {
unsubscribe();
};
}, []);
// TODO -
// There is currently a bug on ios where the keyboard isn't unmounted RCTRootView isn't unmounted
// When removed from subview, because of this we can't rely on it to unsubscribe. Once this is fixed we can
// add this again make it be reactive
// useEffect(() => {
// const unsubscribe = EditorHelper.subscribe((editor) => {
// setEditor(editor);
// });

// return () => {
// unsubscribe();
// };
// }, []);

return editor;
};
10 changes: 5 additions & 5 deletions src/RichText/Keyboard/ColorKeyboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ import { CustomKeyboardExtension } from './CustomKeyboardExtension';
import { Images } from '../../assets';
import type { Color, EditorTheme } from '../../types';

const DEFAULT_COLOR = '#898989';
const DEFAULT_HIGHLIGHT = '#8989894D';

const ColorKeyboardComp = () => {
const editor = useRemoteEditorBridge();
const activeColor = editor?.getEditorState().activeColor;
Expand Down Expand Up @@ -136,7 +133,7 @@ const ColorButton = ({
source={Images.a}
style={[
theme?.colorKeyboard.textIcon,
{ tintColor: color.value || DEFAULT_COLOR },
{ tintColor: color.value || theme?.colorKeyboard.defaultTextColor },
]}
resizeMode="contain"
/>
Expand All @@ -147,7 +144,10 @@ const ColorButton = ({
<View
style={[
theme?.colorKeyboard.highlight,
{ backgroundColor: color.value || DEFAULT_HIGHLIGHT },
{
backgroundColor:
color.value || theme?.colorKeyboard.defaultHighlightColor,
},
]}
/>
</View>
Expand Down
4 changes: 4 additions & 0 deletions src/RichText/Keyboard/keyboardTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const defaultColorKeyboardTheme: ColorKeyboardTheme = {
bottomSpacer: {
height: 30,
},
defaultTextColor: '#898989',
colorSelection: [
{
name: 'Default',
Expand Down Expand Up @@ -107,6 +108,7 @@ export const defaultColorKeyboardTheme: ColorKeyboardTheme = {
value: '#000000',
},
],
defaultHighlightColor: '#8989894D',
highlightSelection: [
{
name: 'Default',
Expand Down Expand Up @@ -168,6 +170,7 @@ export const darkColorKeyboardTheme: Partial<ColorKeyboardTheme> = {
sectionTitle: {
color: '#CACACA',
},
defaultTextColor: 'white',
colorSelection: [
{
name: 'Default',
Expand Down Expand Up @@ -206,6 +209,7 @@ export const darkColorKeyboardTheme: Partial<ColorKeyboardTheme> = {
value: '#000000',
},
],
defaultHighlightColor: '#E5E5E580',
highlightSelection: [
{
name: 'Default',
Expand Down
13 changes: 9 additions & 4 deletions src/RichText/RichText.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { Platform, StyleSheet, TextInput } from 'react-native';
import {
WebView,
Expand Down Expand Up @@ -49,7 +49,8 @@ const getStyleSheetCSS = (css: string[]) => {
`;
};

export const RichText = ({ editor }: RichTextProps) => {
export const RichText = ({ editor, ...props }: RichTextProps) => {
const [loaded, setLoaded] = useState(false);
const { keyboardHeight: iosKeyboardHeight, isKeyboardUp } = useKeyboard();
const source: WebViewProps['source'] = editor.DEV
? { uri: editor.DEV_SERVER_URL || DEV_SERVER_URL }
Expand Down Expand Up @@ -118,13 +119,15 @@ export const RichText = ({ editor }: RichTextProps) => {
)}
<WebView
scrollEnabled={false}
style={RichTextStyles.fullScreen}
style={[
RichTextStyles.fullScreen,
{ display: loaded ? 'flex' : 'none' },
]}
source={source}
injectedJavaScript={getInjectedJS()}
injectedJavaScriptBeforeContentLoaded={`${
editor.bridgeExtensions
? `
window.bridgeExtensionConfigMap = '${JSON.stringify(
editor.bridgeExtensions.reduce((acc, bridge) => {
return {
Expand All @@ -149,6 +152,8 @@ export const RichText = ({ editor }: RichTextProps) => {
ref={editor.webviewRef}
webviewDebuggingEnabled={__DEV__}
keyboardDisplayRequiresUserAction={false}
onLoad={() => setLoaded(true)}
{...props}
/>
</>
);
Expand Down
4 changes: 2 additions & 2 deletions src/RichText/Toolbar/toolbarTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ export const defaultToolbarTheme: ToolbarTheme = {

export const darkToolbarTheme: Partial<ToolbarTheme> = {
toolbarBody: {
borderTopColor: '#C6C6C6',
borderBottomColor: '#C6C6C6',
borderTopColor: '#C6C6C6B3',
borderBottomColor: '#C6C6C6B3',
backgroundColor: '#474747',
},
toolbarButton: {
Expand Down
4 changes: 3 additions & 1 deletion src/RichText/useEditorBridge.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useMemo, useRef } from 'react';
import WebView from 'react-native-webview';
import cloneDeep from 'lodash/cloneDeep';
import merge from 'lodash/merge';
import {
type EditorActionMessage,
Expand Down Expand Up @@ -40,7 +41,8 @@ export const useEditorBridge = (options?: {
}, [options?.bridgeExtensions]);

const mergedTheme = useMemo(
() => merge(defaultEditorTheme, options?.theme),
// We must deep clone defaultEditorTheme, because it is read only
() => merge(cloneDeep(defaultEditorTheme), options?.theme),
[options?.theme]
);
const _updateEditorState = (editorState: BridgeState) => {
Expand Down
2 changes: 2 additions & 0 deletions src/types/Theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,6 @@ export type ColorKeyboardTheme = {
bottomSpacer: StyleProp<ViewStyle>;
colorSelection: Color[];
highlightSelection: Color[];
defaultTextColor: ColorValue;
defaultHighlightColor: ColorValue;
};

0 comments on commit 7beb4a4

Please sign in to comment.