@jobber/components-native 0.114.7 → 0.114.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +2 -2
- package/dist/src/AtlantisThemeContext/AtlantisThemeContext.js +7 -2
- package/dist/src/AtlantisThemeContext/AtlantisThemeContext.test.js +9 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/AtlantisThemeContext/AtlantisThemeContext.guide.md +11 -0
- package/src/AtlantisThemeContext/AtlantisThemeContext.test.tsx +24 -1
- package/src/AtlantisThemeContext/AtlantisThemeContext.tsx +14 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components-native",
|
|
3
|
-
"version": "0.114.
|
|
3
|
+
"version": "0.114.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React Native implementation of Atlantis",
|
|
6
6
|
"repository": {
|
|
@@ -123,5 +123,5 @@
|
|
|
123
123
|
"react-native-screens": ">=4.18.0",
|
|
124
124
|
"react-native-svg": ">=12.0.0"
|
|
125
125
|
},
|
|
126
|
-
"gitHead": "
|
|
126
|
+
"gitHead": "849254e4ce108a25e35ab25eab411ab07dad69dd"
|
|
127
127
|
}
|
|
@@ -32,6 +32,17 @@ Consumers that need to persist or display the user's choice should use `theme`.
|
|
|
32
32
|
Consumers that need to style non-Atlantis surfaces should usually use
|
|
33
33
|
`effectiveTheme`.
|
|
34
34
|
|
|
35
|
+
## Platform token composition
|
|
36
|
+
|
|
37
|
+
Native themes start with the current platform's iOS or Android token set and
|
|
38
|
+
then apply dark theme overrides. An override must preserve the native token's
|
|
39
|
+
runtime shape. If a dark override is a primitive but the platform token is an
|
|
40
|
+
object, the provider keeps the platform value.
|
|
41
|
+
|
|
42
|
+
This matters for shadows: web dark shadow tokens are CSS strings, while native
|
|
43
|
+
shadow tokens are React Native style objects. Keeping the platform object means
|
|
44
|
+
consumers can safely continue to spread `tokens["shadow-base"]` in both themes.
|
|
45
|
+
|
|
35
46
|
## Controlled vs uncontrolled usage
|
|
36
47
|
|
|
37
48
|
`AtlantisThemeContextProvider` supports both controlled and uncontrolled usage.
|
|
@@ -23,7 +23,12 @@ jest.mock("react-native", () => {
|
|
|
23
23
|
return actual;
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
const expectedDarkTokens =
|
|
26
|
+
const expectedDarkTokens = {
|
|
27
|
+
...merge({}, iosTokens, darkTokens),
|
|
28
|
+
"shadow-low": iosTokens["shadow-low"],
|
|
29
|
+
"shadow-base": iosTokens["shadow-base"],
|
|
30
|
+
"shadow-high": iosTokens["shadow-high"],
|
|
31
|
+
};
|
|
27
32
|
const expectedLightTokens = iosTokens;
|
|
28
33
|
const mockUseColorScheme = useColorScheme as jest.MockedFunction<
|
|
29
34
|
typeof useColorScheme
|
|
@@ -96,6 +101,24 @@ describe("ThemeContext", () => {
|
|
|
96
101
|
expect(result.current.tokens).toEqual(expectedLightTokens);
|
|
97
102
|
});
|
|
98
103
|
|
|
104
|
+
it.each(["shadow-low", "shadow-base", "shadow-high"] as const)(
|
|
105
|
+
"keeps the platform-native %s token in dark mode",
|
|
106
|
+
async shadowToken => {
|
|
107
|
+
const { result } = renderHook(useAtlantisTheme, {
|
|
108
|
+
wrapper: (props: AtlantisThemeContextProviderProps) => (
|
|
109
|
+
<Wrapper {...props} />
|
|
110
|
+
),
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
await act(async () => result.current.setTheme("dark"));
|
|
114
|
+
|
|
115
|
+
expect(result.current.tokens[shadowToken]).toEqual(
|
|
116
|
+
iosTokens[shadowToken],
|
|
117
|
+
);
|
|
118
|
+
expect(typeof result.current.tokens[shadowToken]).toBe("object");
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
|
|
99
122
|
it("resolves the system theme from the OS color scheme", async () => {
|
|
100
123
|
mockUseColorScheme.mockReturnValue("dark");
|
|
101
124
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { androidTokens, darkTokens, iosTokens } from "@jobber/design";
|
|
2
2
|
import React, { createContext, useCallback, useContext, useState } from "react";
|
|
3
|
-
import
|
|
3
|
+
import mergeWith from "lodash/mergeWith";
|
|
4
4
|
import { Platform, useColorScheme } from "react-native";
|
|
5
5
|
import type {
|
|
6
6
|
AtlantisThemeContextProviderProps,
|
|
@@ -15,7 +15,19 @@ const lightTokens = Platform.select({
|
|
|
15
15
|
default: () => androidTokens,
|
|
16
16
|
})();
|
|
17
17
|
|
|
18
|
-
const completeDarkTokens =
|
|
18
|
+
const completeDarkTokens = mergeWith(
|
|
19
|
+
{},
|
|
20
|
+
lightTokens,
|
|
21
|
+
darkTokens,
|
|
22
|
+
(platformValue, darkValue) => {
|
|
23
|
+
const platformValueIsObject =
|
|
24
|
+
typeof platformValue === "object" && platformValue !== null;
|
|
25
|
+
const darkValueIsObject =
|
|
26
|
+
typeof darkValue === "object" && darkValue !== null;
|
|
27
|
+
|
|
28
|
+
if (platformValueIsObject && !darkValueIsObject) return platformValue;
|
|
29
|
+
},
|
|
30
|
+
);
|
|
19
31
|
|
|
20
32
|
const defaultAtlantisThemeContextValue: AtlantisThemeContextValue = {
|
|
21
33
|
theme: "light",
|