Skip to content

Commit

Permalink
Merge pull request #49 from 10play/amir/rnr-39-dark-mode-configurable…
Browse files Browse the repository at this point in the history
…-styles

Amir/rnr 39 dark mode configurable styles
  • Loading branch information
17Amir17 authored Feb 18, 2024
2 parents 27dcc5b + c368a4c commit d01f1e0
Show file tree
Hide file tree
Showing 31 changed files with 887 additions and 305 deletions.
8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,7 @@ PODS:
- RNSVG (14.1.0):
- React-Core
- SocketRocket (0.6.1)
- tentap (0.1.0):
- tentap (0.4.24):
- glog
- RCT-Folly (= 2022.05.16.00)
- React-Core
Expand Down Expand Up @@ -1350,7 +1350,7 @@ SPEC CHECKSUMS:
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
FlipperKit: 37525a5d056ef9b93d1578e04bc3ea1de940094f
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
glog: 035f1e36e53b355cf70f6434d161b36e7d21fecd
hermes-engine: b361c9ef5ef3cda53f66e195599b47e1f84ffa35
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
Expand Down Expand Up @@ -1400,9 +1400,9 @@ SPEC CHECKSUMS:
RNScreens: b582cb834dc4133307562e930e8fa914b8c04ef2
RNSVG: ba3e7232f45e34b7b47e74472386cf4e1a676d0a
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
tentap: 26f5a8b0f5f4e8308e31187880828cbee5be5122
tentap: c7a1f142c8cab3c5e3d8322b41b9b31dcb7171c1
Yoga: e64aa65de36c0832d04e8c7bd614396c77a80047

PODFILE CHECKSUM: 59f02bbde682eb22b765a58d4a0ce59d95964282

COCOAPODS: 1.11.3
COCOAPODS: 1.12.0
12 changes: 2 additions & 10 deletions example/ios/TenTapExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -580,11 +580,7 @@
"-DFOLLY_USE_LIBCPP=1",
"-DFOLLY_CFG_NO_COROUTINES=1",
);
OTHER_LDFLAGS = (
"$(inherited)",
"-Wl",
"-ld_classic",
);
OTHER_LDFLAGS = "$(inherited)";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
Expand Down Expand Up @@ -652,11 +648,7 @@
"-DFOLLY_USE_LIBCPP=1",
"-DFOLLY_CFG_NO_COROUTINES=1",
);
OTHER_LDFLAGS = (
"$(inherited)",
"-Wl",
"-ld_classic",
);
OTHER_LDFLAGS = "$(inherited)";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
Expand Down
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 EDITOR_BACKGROUND_COLOR = '#1C1C1E';
const DEFAULT_TEXT_COLOR = 'white';
const darkEditorCss = `
* {
background-color: ${EDITOR_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: EDITOR_BACKGROUND_COLOR,
}}
ref={rootRef}
>
<View
style={{

Check warning on line 59 in example/src/Examples/DarkEditor.tsx

View workflow job for this annotation

GitHub Actions / lint

Inline style: { paddingHorizontal: 12 }
...exampleStyles.fullScreen,
paddingHorizontal: 12,
backgroundColor: EDITOR_BACKGROUND_COLOR,
}}
>
<RichText editor={editor} />
</View>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={exampleStyles.keyboardAvoidingView}
>
<ToolbarWithColor
editor={editor}
activeKeyboard={activeKeyboard}
setActiveKeyboard={setActiveKeyboard}
/>
<CustomKeyboard
editor={editor}
rootRef={rootRef}
keyboards={[ColorKeyboard]}
activeKeyboardID={activeKeyboard}
setActiveKeyboardID={setActiveKeyboard}
/>
</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>darl</p>`;
1 change: 1 addition & 0 deletions example/src/Examples/WithKeyboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const WithKeyboard = ({}: NativeStackScreenProps<any, any, any>) => {
* {
font-family: 'Protest Riot', sans-serif;
}
`),
],
});
Expand Down
1 change: 1 addition & 0 deletions ios/TenTapViewImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@property (nonatomic, copy) NSNumber *inputTag;
@property (nonatomic, copy) NSString *keyboardID;
@property (nonatomic, copy) NSNumber *keyboardHeight;
@property (nonatomic, copy) UIColor *rootBackground;
@property (nonatomic, weak) RCTBridge *bridge;

@end
4 changes: 3 additions & 1 deletion ios/TenTapViewImpl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ - (void)setInputTag:(NSNumber *)inputTag {

// Create Keyboard
RCTRootView *customKeyboard = [[RCTRootView alloc] initWithBridge:self.bridge moduleName:_keyboardID initialProperties:nil];
if(_rootBackground != nil){
customKeyboard.backgroundColor = _rootBackground;
}

customKeyboard.translatesAutoresizingMaskIntoConstraints = NO;

// Add keyboard to inputView
[inputView addSubview:customKeyboard];

Expand Down
4 changes: 4 additions & 0 deletions ios/TenTapViewManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,9 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(inputTag, NSNumber)
RCT_EXPORT_VIEW_PROPERTY(keyboardID, NSString)
RCT_EXPORT_VIEW_PROPERTY(keyboardHeight, NSNumber)
RCT_CUSTOM_VIEW_PROPERTY(rootBackground, NSString, TenTapViewImpl)
{
view.rootBackground = [RCTConvert UIColor:json];
}

@end
36 changes: 36 additions & 0 deletions src/RichText/EditorHelper.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,50 @@
import { useState } from 'react';
import type { EditorBridge } from '../types';
import type { Subscription } from '../types/Subscription';

class _EditorHelper {
editorLastInstance: EditorBridge | undefined;
cbs: ((editor: EditorBridge | undefined) => void)[] = [];

constructor() {
this.editorLastInstance = undefined;
}

setEditorLastInstance(editorLastInstance: EditorBridge) {
this.editorLastInstance = editorLastInstance;
this.cbs.forEach((cb) => {
cb(editorLastInstance);
});
}

subscribe: Subscription<EditorBridge | undefined> = (cb) => {
this.cbs.push(cb);
return () => {
this.cbs = this.cbs.filter((sub) => sub !== cb);
};
};
}

export const EditorHelper = new _EditorHelper();

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

// 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;
};
Loading

0 comments on commit d01f1e0

Please sign in to comment.