1. Background

In iOS 13 and Android 10, dark mode is introduced.

Reference:

https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/dark-mode/

https://developer.android.com/guide/topics/ui/look-and-feel/darktheme


2. Theme value and notificationa. weex.config.env(WXEnvironment)

Now contains key theme indicating the theme value of system.

   - Value dark for dark mode.
   - Value light for light mode.
   - Other values not supported yet.
   - No such key means light mode by default.

When system theme changed, value of weex.config.env["theme"] is changed,
too.
b. Notification when theme changed.

When theme changed, a JS event would be fired to root component of each
Weex page, just like viewappear and viewdisappear.

The event name for theme change is themechanged with theme value as
parameter.


Objective-C code for theme change event would be:

[[WXSDKManager bridgeMgr] fireEvent:instanceId ref:WX_SDK_ROOT_REF
  type:@"themechanged" params:@{@"theme": @"dark"} domChanges:nil];


3. Automatical theme management

A Weex page developer can use theme value from global configuration and
notification to load and reload page with corresponding theme style values.

Also Weex supports automatical theme management so that developer do not
need to reload the page.
a. Using attribute 'invertForDarkTheme'

By default, Weex does nothing to components when theme changed. If any
component has attribute invertForDarkTheme=true the color values of the
following styles would be inverted in dark theme.

backgroundColor

borderColor

color



   - This attribute is inheritable so you could add this attribute with
   true value to root component, so that auto-invert of color properties will
   take effect for all components of a page.
   - Explicitly set invertForDarkTheme=false will prevent self and
   subcomponents from auto-inverting colors. But not affecting parents. So you
   can enable inverting for whole page and disable for a specific component.
   - Remember that invertForDarkTheme is *false* by default but
   *inheritable* from parents.

b. Using prefixed styles

For the following styles(src is an attribute of image component), if
prefixed with theme name in format 'xx-theme-xxxx', the style with theme
name will be used in a specific theme.

backgroundColor

borderColor

color

src


For example, a component declares such styles.

'background-color': black;'dark-theme-background-color': white;

Black color would be used in light theme and white color be used in dark
theme.


An image component declares

'src': "http://cdn.taobao.net/SomeImageUsedInLightTheme.jpg";;'dark-theme-src':
"http://cdn.taobao.net/SomeImageUsedInDarkTheme.jpg";;

When theme changes from light to dark, the image of this image component
will be automatically reloaded.


*Note: Prefixed style has **higher** priority than color inverting. *

c. Animations

For animations such as keyframe animations and transitions, the invert rule
and prefix rule also both apply.


transition

Currently, Weex only supports 'background-color' to be transitional
animated. Consider that currently platform is in dark theme.

   - Setting new value for dark-theme-background-color, the value will be
   used for animation.
   - If component already has dark-theme-background-color explicitly
   defined, updating style with background-color also takes effect and the
   color is used directly without inverting. After the animation, the color
   value will be stored in dark-theme-background-color property, not in
   background-color property.
   - If component is in invert mode. Updating background-color, the value
   will be inverted.

keyframe animation

The same as transition. For example.

   - If inverting is enabled and no dark-theme-background-color explicitly
   defined. The following animation will invert color '#FF0000' and apply to
   the animation.

animation.transition(ref1, {
    styles: {
        backgroundColor: '#FF0000',
        transform: 'translate(250px, 100px)',
    },
    duration: 800, //ms
    timingFunction: 'ease',
    needLayout:false,
    delay: 0 //ms
    }, function () {
        modal.toast({ message: 'animation finished.' })
})


   - If in animation call dark-theme-background-color is explicitly
   defined, it will always be used in dark mode and not inverted.

animation.transition(ref1, {
    styles: {
        darkThemeBackgroundColor: '#0000FF', // Will always be used in
dark mode.
        transform: 'translate(250px, 100px)',
    },
    duration: 800, //ms
    timingFunction: 'ease',
    needLayout:false,
    delay: 0 //ms
    }, function () {
        modal.toast({ message: 'animation finished.' })
})

Reply via email to