Skip to content

Commit

Permalink
New Theming (50) (#901)
Browse files Browse the repository at this point in the history
* Move all current themeing to seperate package

* Initial progress on new themeing system

* Finalize initial theming package structure

* Add tests for validators

* Remove no longer used colors from palette

* Initial proxy of theme object to allow breakpoint and platform selection

* todo comment

* Cleanup theming proxy

* Add tests for theme values proxy

* Move `createThemeValuesProxy` function to seperate file

* Add new theme provider and hooks

* Update theme references across repo to use new theme structure

* Initial theming in example app

* Fix some tests

* Fix theme not working in portal

* Fix incorrect error thrown

* Adjust some components to use theme

* Add a theme example screen

* Use theme hook instead of `withTheme` when forward ref is used

* Fix typoes

Co-authored-by: needs <[email protected]>

* Revert createMuiTheme usage

* Fix screen container background

* Add `useCallback` to changeTheme

* add webview to core

* Correct version of rn webview

* yarn.lock

* Update dropdown modal picker

* Update theming to v50

* trigger rebuild

* Revert "trigger rebuild"

This reverts commit aed4deb.

---------

Co-authored-by: needs <[email protected]>
  • Loading branch information
YoussefHenna and needs authored Jun 30, 2024
1 parent a54f32d commit 0568206
Show file tree
Hide file tree
Showing 129 changed files with 1,749 additions and 974 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ This is a lerna/monorepo setup that is split up into types, native, core and ui
- packages/ui: pulls in everything from core and native and re-exports it. This is what any user will install to use this Library
- packages/core: Non-native, javascript components go here. These are components that work perfectly across web, ios and android without any adjustments
- packages/native: Native components that rely on expo/react-native modules likes `expo-av` and `@expo/vector-icons`. This houses our AudioPlayer and Icon components because the current version requires modifications to work well on Web
- packages/types: Shared typescript types and SEED_DATA types which is how we build the translation layer for Draftbit
- packages/theme: Draftbit's theming system

** Chances are, you'll spend most of your time in `packages/core` **

Expand Down
1 change: 0 additions & 1 deletion deprecated-packages/web-maps/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"extends": "../../tsconfig.json",
"references": [{ "path": "../types" }],
"compilerOptions": {
"outDir": "./lib/"
}
Expand Down
14 changes: 7 additions & 7 deletions example/src/AccordionExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Section, { Container } from "./Section";

function AccordionExample({ theme }) {
return (
<Container style={{ backgroundColor: theme.colors.background }}>
<Container style={{ backgroundColor: theme.colors.background.brand }}>
<Section title="Basic accordion with no additional styles">
<AccordionGroup label={"Basic"}>
<Text>Item 1</Text>
Expand All @@ -14,9 +14,9 @@ function AccordionExample({ theme }) {
</Section>
<Section title="Expandable Accordion group">
<AccordionGroup
openColor={theme.colors.primary}
closedColor={theme.colors.secondary}
caretColor={theme.colors.medium}
openColor={theme.colors.branding.primary}
closedColor={theme.colors.branding.secondary}
caretColor={theme.colors.text.medium}
icon={"folder"}
iconSize={26}
style={{ fontWeight: "bold" }}
Expand All @@ -28,9 +28,9 @@ function AccordionExample({ theme }) {
</Section>
<Section title="Expanded Accordion group">
<AccordionGroup
openColor={theme.colors.primary}
closedColor={theme.colors.secondary}
caretColor={theme.colors.divider}
openColor={theme.colors.branding.primary}
closedColor={theme.colors.branding.secondary}
caretColor={theme.colors.border.brand}
icon={"folder"}
iconSize={26}
style={{ fontWeight: "normal" }}
Expand Down
4 changes: 2 additions & 2 deletions example/src/ActionSheetExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function ActionSheetExample({ theme }) {
}, []);

return (
<Container style={{ backgroundColor: theme.colors.background }}>
<Container style={{ backgroundColor: theme.colors.background.brand }}>
<Section title="Action Sheet">
<ButtonSolid title="Open Action Sheet" onPress={showActionSheet} />
<ActionSheet visible={visible} onClose={hideActionSheet}>
Expand All @@ -30,7 +30,7 @@ function ActionSheetExample({ theme }) {
you to show some long text message like this."
/>
<ActionSheetItem
style={{ color: theme.colors.error }}
style={{ color: theme.colors.text.danger }}
onPress={hideActionSheet}
label="Delete Draft"
/>
Expand Down
138 changes: 132 additions & 6 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ import {
import { createDrawerNavigator } from "@react-navigation/drawer";
import "react-native-gesture-handler";

import { Provider, DefaultTheme, ScreenContainer } from "@draftbit/ui";
import {
Provider,
DefaultTheme,
ScreenContainer,
useTheme,
createTheme,
useChangeTheme,
} from "@draftbit/ui";
import {
SafeAreaProvider,
initialWindowMetrics,
Expand Down Expand Up @@ -65,8 +72,10 @@ import CircularProgressExample from "./CircularProgressExample";
import VideoPlayerExample from "./VideoPlayerExample";
import PinInputExample from "./PinInputExample";
import KeyboardAvoidingViewExample from "./KeyboardAvoidingViewExample";
import ThemeExample from "./ThemeExample";

const ROUTES = {
Theme: ThemeExample,
AudioPlayer: AudioPlayerExample,
Layout: LayoutExample,
Icon: IconExample,
Expand Down Expand Up @@ -123,10 +132,102 @@ type SplashScreenProviderProps = { image: ImageSourcePropType };

SplashScreen.preventAutoHideAsync().catch(() => {});

const themeBreakpoints = {
mobile: 0,
tablet: 480,
laptop: 992,
desktop: 1440,
bigScreen: 1920,
};

const BaseTheme = createTheme({
breakpoints: themeBreakpoints,
palettes: {},
theme: {
name: "BaseTheme",
colors: {
background: {
platformTest: {
default: "purple",
ios: "blue",
android: "green",
},
breakpointTest: {
default: "purple",
tablet: "yellow",
laptop: "red",
},
},
},
typography: {},
},
baseTheme: DefaultTheme,
});

const DarkTheme = createTheme({
breakpoints: themeBreakpoints,
palettes: {},
theme: {
name: "DarkTheme",
colors: {
background: {
brand: "#404040",
},
text: {
normal: "white",
strong: "white",
},
},
typography: {},
},
baseTheme: BaseTheme,
});

const LightTheme = createTheme({
breakpoints: themeBreakpoints,
palettes: {},
theme: {
name: "LightTheme",
colors: {},
typography: {},
},
baseTheme: BaseTheme,
});

const OtherTheme = createTheme({
breakpoints: themeBreakpoints,
palettes: {},
theme: {
name: "OtherTheme",
colors: {
branding: {
primary: "#A91D3A",
secondary: "#824D74",
},
background: {
brand: "black",
},
text: {
strong: "white",
normal: "white",
},
border: {
brand: "#FDAF7B",
},
},
typography: {},
},
baseTheme: BaseTheme,
});

export default function App() {
return (
<SplashScreenProvider image={splashImage}>
<Provider theme={DefaultTheme}>
<Provider
themes={[LightTheme, DarkTheme, OtherTheme]}
breakpoints={themeBreakpoints}
initialThemeName={"LightTheme"}
>
<SafeAreaProvider initialMetrics={initialWindowMetrics}>
<Examples />
</SafeAreaProvider>
Expand Down Expand Up @@ -228,15 +329,23 @@ const AnimatedSplashScreen: React.FC<

function Example({ title, children }: ExampleProps) {
const navigation = useNavigation();
const theme = useTheme();
const changeTheme = useChangeTheme();

return (
<ScreenContainer
hasSafeArea={true}
hasTopSafeArea={true}
hasBottomSafeArea={true}
scrollable={false}
style={{ backgroundColor: theme.colors.background.brand }}
>
<View style={exampleStyles.headerStyle}>
<View
style={[
exampleStyles.headerStyle,
{ backgroundColor: theme.colors.branding.primary },
]}
>
<TouchableOpacity
style={exampleStyles.menuButtonStyle}
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
Expand All @@ -248,6 +357,23 @@ function Example({ title, children }: ExampleProps) {
</TouchableOpacity>

<Text style={[exampleStyles.headerTextStyle]}>{title}</Text>
<TouchableOpacity
style={exampleStyles.menuButtonStyle}
onPress={() => {
if (theme.name === "LightTheme") {
changeTheme("DarkTheme");
} else if (theme.name === "DarkTheme") {
changeTheme("OtherTheme");
} else {
changeTheme("LightTheme");
}
}}
>
<Image
style={exampleStyles.menuButtonImageStyle}
source={require("./assets/images/theme.png")}
/>
</TouchableOpacity>
</View>
<ScreenContainer scrollable={true} hasSafeArea={false}>
{children}
Expand All @@ -257,12 +383,13 @@ function Example({ title, children }: ExampleProps) {
}

function Examples() {
const theme = useTheme();
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="Layout"
initialRouteName="Theme"
screenOptions={{
drawerActiveTintColor: "rgba(90, 69, 255, 1)",
drawerActiveTintColor: theme.colors.branding.primary,
headerShown: false,
}}
>
Expand Down Expand Up @@ -290,7 +417,6 @@ const exampleStyles = StyleSheet.create({
},
headerStyle: {
flexDirection: "row",
backgroundColor: "rgba(90, 69, 255, 1)",
alignItems: "center",
justifyContent: "flex-start",
height: "10%",
Expand Down
22 changes: 13 additions & 9 deletions example/src/CheckboxExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@ import {
import * as React from "react";
import { StyleSheet, Text, View } from "react-native";
import Section from "./Section";
import { useTheme } from "@react-navigation/native";

const SingleCheckboxWrapper = ({ label, children }) => (
<View style={styles.checkboxWrapper}>
<View style={styles.checkboxLabel}>
<Text>{label}</Text>
const SingleCheckboxWrapper = ({ label, children }) => {
const theme = useTheme();
return (
<View style={styles.checkboxWrapper}>
<View style={styles.checkboxLabel}>
<Text style={{ color: theme.colors.text.strong }}>{label}</Text>
</View>
<View>{children}</View>
</View>
<View>{children}</View>
</View>
);
);
};

const CheckboxExample = ({ theme }) => {
const [checked, setChecked] = React.useState(true);
Expand All @@ -43,8 +47,8 @@ const CheckboxExample = ({ theme }) => {
<Checkbox
status={checked}
onPress={handlePress}
color={theme.colors.secondary}
uncheckedColor={theme.colors.error}
color={theme.colors.branding.secondary}
uncheckedColor={theme.colors.text.danger}
/>
</SingleCheckboxWrapper>
<SingleCheckboxWrapper label="Custom icons">
Expand Down
2 changes: 1 addition & 1 deletion example/src/DatePickerExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function DatePickerExample({ theme }) {
const [date3, setDate3] = React.useState(new Date());

return (
<Container style={{ backgroundColor: theme.colors.background }}>
<Container style={{ backgroundColor: theme.colors.background.brand }}>
<Section title="Underline">
<DatePicker
label="Date (without date prop)"
Expand Down
2 changes: 1 addition & 1 deletion example/src/MapViewDataDrivenExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const MapViewDataDrivenExample = ({ theme }) => {
<MapMarker
latitude={item.latitude}
longitude={item.longitude}
pinColor={theme.colors.secondary}
pinColor={theme.colors.branding.secondary}
>
<MapCallout showTooltip>
<Text>With Callout</Text>
Expand Down
8 changes: 4 additions & 4 deletions example/src/MapViewExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ const MapViewExample = ({ theme }) => {
<MapMarker
latitude={40.741895}
longitude={-73.989308}
pinColor={theme.colors.primary}
pinColor={theme.colors.branding.primary}
title="Draftbit"
description="A simple MapView example"
/>
<MapMarker
latitude={40.741895}
longitude={-73.979308}
pinColor={theme.colors.secondary}
pinColor={theme.colors.branding.secondary}
>
<MapCallout showTooltip>
<Text>With Callout</Text>
Expand All @@ -45,14 +45,14 @@ const MapViewExample = ({ theme }) => {
<MapMarker
latitude={43.741895}
longitude={-73.989308}
pinColor={theme.colors.primary}
pinColor={theme.colors.branding.primary}
title="Draftbit"
description="A simple MapView example"
/>
<MapMarker
latitude={43.741895}
longitude={-73.979308}
pinColor={theme.colors.secondary}
pinColor={theme.colors.branding.secondary}
>
<MapCallout showTooltip>
<Text>With Callout</Text>
Expand Down
1 change: 0 additions & 1 deletion example/src/PickerExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ function PickerExample() {
options={OPTIONS}
value={value1}
mode="dropdown"
dropDownTextColor="red"
onValueChange={(value) => setValue(value.toString())}
style={{ marginBottom: 20 }}
/>
Expand Down
Loading

0 comments on commit 0568206

Please sign in to comment.