-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DO NOT MERGE] Preview: Appearance Native Module #26172
Changes from all commits
6246c97
bab28dc
d55bd1b
90635a7
92d34f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,79 @@ | ||||||
/** | ||||||
* Copyright (c) Facebook, Inc. and its affiliates. | ||||||
* | ||||||
* This source code is licensed under the MIT license found in the | ||||||
* LICENSE file in the root directory of this source tree. | ||||||
* | ||||||
* @format | ||||||
* @flow | ||||||
*/ | ||||||
|
||||||
'use strict'; | ||||||
|
||||||
import EventEmitter from '../vendor/emitter/EventEmitter'; | ||||||
import NativeEventEmitter from '../EventEmitter/NativeEventEmitter'; | ||||||
import NativeAppearance, { | ||||||
type AppearancePreferences, | ||||||
type ColorSchemeName, | ||||||
} from './NativeAppearance'; | ||||||
import invariant from 'invariant'; | ||||||
|
||||||
type AppearanceListener = (preferences: AppearancePreferences) => void; | ||||||
const eventEmitter = new EventEmitter(); | ||||||
|
||||||
const nativeColorScheme: ?string = | ||||||
NativeAppearance == null ? null : NativeAppearance.getColorScheme(); | ||||||
invariant( | ||||||
nativeColorScheme === 'dark' || | ||||||
nativeColorScheme === 'light' || | ||||||
nativeColorScheme == null, | ||||||
"Unrecognized color scheme. Did you mean 'dark' or 'light'?", | ||||||
); | ||||||
|
||||||
let currentColorScheme: ?ColorSchemeName = nativeColorScheme; | ||||||
|
||||||
if (NativeAppearance) { | ||||||
const nativeEventEmitter = new NativeEventEmitter(NativeAppearance); | ||||||
nativeEventEmitter.addListener( | ||||||
'appearanceChanged', | ||||||
(newAppearance: AppearancePreferences) => { | ||||||
const {colorScheme} = newAppearance; | ||||||
invariant( | ||||||
colorScheme === 'dark' || | ||||||
colorScheme === 'light' || | ||||||
colorScheme == null, | ||||||
"Unrecognized color scheme. Did you mean 'dark' or 'light'?", | ||||||
); | ||||||
currentColorScheme = colorScheme; | ||||||
eventEmitter.emit('change', {colorScheme}); | ||||||
}, | ||||||
); | ||||||
} | ||||||
|
||||||
module.exports = { | ||||||
/** | ||||||
* Note: Although color scheme is available immediately, it may change at any | ||||||
* time. Any rendering logic or styles that depend on this should try to call | ||||||
* this function on every render, rather than caching the value (for example, | ||||||
* using inline styles rather than setting a value in a `StyleSheet`). | ||||||
* | ||||||
* Example: `const colorScheme = Appearance.getColorScheme();` | ||||||
* | ||||||
* @returns {?ColorSchemeName} Value for the color scheme preference. | ||||||
*/ | ||||||
getColorScheme(): ?ColorSchemeName { | ||||||
return currentColorScheme; | ||||||
}, | ||||||
/** | ||||||
* Add an event handler that is fired when appearance preferences change. | ||||||
*/ | ||||||
addChangeListener(listener: AppearanceListener): void { | ||||||
eventEmitter.addListener('change', listener); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
}, | ||||||
/** | ||||||
* Remove an event handler. | ||||||
*/ | ||||||
removeChangeListener(listener: AppearanceListener): void { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. imo we should remove this function and have people just call |
||||||
eventEmitter.removeListener('change', listener); | ||||||
}, | ||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @flow strict-local | ||
* @format | ||
*/ | ||
|
||
'use strict'; | ||
|
||
import type {TurboModule} from '../TurboModule/RCTExport'; | ||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; | ||
|
||
export type ColorSchemeName = 'light' | 'dark'; | ||
|
||
export type AppearancePreferences = {| | ||
// TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union | ||
// types. | ||
/* 'light' | 'dark' */ | ||
colorScheme?: ?string, | ||
|}; | ||
|
||
export interface Spec extends TurboModule { | ||
// TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union | ||
// types. | ||
/* 'light' | 'dark' */ | ||
+getColorScheme: () => ?string; | ||
|
||
// RCTEventEmitter | ||
+addListener: (eventName: string) => void; | ||
+removeListeners: (count: number) => void; | ||
} | ||
|
||
export default (TurboModuleRegistry.get<Spec>('Appearance'): ?Spec); |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,31 @@ | ||||||
/** | ||||||
* Copyright (c) Facebook, Inc. and its affiliates. | ||||||
* | ||||||
* This source code is licensed under the MIT license found in the | ||||||
* LICENSE file in the root directory of this source tree. | ||||||
* | ||||||
* @format | ||||||
* @flow | ||||||
*/ | ||||||
|
||||||
'use strict'; | ||||||
|
||||||
import {useMemo} from 'react'; | ||||||
import {useSubscription} from 'use-subscription'; | ||||||
import Appearance from './Appearance'; | ||||||
import type {ColorSchemeName} from './NativeAppearance'; | ||||||
|
||||||
export default function useColorScheme(): ?ColorSchemeName { | ||||||
const subscription = useMemo( | ||||||
() => ({ | ||||||
getCurrentValue: () => Appearance.getColorScheme(), | ||||||
subscribe: callback => { | ||||||
Appearance.addChangeListener(callback); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
return () => Appearance.removeChangeListener(callback); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
}, | ||||||
}), | ||||||
[], | ||||||
); | ||||||
|
||||||
return useSubscription(subscription); | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.