@fluentui-react-native/use-tokens 0.1.6

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.
Files changed (106) hide show
  1. package/CHANGELOG.json +200 -0
  2. package/CHANGELOG.md +53 -0
  3. package/README.md +85 -0
  4. package/babel.config.js +1 -0
  5. package/just.config.js +3 -0
  6. package/lib/applyPropsToTokens.d.ts +3 -0
  7. package/lib/applyPropsToTokens.d.ts.map +1 -0
  8. package/lib/applyPropsToTokens.js +28 -0
  9. package/lib/applyPropsToTokens.js.map +1 -0
  10. package/lib/applyPropsToTokens.test.d.ts +2 -0
  11. package/lib/applyPropsToTokens.test.d.ts.map +1 -0
  12. package/lib/applyPropsToTokens.test.js +30 -0
  13. package/lib/applyPropsToTokens.test.js.map +1 -0
  14. package/lib/applyTokenLayers.d.ts +16 -0
  15. package/lib/applyTokenLayers.d.ts.map +1 -0
  16. package/lib/applyTokenLayers.js +25 -0
  17. package/lib/applyTokenLayers.js.map +1 -0
  18. package/lib/applyTokenLayers.test.d.ts +2 -0
  19. package/lib/applyTokenLayers.test.d.ts.map +1 -0
  20. package/lib/applyTokenLayers.test.js +64 -0
  21. package/lib/applyTokenLayers.test.js.map +1 -0
  22. package/lib/buildUseTokens.d.ts +35 -0
  23. package/lib/buildUseTokens.d.ts.map +1 -0
  24. package/lib/buildUseTokens.js +62 -0
  25. package/lib/buildUseTokens.js.map +1 -0
  26. package/lib/buildUseTokens.test.d.ts +2 -0
  27. package/lib/buildUseTokens.test.d.ts.map +1 -0
  28. package/lib/buildUseTokens.test.js +103 -0
  29. package/lib/buildUseTokens.test.js.map +1 -0
  30. package/lib/customizable.d.ts +24 -0
  31. package/lib/customizable.d.ts.map +1 -0
  32. package/lib/customizable.js +22 -0
  33. package/lib/customizable.js.map +1 -0
  34. package/lib/index.d.ts +6 -0
  35. package/lib/index.d.ts.map +1 -0
  36. package/lib/index.js +6 -0
  37. package/lib/index.js.map +1 -0
  38. package/lib/patchTokens.d.ts +12 -0
  39. package/lib/patchTokens.d.ts.map +1 -0
  40. package/lib/patchTokens.js +42 -0
  41. package/lib/patchTokens.js.map +1 -0
  42. package/lib/patchTokens.test.d.ts +2 -0
  43. package/lib/patchTokens.test.d.ts.map +1 -0
  44. package/lib/patchTokens.test.js +38 -0
  45. package/lib/patchTokens.test.js.map +1 -0
  46. package/lib/useTokens.samples.test.d.ts +2 -0
  47. package/lib/useTokens.samples.test.d.ts.map +1 -0
  48. package/lib/useTokens.samples.test.js +165 -0
  49. package/lib/useTokens.samples.test.js.map +1 -0
  50. package/lib-commonjs/applyPropsToTokens.d.ts +3 -0
  51. package/lib-commonjs/applyPropsToTokens.d.ts.map +1 -0
  52. package/lib-commonjs/applyPropsToTokens.js +31 -0
  53. package/lib-commonjs/applyPropsToTokens.js.map +1 -0
  54. package/lib-commonjs/applyPropsToTokens.test.d.ts +2 -0
  55. package/lib-commonjs/applyPropsToTokens.test.d.ts.map +1 -0
  56. package/lib-commonjs/applyPropsToTokens.test.js +32 -0
  57. package/lib-commonjs/applyPropsToTokens.test.js.map +1 -0
  58. package/lib-commonjs/applyTokenLayers.d.ts +16 -0
  59. package/lib-commonjs/applyTokenLayers.d.ts.map +1 -0
  60. package/lib-commonjs/applyTokenLayers.js +28 -0
  61. package/lib-commonjs/applyTokenLayers.js.map +1 -0
  62. package/lib-commonjs/applyTokenLayers.test.d.ts +2 -0
  63. package/lib-commonjs/applyTokenLayers.test.d.ts.map +1 -0
  64. package/lib-commonjs/applyTokenLayers.test.js +66 -0
  65. package/lib-commonjs/applyTokenLayers.test.js.map +1 -0
  66. package/lib-commonjs/buildUseTokens.d.ts +35 -0
  67. package/lib-commonjs/buildUseTokens.d.ts.map +1 -0
  68. package/lib-commonjs/buildUseTokens.js +65 -0
  69. package/lib-commonjs/buildUseTokens.js.map +1 -0
  70. package/lib-commonjs/buildUseTokens.test.d.ts +2 -0
  71. package/lib-commonjs/buildUseTokens.test.d.ts.map +1 -0
  72. package/lib-commonjs/buildUseTokens.test.js +105 -0
  73. package/lib-commonjs/buildUseTokens.test.js.map +1 -0
  74. package/lib-commonjs/customizable.d.ts +24 -0
  75. package/lib-commonjs/customizable.d.ts.map +1 -0
  76. package/lib-commonjs/customizable.js +25 -0
  77. package/lib-commonjs/customizable.js.map +1 -0
  78. package/lib-commonjs/index.d.ts +6 -0
  79. package/lib-commonjs/index.d.ts.map +1 -0
  80. package/lib-commonjs/index.js +11 -0
  81. package/lib-commonjs/index.js.map +1 -0
  82. package/lib-commonjs/patchTokens.d.ts +12 -0
  83. package/lib-commonjs/patchTokens.d.ts.map +1 -0
  84. package/lib-commonjs/patchTokens.js +45 -0
  85. package/lib-commonjs/patchTokens.js.map +1 -0
  86. package/lib-commonjs/patchTokens.test.d.ts +2 -0
  87. package/lib-commonjs/patchTokens.test.d.ts.map +1 -0
  88. package/lib-commonjs/patchTokens.test.js +40 -0
  89. package/lib-commonjs/patchTokens.test.js.map +1 -0
  90. package/lib-commonjs/useTokens.samples.test.d.ts +2 -0
  91. package/lib-commonjs/useTokens.samples.test.d.ts.map +1 -0
  92. package/lib-commonjs/useTokens.samples.test.js +177 -0
  93. package/lib-commonjs/useTokens.samples.test.js.map +1 -0
  94. package/package.json +41 -0
  95. package/src/__snapshots__/useTokens.samples.test.tsx.snap +163 -0
  96. package/src/applyPropsToTokens.test.ts +47 -0
  97. package/src/applyPropsToTokens.ts +15 -0
  98. package/src/applyTokenLayers.test.ts +67 -0
  99. package/src/applyTokenLayers.ts +40 -0
  100. package/src/buildUseTokens.test.ts +113 -0
  101. package/src/buildUseTokens.ts +89 -0
  102. package/src/customizable.ts +36 -0
  103. package/src/index.ts +5 -0
  104. package/src/patchTokens.test.ts +50 -0
  105. package/src/patchTokens.ts +30 -0
  106. package/src/useTokens.samples.test.tsx +219 -0
@@ -0,0 +1,89 @@
1
+ import { getMemoCache, GetMemoValue } from '@fluentui-react-native/memo-cache';
2
+ import { immutableMerge } from '@fluentui-react-native/immutable-merge';
3
+
4
+ /** A function to generate tokens based on a theme */
5
+ export type TokensFromTheme<TTokens, TTheme> = (theme: TTheme) => TTokens;
6
+
7
+ /**
8
+ * Types of tokens, can be:
9
+ * - string - will lookup the name in the theme
10
+ * - Tokens - will merge the tokens in directly
11
+ * - Function - will run against the theme once for each unique theme encountered
12
+ */
13
+ export type TokenSettings<TTokens, TTheme> = string | TTokens | TokensFromTheme<TTokens, TTheme>;
14
+
15
+ /**
16
+ * The main signature of a useTokens hook is to take the theme and produce a set of resolved tokens,
17
+ * as well as a sub-cache, specific to this particular theme, that can be used for caching various styles
18
+ * or values that are theme specific
19
+ */
20
+ export type UseTokensCore<TTokens, TTheme> = (theme: TTheme) => [TTokens, GetMemoValue<TTokens>];
21
+
22
+ /**
23
+ * The full signature also includes a customize function that returns an updated version of useTokens
24
+ * that captures both the previous values, and layers in the new values specified
25
+ */
26
+ export type UseTokens<TTokens, TTheme> = UseTokensCore<TTokens, TTheme> & {
27
+ customize: (...tokens: TokenSettings<TTokens, TTheme>[]) => UseTokens<TTokens, TTheme>;
28
+ };
29
+
30
+ /**
31
+ * Helper function that knows how to try to look up token information from the theme
32
+ */
33
+ export type GetComponentInfo<TTokens, TTheme> = (theme: TTheme, name: string) => TTokens | TokensFromTheme<TTokens, TTheme>;
34
+
35
+ /**
36
+ * Tokens are defined as either:
37
+ * TTokens - an object
38
+ * string - a name to look up in the theme
39
+ * function - a function to run against the theme to produce tokens
40
+ *
41
+ * This function maps any of these types into a specific TTokens object. A string is first lookup up in the theme, returning a function
42
+ * or object. If the type is a function this will be invoked with the theme to generate the tokens object.
43
+ *
44
+ * @param tokenEntry - token entry to start with
45
+ * @param theme - theme to use for queries
46
+ * @param getComponentInfo - helper to use to lookup the component in the theme
47
+ */
48
+ function mapToTokens<TTokens, TTheme>(
49
+ tokenEntry: TTokens | string | TokensFromTheme<TTokens, TTheme>,
50
+ theme: TTheme,
51
+ getComponentInfo: GetComponentInfo<TTokens, TTheme> | undefined,
52
+ ): object {
53
+ if (typeof tokenEntry === 'string') {
54
+ tokenEntry = (getComponentInfo && (getComponentInfo(theme, tokenEntry) as TTokens)) || ({} as TTokens);
55
+ }
56
+ if (typeof tokenEntry === 'function') {
57
+ tokenEntry = (tokenEntry as TokensFromTheme<TTokens, TTheme>)(theme);
58
+ }
59
+ return tokenEntry as unknown as object;
60
+ }
61
+
62
+ /**
63
+ * Construct a useStyling hook which returns styled slot props based on props and tokens defined in options and in the theme
64
+ *
65
+ * @param options - options which drive behavior for the generated styling hook
66
+ * @param themeHelper - injected theme functionality
67
+ */
68
+ export function buildUseTokens<TTokens, TTheme>(
69
+ getComponentInfo: GetComponentInfo<TTokens, TTheme> | undefined,
70
+ ...tokens: TokenSettings<TTokens, TTheme>[]
71
+ ): UseTokens<TTokens, TTheme> {
72
+ // create a cache instance for use in this particular call to buildUseTokens
73
+ const cache = getMemoCache();
74
+
75
+ // the core function simply merges layers together, looking up component definitions in the theme as well as executing any
76
+ // theme functions. This turns the tokens into an array of token objects that then get merged together
77
+ const useTokensCore = (theme: TTheme) => {
78
+ // get the base styles all merged together, these will only depend on internal tokens and theme
79
+ return cache(() => immutableMerge(...tokens.map((value) => mapToTokens(value, theme, getComponentInfo))), [theme]);
80
+ };
81
+
82
+ // attach a customize function to generate a new use
83
+ useTokensCore.customize = (...newTokens: TokenSettings<TTokens, TTheme>[]) => {
84
+ const mergedTokens = [...tokens, ...newTokens];
85
+ return buildUseTokens<TTokens, TTheme>(getComponentInfo, ...mergedTokens);
86
+ };
87
+
88
+ return useTokensCore;
89
+ }
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import { TokenSettings, UseTokens } from './buildUseTokens';
3
+
4
+ /**
5
+ * A component implementation, with a use tokens hook passed in. Implementing it this way allows the useTokens hook to be
6
+ * modified by the customization handler
7
+ */
8
+ export type InjectableComponent<TProps, TTokens, TTheme> = (props: TProps, useTokens: UseTokens<TTokens, TTheme>) => JSX.Element | null;
9
+
10
+ /**
11
+ * A component with an attached customize function, used to create alternatively styled versions of the component
12
+ */
13
+ export type CustomizableComponent<TProps, TTokens, TTheme> = React.FunctionComponent<TProps> & {
14
+ customize: (...tokens: TokenSettings<TTokens, TTheme>[]) => CustomizableComponent<TProps, TTokens, TTheme>;
15
+ };
16
+
17
+ /**
18
+ * Function helper for easily creating a customizable component based on the useTokens hook
19
+ *
20
+ * @param injectable - a function component implementation, written in (props, useTokens) => JSX.Element form
21
+ * @param useTokens - a hook function, generally built via buildUseTokens, used to retrieve design tokens for the component
22
+ *
23
+ * @returns - a function component that has a static function called customize attached. Customize will return a
24
+ * new component (which can also be customized)
25
+ */
26
+ export function customizable<TProps, TTokens, TTheme>(
27
+ injectable: InjectableComponent<TProps, TTokens, TTheme>,
28
+ useTokens: UseTokens<TTokens, TTheme>,
29
+ ): CustomizableComponent<TProps, TTokens, TTheme> {
30
+ const component = (props: TProps) => injectable(props, useTokens);
31
+ component.customize = (...tokens: TokenSettings<TTokens, TTheme>[]) => {
32
+ const useTokensNew = useTokens.customize(...tokens);
33
+ return customizable(injectable, useTokensNew);
34
+ };
35
+ return component;
36
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './applyPropsToTokens';
2
+ export * from './applyTokenLayers';
3
+ export * from './buildUseTokens';
4
+ export * from './customizable';
5
+ export * from './patchTokens';
@@ -0,0 +1,50 @@
1
+ import { patchTokens } from './patchTokens';
2
+ import { getMemoCache } from '@fluentui-react-native/memo-cache';
3
+
4
+ interface Tokens {
5
+ uno?: string;
6
+ dos?: string;
7
+ tres?: number;
8
+ quatro?: string | number;
9
+ cinco?: boolean;
10
+ }
11
+
12
+ const themeTokens: Tokens = {
13
+ uno: 'uno',
14
+ dos: 'dos',
15
+ tres: 3,
16
+ quatro: 4,
17
+ cinco: true,
18
+ };
19
+
20
+ describe('patchTokens tests', () => {
21
+ test('props get copied', () => {
22
+ const cache = getMemoCache();
23
+ const patchValues = { uno: 'one', quatro: 'quatro' };
24
+ const [tokens] = patchTokens(themeTokens, cache, patchValues);
25
+ expect(tokens).not.toBe(themeTokens);
26
+ for (const key in patchValues) {
27
+ expect(tokens[key]).toEqual(patchValues[key]);
28
+ }
29
+ });
30
+
31
+ test('no copied props does not change tokens', () => {
32
+ const cache = getMemoCache();
33
+ const patchValues1 = {};
34
+ const [tokens] = patchTokens(themeTokens, cache, patchValues1);
35
+ expect(tokens).toBe(themeTokens);
36
+
37
+ const patchValues2 = { tres: undefined };
38
+ const [tokens2] = patchTokens(themeTokens, cache, patchValues2);
39
+ expect(tokens2).toBe(themeTokens);
40
+ });
41
+
42
+ test('patching tokens cache independent of order', () => {
43
+ const cache = getMemoCache();
44
+ const patch1 = { uno: 'one', cinco: false };
45
+ const patch2 = { cinco: false, uno: 'one' };
46
+ const [tokens1] = patchTokens(themeTokens, cache, patch1);
47
+ const [tokens2] = patchTokens(themeTokens, cache, patch2);
48
+ expect(tokens1).toBe(tokens2);
49
+ });
50
+ });
@@ -0,0 +1,30 @@
1
+ import { GetMemoValue } from '@fluentui-react-native/memo-cache';
2
+
3
+ /**
4
+ * Take a set of tokens (and a memo-cache) and apply changes to those tokens from an additional set of tokens. Only keys which are
5
+ * not undefined will be applied and if no changes are detected the token object will be unchanged.
6
+ *
7
+ * @param tokens - base set of tokens to apply changes to, this will not be modified
8
+ * @param cache - cache corresponding to this set of tokens
9
+ * @param patchValues - new values to apply, values will be obtained via keys in the object
10
+ * @returns - a tuple consisting of a new tokens object and a new memo-cache
11
+ */
12
+ export function patchTokens<TTokens>(
13
+ tokens: TTokens,
14
+ cache: GetMemoValue<TTokens>,
15
+ patchValues: TTokens,
16
+ ): [TTokens, GetMemoValue<TTokens>] {
17
+ // reduce the patch values to the set of keys that are defined, and sort them to ensure consistent ordering
18
+ const keys = Object.keys(patchValues)
19
+ .filter((v) => patchValues[v] !== undefined)
20
+ .sort();
21
+
22
+ // for each key get an updated tokens collection based on key + value. Value alone isn't sufficient as the values
23
+ // are not necessarily unique. i.e. { a: 'blue' } and { b: 'blue' } would cache to the same without the key
24
+ for (const key of keys) {
25
+ [tokens, cache] = cache(() => ({ ...tokens, [key]: patchValues[key] }), [key, patchValues[key]]);
26
+ }
27
+
28
+ // return the updated tokens and cache (if there were any keys applied)
29
+ return [tokens, cache];
30
+ }
@@ -0,0 +1,219 @@
1
+ import { TextProps, Text, View } from 'react-native';
2
+ import toJson from 'enzyme-to-json';
3
+ import * as React from 'react';
4
+ import { mount } from 'enzyme';
5
+ import { buildUseTokens } from './buildUseTokens';
6
+ import { mergeStyles } from '@fluentui-react-native/merge-props';
7
+ import { immutableMerge } from '@fluentui-react-native/immutable-merge';
8
+
9
+ /**
10
+ * Sample super simple theming implementation, shared by all the samples. This is intended to be illustrative,
11
+ * not to be production ready theming code
12
+ */
13
+
14
+ /**
15
+ * The theme just contains global values and options for looking up component overrides
16
+ */
17
+ type Theme = {
18
+ globals: {
19
+ backgroundColor: string;
20
+ color: string;
21
+ borderColor: string;
22
+ fontFamily: string;
23
+ fontSize: number;
24
+ };
25
+ components: {
26
+ [key: string]: any;
27
+ };
28
+ };
29
+
30
+ /**
31
+ * The default/base theme just contains base values
32
+ */
33
+ const baseTheme: Theme = {
34
+ globals: {
35
+ backgroundColor: 'white',
36
+ color: 'black',
37
+ borderColor: 'blue',
38
+ fontFamily: 'Arial',
39
+ fontSize: 12,
40
+ },
41
+ components: {},
42
+ };
43
+
44
+ const current = { theme: baseTheme };
45
+
46
+ const useTheme = () => current.theme;
47
+
48
+ const setActiveTheme = (theme?: Partial<Theme>) => {
49
+ current.theme = (theme && immutableMerge<Theme>(baseTheme, theme as Theme)) || baseTheme;
50
+ };
51
+
52
+ /**
53
+ * this wrapper solves the (so-far) inexplicable type errors from the matchers in typescript
54
+ */
55
+ function snapshotTestTree(tree: any) {
56
+ (expect(toJson(tree)) as any).toMatchSnapshot();
57
+ }
58
+
59
+ /**
60
+ * Helper function used to look up a component in the theme. Having this injected allows this module to not be dependent on the shape of
61
+ * the theme used.
62
+ */
63
+ const getComponentInfo = (theme: Theme, name: string) => theme.components[name];
64
+
65
+ describe('useTokens samples', () => {
66
+ /**
67
+ * Sample #1 - Themeable text element
68
+ *
69
+ * This adds some default opinions for how a text element should be styled but only allows for customization
70
+ * via theming
71
+ */
72
+
73
+ // the tokens for customization are just the color and font props from the theme
74
+ type Sample1Tokens = {
75
+ color?: string;
76
+ fontFamily?: string;
77
+ fontSize?: number;
78
+ };
79
+
80
+ const useTokensSample1 = buildUseTokens<Sample1Tokens, Theme>(
81
+ getComponentInfo,
82
+ /** first the default values should come from the global theme section */
83
+ (t: Theme) => ({
84
+ color: t.globals.color,
85
+ fontFamily: t.globals.fontFamily,
86
+ fontSize: t.globals.fontSize,
87
+ }),
88
+ /** next we should look for a component reference to overlay */
89
+ 'SampleText',
90
+ );
91
+
92
+ const SampleText1: React.FunctionComponent<TextProps> = (props) => {
93
+ // standard props splitting
94
+ const { style, children, ...rest } = props;
95
+
96
+ // typically this would start with a call to retrieve the theme from the context via whatever method is appropriate
97
+ const theme = useTheme();
98
+
99
+ // next the tokens are resolved from the theme, a cache specific to this theme is returned as well to allow for
100
+ // style objects to not be rebuilt unnecessarily
101
+ const [tokens, cache] = useTokensSample1(theme);
102
+
103
+ // build up the text style, or the full props as appropriate
104
+ const styleFromTokens = cache(
105
+ /**
106
+ * first build the style object
107
+ * - this executes once for every unique set of keys.
108
+ * - The cache is already unique for this theme
109
+ */
110
+ () => ({ ...tokens }),
111
+ /**
112
+ * now specify the keys
113
+ * - because the only changing variable is the theme
114
+ * - ...and all the style properties are either constant or come from the tokens
115
+ * - ...no keys need to be specified
116
+ * - this means that only one style object will be created per component + theme pair
117
+ */
118
+ [],
119
+ );
120
+
121
+ // merge the props from the tokens with anything passed in via style. This is internally cached via object identity
122
+ // so the merged style object won't change identity unless one of the two inputs changes identity.
123
+ const mergedStyle = mergeStyles(styleFromTokens, style);
124
+
125
+ // now just render the element, forwarding the props, setting the merged style, then passing the children as appropriate
126
+ return (
127
+ <Text {...rest} style={mergedStyle}>
128
+ {children}
129
+ </Text>
130
+ );
131
+ };
132
+
133
+ beforeEach(() => {
134
+ setActiveTheme();
135
+ });
136
+
137
+ /** first render the component with no updates */
138
+ it('Sample1Text rendering with no overrides', () => {
139
+ const tree = mount(<SampleText1>Sample1a</SampleText1>);
140
+ snapshotTestTree(tree);
141
+ });
142
+
143
+ /** now re-theme the component via the components in the theme */
144
+ it('Sample1Text rendering with some custom settings in the theme', () => {
145
+ setActiveTheme({
146
+ components: {
147
+ SampleText: {
148
+ color: 'pink',
149
+ fontSize: 24,
150
+ },
151
+ },
152
+ });
153
+ const tree = mount(<SampleText1>Sample1b</SampleText1>);
154
+ snapshotTestTree(tree);
155
+ });
156
+
157
+ /**
158
+ * Sample 2 - take the styled text component from the first example and allow color to be set in props as well. This is
159
+ * effectively saying that all other styles come from the theme except that color can be overriden via props.
160
+ */
161
+
162
+ /** use the props from the first sample and just add a color setting */
163
+ type Sample2Props = TextProps & { color?: string };
164
+
165
+ // the Sample2Text component is built the same way as sample1, just using the new hook that has been created
166
+ const SampleText2: React.FunctionComponent<Sample2Props> = (props) => {
167
+ const { color, style, children, ...rest } = props;
168
+ const theme = useTheme();
169
+
170
+ // this starts the same as sample1, extract tokens from the theme and get a theme specific cache object
171
+ const [tokens, cache] = useTokensSample1(theme);
172
+
173
+ // now when building up the style this time, the resulting style object is based upon both the theme and the passed
174
+ // in value of colors. Because the theme is already part of the cache definition, only color needs to be a key
175
+ const styleFromTokens = cache(
176
+ /** build the style, only patch the color if it has a value, otherwise the theme value would get stomped if color was undefined */
177
+ () => ({ ...tokens, ...(color && { color }) }),
178
+ /** use color as an additional key for the style */
179
+ [color],
180
+ );
181
+
182
+ // now just render, this time merging styles inline to make it a bit shorter
183
+ return (
184
+ <Text {...rest} style={mergeStyles(styleFromTokens, style)}>
185
+ {children}
186
+ </Text>
187
+ );
188
+ };
189
+
190
+ /** rendering the Sample2 component with the base theme */
191
+ it('Sample2Text rendering with defaults and a color override', () => {
192
+ const tree = mount(
193
+ <View>
194
+ <SampleText2>Sample2 with defaults</SampleText2>
195
+ <SampleText2 color="green">Sample2 with color override via prop</SampleText2>
196
+ </View>,
197
+ );
198
+ snapshotTestTree(tree);
199
+ });
200
+
201
+ /** now re-theme the component via the components in the theme */
202
+ it('Sample2Text rendering with some custom settings in the theme', () => {
203
+ setActiveTheme({
204
+ components: {
205
+ SampleText: {
206
+ fontSize: 18,
207
+ fontFamily: 'Helvetica',
208
+ },
209
+ },
210
+ });
211
+ const tree = mount(
212
+ <View>
213
+ <SampleText2>Sample2 with theme overrides set</SampleText2>
214
+ <SampleText2 color="purple">Sample2 with theme and color prop override</SampleText2>
215
+ </View>,
216
+ );
217
+ snapshotTestTree(tree);
218
+ });
219
+ });