@fluentui-react-native/use-styling 0.7.0 → 0.8.1

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 (37) hide show
  1. package/CHANGELOG.json +96 -1
  2. package/CHANGELOG.md +40 -2
  3. package/README.md +19 -17
  4. package/lib/buildProps.d.ts +10 -10
  5. package/lib/buildProps.d.ts.map +1 -1
  6. package/lib/buildProps.js +10 -28
  7. package/lib/buildProps.js.map +1 -1
  8. package/lib/buildProps.test.js +11 -30
  9. package/lib/buildProps.test.js.map +1 -1
  10. package/lib/buildUseStyling.d.ts +1 -1
  11. package/lib/buildUseStyling.d.ts.map +1 -1
  12. package/lib/buildUseStyling.js +5 -23
  13. package/lib/buildUseStyling.js.map +1 -1
  14. package/lib/buildUseStyling.test.js +1 -11
  15. package/lib/buildUseStyling.test.js.map +1 -1
  16. package/lib/useStyling.samples.test.js +2 -19
  17. package/lib/useStyling.samples.test.js.map +1 -1
  18. package/lib-commonjs/buildProps.d.ts +10 -10
  19. package/lib-commonjs/buildProps.d.ts.map +1 -1
  20. package/lib-commonjs/buildProps.js +11 -28
  21. package/lib-commonjs/buildProps.js.map +1 -1
  22. package/lib-commonjs/buildProps.test.js +15 -34
  23. package/lib-commonjs/buildProps.test.js.map +1 -1
  24. package/lib-commonjs/buildUseStyling.d.ts +1 -1
  25. package/lib-commonjs/buildUseStyling.d.ts.map +1 -1
  26. package/lib-commonjs/buildUseStyling.js +10 -27
  27. package/lib-commonjs/buildUseStyling.js.map +1 -1
  28. package/lib-commonjs/buildUseStyling.test.js +5 -15
  29. package/lib-commonjs/buildUseStyling.test.js.map +1 -1
  30. package/lib-commonjs/index.js +5 -6
  31. package/lib-commonjs/index.js.map +1 -1
  32. package/lib-commonjs/useStyling.samples.test.js +18 -45
  33. package/lib-commonjs/useStyling.samples.test.js.map +1 -1
  34. package/package.json +7 -6
  35. package/src/buildProps.test.ts +10 -22
  36. package/src/buildProps.ts +32 -57
  37. package/src/buildUseStyling.ts +7 -9
@@ -3,18 +3,16 @@ import { buildProps } from './buildProps';
3
3
 
4
4
  type ITheme = { foo?: string; bar?: string };
5
5
  type ITokens = { a?: string; b?: string; c?: string; d?: string };
6
- type IOuterProps = { banana?: string; potato?: string };
7
- type IProps = ITokens & ITheme & IOuterProps & { instance: number };
6
+ type IProps = ITokens & ITheme & { instance: number };
8
7
 
9
8
  const theme: ITheme = { foo: 'foo', bar: 'bar' };
10
9
 
11
10
  let instanceCount = 0;
12
11
 
13
- function munge(tokens: ITokens, theme: ITheme, props: IOuterProps): IProps {
12
+ function munge(tokens: ITokens, theme: ITheme): IProps {
14
13
  return {
15
14
  ...theme,
16
15
  ...tokens,
17
- ...props,
18
16
  instance: instanceCount++,
19
17
  };
20
18
  }
@@ -23,11 +21,11 @@ describe('props function tests', () => {
23
21
  test('basic build props function caches as expected', () => {
24
22
  const cache = getMemoCache();
25
23
  const styleFn = buildProps(munge, ['a', 'b']);
26
- const p1 = styleFn({ a: 'a', b: 'b', c: 'c' }, theme, undefined, cache);
27
- expect(styleFn({ a: 'a', b: 'b', c: 'foo' }, theme, undefined, cache)).toBe(p1);
28
- const p2 = styleFn({ a: 'b', b: 'b' }, theme, undefined, cache);
24
+ const p1 = styleFn({ a: 'a', b: 'b', c: 'c' }, theme, cache);
25
+ expect(styleFn({ a: 'a', b: 'b', c: 'foo' }, theme, cache)).toBe(p1);
26
+ const p2 = styleFn({ a: 'b', b: 'b' }, theme, cache);
29
27
  expect(p2).not.toBe(p1);
30
- expect(styleFn({ a: 'b', b: 'b', c: 'bar' }, theme, undefined, cache)).toBe(p2);
28
+ expect(styleFn({ a: 'b', b: 'b', c: 'bar' }, theme, cache)).toBe(p2);
31
29
  });
32
30
 
33
31
  test('build props function refinement works with explicit keys', () => {
@@ -37,22 +35,12 @@ describe('props function tests', () => {
37
35
  const t1 = { a: 'a', b: 'b', c: 'c', d: 'd' };
38
36
  const t2 = { a: 'a', b: 'b', c: 'foo', d: 'bar' };
39
37
 
40
- const p1 = styleFn(t1, theme, undefined, cache);
41
- const p2 = styleFn(t2, theme, undefined, cache);
38
+ const p1 = styleFn(t1, theme, cache);
39
+ const p2 = styleFn(t2, theme, cache);
42
40
  expect(p2).not.toBe(p1);
43
41
 
44
- const rp1 = refinedFn(t1, theme, undefined, cache);
45
- const rp2 = refinedFn(t2, theme, undefined, cache);
42
+ const rp1 = refinedFn(t1, theme, cache);
43
+ const rp2 = refinedFn(t2, theme, cache);
46
44
  expect(rp2).toBe(rp1);
47
45
  });
48
-
49
- test('build props with outer props function caches as expected', () => {
50
- const cache = getMemoCache();
51
- const styleFn = buildProps(munge, ['a', 'b', 'banana']);
52
- const p1 = styleFn({ a: 'a', b: 'b', c: 'c' }, theme, { banana: 'banana' }, cache);
53
- expect(styleFn({ a: 'a', b: 'b', c: 'foo' }, theme, { banana: 'banana', potato: 'potato' }, cache)).toBe(p1);
54
- const p2 = styleFn({ a: 'b', b: 'b' }, theme, { banana: 'potato' }, cache);
55
- expect(p2).not.toBe(p1);
56
- expect(styleFn({ a: 'b', b: 'b', c: 'bar' }, theme, { banana: 'potato', potato: 'potato' }, cache)).toBe(p2);
57
- });
58
46
  });
package/src/buildProps.ts CHANGED
@@ -18,83 +18,59 @@ export type TokensThatAreAlsoProps<TTokens> = (keyof TTokens)[] | 'all' | 'none'
18
18
  * The provided
19
19
  * cache will be scoped to the theme, slot, and tokens that are coming out of the theme.
20
20
  */
21
- export type BuildPropsBase<TProps, TTokens, TTheme, TOuterProps> = (
22
- tokens: TTokens,
23
- theme: TTheme,
24
- props: TOuterProps,
25
- cache: GetMemoValue<any>,
26
- ) => Partial<TProps>;
21
+ export type BuildPropsBase<TProps, TTokens, TTheme> = (tokens: TTokens, theme: TTheme, cache: GetMemoValue<any>) => Partial<TProps>;
27
22
 
28
23
  /**
29
24
  * A refine function allows style functions to be updated based on tokens that are also props. Only those tokens that are also
30
25
  * props need to be considered as a key for caching
31
26
  */
32
- export type RefineFunctionBase<TProps, TTokens, TTheme, TOuterProps> = (
27
+ export type RefineFunctionBase<TProps, TTokens, TTheme> = (
33
28
  mask?: TokensThatAreAlsoProps<TTokens>,
34
- ) => BuildPropsBase<TProps, TTokens, TTheme, TOuterProps>;
29
+ ) => BuildPropsBase<TProps, TTokens, TTheme>;
35
30
 
36
31
  /**
37
32
  * Signature for a style function which can be optionally refined by the styling hook if prop masks are provided
38
33
  */
39
- export type RefinableBuildPropsBase<TProps, TTokens, TTheme, TOuterProps> = BuildPropsBase<TProps, TTokens, TTheme, TOuterProps> & {
40
- refine?: RefineFunctionBase<TProps, TTokens, TTheme, TOuterProps>;
34
+ export type RefinableBuildPropsBase<TProps, TTokens, TTheme> = BuildPropsBase<TProps, TTokens, TTheme> & {
35
+ refine?: RefineFunctionBase<TProps, TTokens, TTheme>;
41
36
  };
42
37
 
43
38
  /**
44
39
  * Style functions can be plain functions, refinable functions, or just raw props
45
40
  */
46
- export type BuildSlotProps<TSlotProps, TTokens, TTheme, TOuterProps> = {
47
- [K in keyof TSlotProps]?: RefinableBuildPropsBase<TSlotProps[K], TTokens, TTheme, TOuterProps> | TSlotProps[K]
41
+ export type BuildSlotProps<TSlotProps, TTokens, TTheme> = {
42
+ [K in keyof TSlotProps]?: RefinableBuildPropsBase<TSlotProps[K], TTokens, TTheme> | TSlotProps[K];
48
43
  };
49
44
 
50
- /**
51
- * Caches and returns the function based on the current keys.
52
- *
53
- * @param fn Function which does the work of producing props for the tokens, theme, and props provided
54
- * @param keys Set of input values the function is dependent on
55
- * @returns Cached function
56
- */
57
- function cacheStyleClosure<TProps, TTokens, TTheme, TOuterProps>(
58
- fn: (tokens: TTokens, theme: TTheme, props: TOuterProps) => TProps,
59
- keys?: (keyof TTokens | keyof TOuterProps)[],
60
- ): RefinableBuildPropsBase<TProps, TTokens, TTheme, TOuterProps> {
61
- return (tokens: TTokens, theme: TTheme, props: TOuterProps, cache: GetMemoValue<TProps>) =>
45
+ function cacheStyleClosure<TProps, TTokens, TTheme>(
46
+ fn: (tokens: TTokens, theme: TTheme) => TProps,
47
+ keys?: (keyof TTokens)[],
48
+ ): RefinableBuildPropsBase<TProps, TTokens, TTheme> {
49
+ return (tokens: TTokens, theme: TTheme, cache: GetMemoValue<TProps>) =>
62
50
  cache(
63
- () => fn(tokens, theme, props),
64
- (keys || []).map(key => {
65
- if (Object.keys(tokens).includes(key as string)) {
66
- return tokens[key as keyof TTokens];
67
- } else {
68
- return props[key as keyof TOuterProps];
69
- }
70
- }),
51
+ () => fn(tokens, theme),
52
+ (keys || []).map((key) => tokens[key]),
71
53
  )[0];
72
54
  }
73
55
 
74
- /**
75
- * Reduce keys to the set that are also part of the mask.
76
- *
77
- * @param keys - which token and prop properties are used by this style, this determines the keys to use for caching
78
- * @param mask - the set of tokens that are also props
79
- * @returns An array of keys that are part of the mask to be used as a caching key
80
- */
81
- function refineKeys<TTokens, TOuterProps = unknown>(
82
- keys: (keyof TTokens | keyof TOuterProps)[],
83
- mask?: TokensThatAreAlsoProps<TTokens>,
84
- ): (keyof TTokens | keyof TOuterProps)[] {
85
- return typeof mask === 'object' && Array.isArray(mask) ? keys.filter(key => mask.findIndex(val => val === key) !== -1) : mask ? keys : [];
56
+ function refineKeys<TTokens>(keys: (keyof TTokens)[], mask?: TokensThatAreAlsoProps<TTokens>): (keyof TTokens)[] {
57
+ return typeof mask === 'object' && Array.isArray(mask)
58
+ ? keys.filter((key) => mask.findIndex((val) => val === key) !== -1)
59
+ : mask
60
+ ? keys
61
+ : [];
86
62
  }
87
63
 
88
64
  /**
89
65
  * Standard wrapper for a function that provides props for a component based on tokens and theme.
90
66
  *
91
- * @param fn - function which does the work of producing props for the tokens, theme, and props provided
92
- * @param keys - which token and prop properties are used by this style, this determines the keys to use for caching
67
+ * @param fn - function which does the work of producing props for the tokens and theme provided
68
+ * @param keys - which token properties are used by this style, this determines the keys to use for caching
93
69
  */
94
- export function buildProps<TProps, TTokens, TTheme, TOuterProps = unknown>(
95
- fn: (tokens: TTokens, theme: TTheme, props?: TOuterProps) => TProps,
96
- keys?: (keyof TTokens | keyof TOuterProps)[],
97
- ): RefinableBuildPropsBase<TProps, TTokens, TTheme, TOuterProps> {
70
+ export function buildProps<TProps, TTokens, TTheme>(
71
+ fn: (tokens: TTokens, theme: TTheme) => TProps,
72
+ keys?: (keyof TTokens)[],
73
+ ): RefinableBuildPropsBase<TProps, TTokens, TTheme> {
98
74
  // wrap the provided function in the standard caching layer, basing it upon the provided keys
99
75
  const result = cacheStyleClosure(fn, keys);
100
76
 
@@ -102,7 +78,7 @@ export function buildProps<TProps, TTokens, TTheme, TOuterProps = unknown>(
102
78
  result.refine =
103
79
  keys && keys.length > 0
104
80
  ? (mask?: TokensThatAreAlsoProps<TTokens>) => {
105
- return cacheStyleClosure(fn, refineKeys<TTokens, TOuterProps>(keys, mask));
81
+ return cacheStyleClosure(fn, refineKeys(keys, mask));
106
82
  }
107
83
  : undefined;
108
84
 
@@ -116,15 +92,14 @@ export function buildProps<TProps, TTokens, TTheme, TOuterProps = unknown>(
116
92
  * @param fn - function or props to potentially refine
117
93
  * @param mask - prop mask to use for refinement
118
94
  */
119
- export function refinePropsFunctions<TSlotProps, TTokens, TTheme, TOuterProps>(
120
- styles: BuildSlotProps<TSlotProps, TTokens, TTheme, TOuterProps>,
95
+ export function refinePropsFunctions<TSlotProps, TTokens, TTheme>(
96
+ styles: BuildSlotProps<TSlotProps, TTokens, TTheme>,
121
97
  mask: TokensThatAreAlsoProps<TTokens>,
122
- ): BuildSlotProps<TSlotProps, TTokens, TTheme, TOuterProps> {
98
+ ): BuildSlotProps<TSlotProps, TTokens, TTheme> {
123
99
  const result = {};
124
- Object.keys(styles).forEach(key => {
100
+ Object.keys(styles).forEach((key) => {
125
101
  const refine =
126
- typeof styles[key] === 'function' &&
127
- (styles[key] as RefinableBuildPropsBase<TSlotProps[keyof TSlotProps], TTokens, TTheme, TOuterProps>).refine;
102
+ typeof styles[key] === 'function' && (styles[key] as RefinableBuildPropsBase<TSlotProps[keyof TSlotProps], TTokens, TTheme>).refine;
128
103
  result[key] = refine ? refine(mask) : styles[key];
129
104
  });
130
105
  return result;
@@ -20,7 +20,7 @@ export type UseStylingOptions<TProps, TSlotProps, TTokens, TTheme> = {
20
20
  /**
21
21
  * Functions which build up the props for each slot
22
22
  */
23
- slotProps?: BuildSlotProps<TSlotProps, TTokens, TTheme, TProps>;
23
+ slotProps?: BuildSlotProps<TSlotProps, TTokens, TTheme>;
24
24
 
25
25
  /**
26
26
  * Which props should be considered to be tokens.
@@ -55,20 +55,18 @@ export type ThemeHelper<TTheme> = {
55
55
  * @param styles - refined style functions or props to use for processing
56
56
  * @param tokens - token inputs for the style functions
57
57
  * @param theme - theme to resolve against
58
- * @param props - props from outer component
59
58
  * @param cache - cache to use for the base of slot caching
60
59
  */
61
- function resolveToSlotProps<TSlotProps, TTokens, TTheme, TProps>(
62
- styles: BuildSlotProps<TSlotProps, TTokens, TTheme, TProps>,
60
+ function resolveToSlotProps<TSlotProps, TTokens, TTheme>(
61
+ styles: BuildSlotProps<TSlotProps, TTokens, TTheme>,
63
62
  tokens: TTokens,
64
63
  theme: TTheme,
65
- props: TProps,
66
64
  cache: GetMemoValue<TTokens>,
67
65
  ): TSlotProps {
68
66
  const slotProps = {};
69
- Object.keys(styles).forEach(key => {
67
+ Object.keys(styles).forEach((key) => {
70
68
  const style = styles[key];
71
- slotProps[key] = typeof style === 'function' ? style(tokens, theme, props, cache(null, [key])[1]) : style;
69
+ slotProps[key] = typeof style === 'function' ? style(tokens, theme, cache(null, [key])[1]) : style;
72
70
  });
73
71
  return slotProps as TSlotProps;
74
72
  }
@@ -98,7 +96,7 @@ export function buildUseStyling<TProps, TSlotProps, TTokens, TTheme>(
98
96
 
99
97
  // resolve overrides as appropriate
100
98
  if (options.states) {
101
- [mergedTokens, cache] = applyTokenLayers(mergedTokens, options.states as string[], cache, lookup || (val => props[val]));
99
+ [mergedTokens, cache] = applyTokenLayers(mergedTokens, options.states as string[], cache, lookup || ((val) => props[val]));
102
100
  }
103
101
 
104
102
  // now resolve tokens
@@ -109,6 +107,6 @@ export function buildUseStyling<TProps, TSlotProps, TTokens, TTheme>(
109
107
  }
110
108
 
111
109
  // finally produce slotProps from calling the style functions on each entry
112
- return resolveToSlotProps(styles, mergedTokens, theme, props, cache);
110
+ return resolveToSlotProps(styles, mergedTokens, theme, cache);
113
111
  };
114
112
  }