Skip to content

Commit 5c222b6

Browse files
Merge pull request #300 from reown-com/feat/theme
feat: added ability to change themeMode and override accent color
2 parents f4774e1 + 370ca23 commit 5c222b6

File tree

19 files changed

+211
-89
lines changed

19 files changed

+211
-89
lines changed

.changeset/late-cycles-lick.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
'@reown/appkit-scaffold-react-native': minor
3+
'@reown/appkit-ethers5-react-native': minor
4+
'@reown/appkit-common-react-native': minor
5+
'@reown/appkit-ethers-react-native': minor
6+
'@reown/appkit-wallet-react-native': minor
7+
'@reown/appkit-wagmi-react-native': minor
8+
'@reown/appkit-core-react-native': minor
9+
'@reown/appkit-ui-react-native': minor
10+
'@reown/appkit-auth-ethers-react-native': minor
11+
'@reown/appkit-auth-wagmi-react-native': minor
12+
'@reown/appkit-coinbase-ethers-react-native': minor
13+
'@reown/appkit-coinbase-wagmi-react-native': minor
14+
'@reown/appkit-scaffold-utils-react-native': minor
15+
'@reown/appkit-siwe-react-native': minor
16+
---
17+
18+
feat: added ability to change themeMode and override accent color

apps/native/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ createAppKit({
7676
debug: true,
7777
features: {
7878
email: true,
79-
socials: ['x', 'farcaster', 'discord', 'apple'],
79+
socials: ['x', 'discord', 'apple'],
8080
emailShowWallets: true,
8181
swaps: true
8282
}

packages/common/src/utils/TypeUtil.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,9 @@ export interface TransactionQuantity {
8787
}
8888

8989
export type SocialProvider = 'apple' | 'x' | 'discord' | 'farcaster';
90+
91+
export type ThemeMode = 'dark' | 'light';
92+
93+
export interface ThemeVariables {
94+
accent?: string;
95+
}

packages/core/src/__tests__/controllers/ThemeController.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ThemeController } from '../../index';
44
describe('ThemeController', () => {
55
it('should have valid default state', () => {
66
expect(ThemeController.state).toEqual({
7-
themeMode: 'dark',
7+
themeMode: undefined,
88
themeVariables: {}
99
});
1010
});

packages/core/src/controllers/ThemeController.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { proxy, subscribe as sub } from 'valtio';
2-
import type { ThemeMode, ThemeVariables } from '../utils/TypeUtil';
2+
import type { ThemeMode, ThemeVariables } from '@reown/appkit-common-react-native';
33

44
// -- Types --------------------------------------------- //
55
export interface ThemeControllerState {
6-
themeMode: ThemeMode;
6+
themeMode?: ThemeMode;
77
themeVariables: ThemeVariables;
88
}
99

1010
// -- State --------------------------------------------- //
1111
const state = proxy<ThemeControllerState>({
12-
themeMode: 'dark',
12+
themeMode: undefined,
1313
themeVariables: {}
1414
});
1515

packages/core/src/utils/TypeUtil.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { type EventEmitter } from 'events';
2-
import type { Balance, SocialProvider, Transaction } from '@reown/appkit-common-react-native';
2+
import type {
3+
Balance,
4+
SocialProvider,
5+
ThemeMode,
6+
Transaction
7+
} from '@reown/appkit-common-react-native';
38

49
export interface BaseError {
510
message?: string;
@@ -140,14 +145,6 @@ export type RequestCache =
140145
| 'only-if-cached'
141146
| 'reload';
142147

143-
// -- ThemeController Types ---------------------------------------------------
144-
145-
export type ThemeMode = 'dark' | 'light';
146-
147-
export interface ThemeVariables {
148-
accent?: string;
149-
}
150-
151148
// -- BlockchainApiController Types ---------------------------------------------
152149
export interface BlockchainApiIdentityRequest {
153150
address: string;

packages/scaffold/src/client.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import type {
1010
EventsControllerState,
1111
PublicStateControllerState,
1212
ThemeControllerState,
13-
ThemeMode,
14-
ThemeVariables,
1513
Connector,
1614
ConnectedWalletInfo,
1715
Features
@@ -33,7 +31,12 @@ import {
3331
ThemeController,
3432
TransactionsController
3533
} from '@reown/appkit-core-react-native';
36-
import { ConstantsUtil, ErrorUtil } from '@reown/appkit-common-react-native';
34+
import {
35+
ConstantsUtil,
36+
ErrorUtil,
37+
type ThemeMode,
38+
type ThemeVariables
39+
} from '@reown/appkit-common-react-native';
3740

3841
// -- Types ---------------------------------------------------------------------
3942
export interface LibraryOptions {

packages/scaffold/src/modal/w3m-account-button/index.tsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import {
44
CoreHelperUtil,
55
NetworkController,
66
ModalController,
7-
AssetUtil
7+
AssetUtil,
8+
ThemeController
89
} from '@reown/appkit-core-react-native';
910

10-
import { AccountButton as AccountButtonUI } from '@reown/appkit-ui-react-native';
11+
import { AccountButton as AccountButtonUI, ThemeProvider } from '@reown/appkit-ui-react-native';
1112
import { ApiController } from '@reown/appkit-core-react-native';
1213
import type { StyleProp, ViewStyle } from 'react-native';
1314

@@ -27,22 +28,25 @@ export function AccountButton({ balance, disabled, style, testID }: AccountButto
2728
profileName
2829
} = useSnapshot(AccountController.state);
2930
const { caipNetwork } = useSnapshot(NetworkController.state);
31+
const { themeMode, themeVariables } = useSnapshot(ThemeController.state);
3032

3133
const networkImage = AssetUtil.getNetworkImage(caipNetwork);
3234
const showBalance = balance === 'show';
3335

3436
return (
35-
<AccountButtonUI
36-
onPress={() => ModalController.open()}
37-
address={address}
38-
profileName={profileName}
39-
networkSrc={networkImage}
40-
imageHeaders={ApiController._getApiHeaders()}
41-
avatarSrc={profileImage}
42-
disabled={disabled}
43-
style={style}
44-
balance={showBalance ? CoreHelperUtil.formatBalance(balanceVal, balanceSymbol) : ''}
45-
testID={testID}
46-
/>
37+
<ThemeProvider themeMode={themeMode} themeVariables={themeVariables}>
38+
<AccountButtonUI
39+
onPress={() => ModalController.open()}
40+
address={address}
41+
profileName={profileName}
42+
networkSrc={networkImage}
43+
imageHeaders={ApiController._getApiHeaders()}
44+
avatarSrc={profileImage}
45+
disabled={disabled}
46+
style={style}
47+
balance={showBalance ? CoreHelperUtil.formatBalance(balanceVal, balanceSymbol) : ''}
48+
testID={testID}
49+
/>
50+
</ThemeProvider>
4751
);
4852
}

packages/scaffold/src/modal/w3m-connect-button/index.tsx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { useSnapshot } from 'valtio';
2-
import { ModalController } from '@reown/appkit-core-react-native';
2+
import { ModalController, ThemeController } from '@reown/appkit-core-react-native';
33
import {
44
ConnectButton as ConnectButtonUI,
5+
ThemeProvider,
56
type ConnectButtonProps as ConnectButtonUIProps
67
} from '@reown/appkit-ui-react-native';
78

@@ -23,17 +24,20 @@ export function ConnectButton({
2324
testID
2425
}: ConnectButtonProps) {
2526
const { open, loading } = useSnapshot(ModalController.state);
27+
const { themeMode, themeVariables } = useSnapshot(ThemeController.state);
2628

2729
return (
28-
<ConnectButtonUI
29-
onPress={() => ModalController.open()}
30-
size={size}
31-
loading={loading || open}
32-
style={style}
33-
testID={testID}
34-
disabled={disabled}
35-
>
36-
{loading || open ? loadingLabel : label}
37-
</ConnectButtonUI>
30+
<ThemeProvider themeMode={themeMode} themeVariables={themeVariables}>
31+
<ConnectButtonUI
32+
onPress={() => ModalController.open()}
33+
size={size}
34+
loading={loading || open}
35+
style={style}
36+
testID={testID}
37+
disabled={disabled}
38+
>
39+
{loading || open ? loadingLabel : label}
40+
</ConnectButtonUI>
41+
</ThemeProvider>
3842
);
3943
}

packages/scaffold/src/modal/w3m-modal/index.tsx

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useSnapshot } from 'valtio';
22
import { useCallback, useEffect } from 'react';
33
import { useWindowDimensions, StatusBar } from 'react-native';
44
import Modal from 'react-native-modal';
5-
import { Card } from '@reown/appkit-ui-react-native';
5+
import { Card, ThemeProvider } from '@reown/appkit-ui-react-native';
66
import {
77
AccountController,
88
ApiController,
@@ -16,7 +16,8 @@ import {
1616
TransactionsController,
1717
type CaipAddress,
1818
type AppKitFrameProvider,
19-
WebviewController
19+
WebviewController,
20+
ThemeController
2021
} from '@reown/appkit-core-react-native';
2122
import { SIWEController } from '@reown/appkit-siwe-react-native';
2223

@@ -31,6 +32,7 @@ export function AppKit() {
3132
const { connectors, connectedConnector } = useSnapshot(ConnectorController.state);
3233
const { caipAddress, isConnected } = useSnapshot(AccountController.state);
3334
const { frameViewVisible, webviewVisible } = useSnapshot(WebviewController.state);
35+
const { themeMode, themeVariables } = useSnapshot(ThemeController.state);
3436
const { height } = useWindowDimensions();
3537
const { isLandscape } = useCustomDimensions();
3638
const portraitHeight = height - 120;
@@ -117,28 +119,32 @@ export function AppKit() {
117119

118120
return (
119121
<>
120-
<Modal
121-
style={styles.modal}
122-
coverScreen={!frameViewVisible && !webviewVisible}
123-
isVisible={open}
124-
useNativeDriver
125-
useNativeDriverForBackdrop
126-
statusBarTranslucent
127-
hideModalContentWhileAnimating
128-
propagateSwipe
129-
onModalHide={handleClose}
130-
onBackdropPress={ModalController.close}
131-
onBackButtonPress={onBackButtonPress}
132-
testID="w3m-modal"
133-
>
134-
<Card style={[styles.card, { maxHeight: isLandscape ? landScapeHeight : portraitHeight }]}>
135-
<Header />
136-
<AppKitRouter />
137-
<Snackbar />
138-
</Card>
139-
</Modal>
140-
{!!showAuth && AuthView && <AuthView />}
141-
{!!showAuth && SocialView && <SocialView />}
122+
<ThemeProvider themeMode={themeMode} themeVariables={themeVariables}>
123+
<Modal
124+
style={styles.modal}
125+
coverScreen={!frameViewVisible && !webviewVisible}
126+
isVisible={open}
127+
useNativeDriver
128+
useNativeDriverForBackdrop
129+
statusBarTranslucent
130+
hideModalContentWhileAnimating
131+
propagateSwipe
132+
onModalHide={handleClose}
133+
onBackdropPress={ModalController.close}
134+
onBackButtonPress={onBackButtonPress}
135+
testID="w3m-modal"
136+
>
137+
<Card
138+
style={[styles.card, { maxHeight: isLandscape ? landScapeHeight : portraitHeight }]}
139+
>
140+
<Header />
141+
<AppKitRouter />
142+
<Snackbar />
143+
</Card>
144+
</Modal>
145+
{!!showAuth && AuthView && <AuthView />}
146+
{!!showAuth && SocialView && <SocialView />}
147+
</ThemeProvider>
142148
</>
143149
);
144150
}

0 commit comments

Comments
 (0)