react-native-unistyles 2.0.0-alpha.14 → 2.0.0-alpha.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. package/cxx/UnistylesRuntime.h +6 -6
  2. package/lib/commonjs/common.js +15 -15
  3. package/lib/commonjs/common.js.map +1 -1
  4. package/lib/commonjs/core/UnistylesRuntime.js +1 -1
  5. package/lib/commonjs/core/UnistylesRuntime.js.map +1 -1
  6. package/lib/commonjs/createStyleSheet.js +1 -6
  7. package/lib/commonjs/createStyleSheet.js.map +1 -1
  8. package/lib/commonjs/hooks/index.js +7 -0
  9. package/lib/commonjs/hooks/index.js.map +1 -1
  10. package/lib/commonjs/hooks/useUnistyles.js +4 -7
  11. package/lib/commonjs/hooks/useUnistyles.js.map +1 -1
  12. package/lib/commonjs/hooks/useVariants.js +24 -0
  13. package/lib/commonjs/hooks/useVariants.js.map +1 -0
  14. package/lib/commonjs/plugins/normalizer/normalizer.js +1 -1
  15. package/lib/commonjs/plugins/normalizer/normalizer.js.map +1 -1
  16. package/lib/commonjs/types/stylesheet.js +6 -0
  17. package/lib/commonjs/types/stylesheet.js.map +1 -0
  18. package/lib/commonjs/useStyles.js +5 -4
  19. package/lib/commonjs/useStyles.js.map +1 -1
  20. package/lib/commonjs/utils/index.js +24 -0
  21. package/lib/commonjs/utils/index.js.map +1 -1
  22. package/lib/commonjs/utils/mq.js +42 -28
  23. package/lib/commonjs/utils/mq.js.map +1 -1
  24. package/lib/commonjs/utils/styles.js +14 -8
  25. package/lib/commonjs/utils/styles.js.map +1 -1
  26. package/lib/commonjs/utils/variants.js +33 -13
  27. package/lib/commonjs/utils/variants.js.map +1 -1
  28. package/lib/module/common.js +14 -14
  29. package/lib/module/common.js.map +1 -1
  30. package/lib/module/core/UnistylesRuntime.js +1 -1
  31. package/lib/module/core/UnistylesRuntime.js.map +1 -1
  32. package/lib/module/createStyleSheet.js +1 -6
  33. package/lib/module/createStyleSheet.js.map +1 -1
  34. package/lib/module/hooks/index.js +1 -0
  35. package/lib/module/hooks/index.js.map +1 -1
  36. package/lib/module/hooks/useUnistyles.js +5 -8
  37. package/lib/module/hooks/useUnistyles.js.map +1 -1
  38. package/lib/module/hooks/useVariants.js +17 -0
  39. package/lib/module/hooks/useVariants.js.map +1 -0
  40. package/lib/module/plugins/normalizer/normalizer.js +1 -1
  41. package/lib/module/plugins/normalizer/normalizer.js.map +1 -1
  42. package/lib/module/types/stylesheet.js +2 -0
  43. package/lib/module/types/stylesheet.js.map +1 -0
  44. package/lib/module/useStyles.js +6 -5
  45. package/lib/module/useStyles.js.map +1 -1
  46. package/lib/module/utils/index.js +1 -1
  47. package/lib/module/utils/index.js.map +1 -1
  48. package/lib/module/utils/mq.js +41 -27
  49. package/lib/module/utils/mq.js.map +1 -1
  50. package/lib/module/utils/styles.js +15 -9
  51. package/lib/module/utils/styles.js.map +1 -1
  52. package/lib/module/utils/variants.js +31 -11
  53. package/lib/module/utils/variants.js.map +1 -1
  54. package/lib/typescript/src/common.d.ts +10 -10
  55. package/lib/typescript/src/common.d.ts.map +1 -1
  56. package/lib/typescript/src/createStyleSheet.d.ts +2 -2
  57. package/lib/typescript/src/createStyleSheet.d.ts.map +1 -1
  58. package/lib/typescript/src/global.d.ts.map +1 -1
  59. package/lib/typescript/src/hooks/index.d.ts +1 -0
  60. package/lib/typescript/src/hooks/index.d.ts.map +1 -1
  61. package/lib/typescript/src/hooks/useUnistyles.d.ts.map +1 -1
  62. package/lib/typescript/src/hooks/useVariants.d.ts +3 -0
  63. package/lib/typescript/src/hooks/useVariants.d.ts.map +1 -0
  64. package/lib/typescript/src/plugins/normalizer/normalizer.d.ts.map +1 -1
  65. package/lib/typescript/src/types/breakpoints.d.ts +20 -14
  66. package/lib/typescript/src/types/breakpoints.d.ts.map +1 -1
  67. package/lib/typescript/src/types/core.d.ts +3 -26
  68. package/lib/typescript/src/types/core.d.ts.map +1 -1
  69. package/lib/typescript/src/types/index.d.ts +2 -1
  70. package/lib/typescript/src/types/index.d.ts.map +1 -1
  71. package/lib/typescript/src/types/mq.d.ts +2 -2
  72. package/lib/typescript/src/types/mq.d.ts.map +1 -1
  73. package/lib/typescript/src/types/stylesheet.d.ts +47 -0
  74. package/lib/typescript/src/types/stylesheet.d.ts.map +1 -0
  75. package/lib/typescript/src/types/unistyles.d.ts +5 -6
  76. package/lib/typescript/src/types/unistyles.d.ts.map +1 -1
  77. package/lib/typescript/src/types/variants.d.ts +13 -7
  78. package/lib/typescript/src/types/variants.d.ts.map +1 -1
  79. package/lib/typescript/src/useStyles.d.ts +3 -3
  80. package/lib/typescript/src/useStyles.d.ts.map +1 -1
  81. package/lib/typescript/src/utils/index.d.ts +1 -1
  82. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  83. package/lib/typescript/src/utils/mq.d.ts +19 -13
  84. package/lib/typescript/src/utils/mq.d.ts.map +1 -1
  85. package/lib/typescript/src/utils/styles.d.ts +3 -3
  86. package/lib/typescript/src/utils/styles.d.ts.map +1 -1
  87. package/lib/typescript/src/utils/variants.d.ts +2 -2
  88. package/lib/typescript/src/utils/variants.d.ts.map +1 -1
  89. package/package.json +14 -14
  90. package/src/common.ts +10 -10
  91. package/src/core/UnistylesRuntime.ts +1 -1
  92. package/src/createStyleSheet.ts +2 -8
  93. package/src/global.ts +1 -0
  94. package/src/hooks/index.ts +1 -0
  95. package/src/hooks/useUnistyles.ts +5 -8
  96. package/src/hooks/useVariants.ts +23 -0
  97. package/src/plugins/normalizer/normalizer.ts +3 -3
  98. package/src/types/breakpoints.ts +47 -26
  99. package/src/types/core.ts +6 -42
  100. package/src/types/index.ts +1 -1
  101. package/src/types/mq.ts +2 -2
  102. package/src/types/stylesheet.ts +56 -0
  103. package/src/types/unistyles.ts +5 -6
  104. package/src/types/variants.ts +17 -9
  105. package/src/useStyles.ts +15 -15
  106. package/src/utils/index.ts +1 -1
  107. package/src/utils/mq.ts +56 -41
  108. package/src/utils/styles.ts +18 -17
  109. package/src/utils/variants.ts +41 -17
@@ -1,7 +1,7 @@
1
1
  import { NativeEventEmitter, NativeModules } from 'react-native'
2
2
  import { useEffect, useState } from 'react'
3
3
  import { unistyles } from '../core'
4
- import { CxxUnistylesEventTypes } from '../common'
4
+ import { UnistylesEventType } from '../common'
5
5
  import type { UnistylesEvents, UnistylesMobileLayoutEvent, UnistylesThemeEvent } from '../types'
6
6
 
7
7
  const unistylesEvents = new NativeEventEmitter(NativeModules.Unistyles)
@@ -23,24 +23,21 @@ export const useUnistyles = () => {
23
23
  'onChange',
24
24
  (event: UnistylesEvents) => {
25
25
  switch (event.type) {
26
- case CxxUnistylesEventTypes.Theme: {
26
+ case UnistylesEventType.Theme: {
27
27
  const themeEvent = event as UnistylesThemeEvent
28
28
 
29
29
  return setTheme(unistyles.registry.getTheme(themeEvent.payload.themeName))
30
30
  }
31
- case CxxUnistylesEventTypes.Layout: {
31
+ case UnistylesEventType.Layout: {
32
32
  const layoutEvent = event as UnistylesMobileLayoutEvent
33
33
 
34
34
  return setLayout({
35
35
  breakpoint: layoutEvent.payload.breakpoint,
36
36
  orientation: layoutEvent.payload.orientation,
37
- screenSize: {
38
- width: layoutEvent.payload.screen.width,
39
- height: layoutEvent.payload.screen.height
40
- }
37
+ screenSize: layoutEvent.payload.screen
41
38
  })
42
39
  }
43
- case CxxUnistylesEventTypes.Plugin: {
40
+ case UnistylesEventType.Plugin: {
44
41
  return setPlugins(unistyles.runtime.enabledPlugins)
45
42
  }
46
43
  default:
@@ -0,0 +1,23 @@
1
+ import { useRef } from 'react'
2
+ import type { Optional } from '../types'
3
+
4
+ const compareVariants = (prevVariants?: Record<string, Optional<string>>, nextVariants?: Record<string, Optional<string>>) => {
5
+ const keysA = Object.keys(prevVariants ?? {})
6
+ const keysB = Object.keys(nextVariants ?? {})
7
+
8
+ if (keysA.length !== keysB.length) {
9
+ return false
10
+ }
11
+
12
+ return keysA.every(key => prevVariants![key] === (nextVariants ?? {})[key])
13
+ }
14
+
15
+ export const useVariants = (variantsMap?: Record<string, Optional<string>>) => {
16
+ const variantsRef = useRef<Optional<Record<string, Optional<string>>>>(variantsMap)
17
+
18
+ if (!compareVariants(variantsRef.current, variantsMap)) {
19
+ variantsRef.current = variantsMap
20
+ }
21
+
22
+ return variantsRef.current
23
+ }
@@ -1,7 +1,7 @@
1
1
  // based on react-native-web normalizer
2
2
  // https://github.com/necolas/react-native-web
3
3
  import normalizeColors from '@react-native/normalize-colors'
4
- import type { TextShadow, Transforms, BoxShadow } from '../../types'
4
+ import type { TextShadow, Transforms, BoxShadow, Nullable } from '../../types'
5
5
 
6
6
  type Preprocessor = {
7
7
  createTextShadowValue(style: TextShadow): string,
@@ -15,9 +15,9 @@ export const normalizeColor = (color: string, opacity: number = 1) => {
15
15
  return color
16
16
  }
17
17
 
18
- const integer = normalizeColors(color) as number | null
18
+ const integer = normalizeColors(color) as Nullable<number>
19
19
 
20
- // If the colour is an unknown format, the return value is null
20
+ // If the color is an unknown format, the return value is null
21
21
  if (integer === null) {
22
22
  return color
23
23
  }
@@ -1,34 +1,55 @@
1
- import type { OpaqueColorValue } from 'react-native'
2
- import type { UnistylesBreakpoints } from '../global'
3
- import type { MediaQuery } from './mq'
1
+ import type { ColorValue, OpaqueColorValue } from 'react-native'
2
+ import type { UnistylesTheme } from '../types'
3
+ import type { AllAvailableKeys, BreakpointsOrMediaQueries } from './stylesheet'
4
4
 
5
5
  type WithEmptyObject<V> = keyof V extends never ? {} : V
6
6
 
7
- type ExtractBreakpoints<T> = T extends Partial<Record<keyof UnistylesBreakpoints & string, infer V>>
8
- ? WithEmptyObject<V>
9
- : T extends (...args: infer A) => infer R
10
- ? (...args: A) => ExtractBreakpoints<R>
11
- : {
12
- [K in keyof T]: T[K] extends (...args: infer A) => infer R
13
- ? (...args: A) => ExtractBreakpoints<R>
14
- : T[K] extends object
15
- ? ExtractBreakpoints<T[K]>
7
+ type ExtractBreakpoints<T> = T extends Partial<Record<BreakpointsOrMediaQueries, infer R>>
8
+ ? WithEmptyObject<R>
9
+ : {
10
+ [K in keyof T]: T[K] extends object
11
+ ? T[K] extends OpaqueColorValue
12
+ ? ColorValue
13
+ : ExtractBreakpoints<T[K]>
14
+ : T[K]
15
+ }
16
+
17
+ type ParseNestedObject<T> = T extends (...args: infer A) => infer R
18
+ ? (...args: A) => ParseNestedObject<R>
19
+ : keyof T extends AllAvailableKeys
20
+ ? ExtractBreakpoints<T>
21
+ : T extends { variants: infer R }
22
+ ? ParseVariants<FlattenVariants<R>> & ParseNestedObject<Omit<T, 'variants'>>
23
+ : {
24
+ [K in keyof T]: T[K] extends object
25
+ ? T[K] extends OpaqueColorValue
26
+ ? ColorValue
27
+ : ExtractBreakpoints<T[K]>
16
28
  : T[K]
17
- }
29
+ }
18
30
 
19
- type UnionToIntersection<U> =
20
- (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
31
+ type FlattenVariants<T> = T extends object
32
+ ? {
33
+ [K in keyof T]: T[K] extends object
34
+ ? {
35
+ [key in keyof T[K]]: T[K][key] extends object
36
+ ? ParseNestedObject<T[K][key]>
37
+ : never
38
+ }
39
+ : never
40
+ }
41
+ : never
21
42
 
22
- type RemoveKeysWithPrefix<T> = T extends (...args: Array<any>) => infer R
23
- ? (...args: Parameters<T>) => RemoveKeysWithPrefix<R>
24
- : T extends object
25
- ? T extends OpaqueColorValue
26
- ? string
27
- : T extends Record<string, infer _V>
28
- ? T extends { variants: infer _V }
29
- ? Omit<T, 'variants'> & UnionToIntersection<_V[keyof _V]>
30
- : { [K in keyof T as K extends MediaQuery ? keyof UnistylesBreakpoints & string : K]: RemoveKeysWithPrefix<T[K]> }
31
- : { [K in keyof T]: RemoveKeysWithPrefix<T[K]> }
43
+ type ParseVariants<T> = T extends object
44
+ ? T[keyof T] extends object
45
+ ? ParseVariants<T[keyof T]>
32
46
  : T
47
+ : T
48
+
49
+ type ParseStyleKeys<T> = T extends object
50
+ ? { [K in keyof T]: ParseNestedObject<T[K]> }
51
+ : never
33
52
 
34
- export type ReactNativeStyleSheet<T> = ExtractBreakpoints<RemoveKeysWithPrefix<T>>
53
+ export type ReactNativeStyleSheet<T> = T extends (theme: UnistylesTheme) => infer R
54
+ ? ParseStyleKeys<R>
55
+ : ParseStyleKeys<T>
package/src/types/core.ts CHANGED
@@ -17,17 +17,12 @@ import type { ImageStyle, TextStyle, ViewStyle } from 'react-native'
17
17
  import type { UnistylesBreakpoints, UnistylesThemes } from '../global'
18
18
  import type { MediaQuery } from './mq'
19
19
 
20
- type ShadowOffset = {
20
+ export type ShadowOffset = {
21
21
  width: number,
22
22
  height: number
23
23
  }
24
24
 
25
- export type ScreenSize = {
26
- width: number,
27
- height: number
28
- }
29
-
30
- type TransformStyles =
25
+ export type TransformStyles =
31
26
  & PerpectiveTransform
32
27
  & RotateTransform
33
28
  & RotateXTransform
@@ -42,40 +37,9 @@ type TransformStyles =
42
37
  & SkewYTransform
43
38
  & MatrixTransform
44
39
 
45
- type UnistyleNested = {
46
- shadowOffset?: DeepUniStyle<ShadowOffset>,
47
- textShadowOffset?: DeepUniStyle<ShadowOffset>,
48
- transform?: Array<DeepUniStyle<TransformStyles>>,
49
- variants?: Record<string, UnistyleView | UnistyleText | UnistyleImage & Omit<UnistyleNested, 'variants'>>
50
- }
51
-
52
- type UniStyle<V> = {
53
- [innerKey in keyof UnistylesBreakpoints]?: V
54
- } | {
55
- [innerKey in MediaQuery]: V
56
- }
57
-
58
- type DeepUniStyle<T> = {
59
- [K in keyof T]?: UniStyle<T[K]> | T[K]
60
- }
61
-
62
- // these props are treated differently to nest breakpoints and media queries
63
- type NestedTypes = 'shadowOffset' | 'transform' | 'textShadowOffset'
64
-
65
- type UnistyleView = DeepUniStyle<Omit<ViewStyle, NestedTypes>>
66
- type UnistyleText = DeepUniStyle<Omit<TextStyle, NestedTypes>>
67
- type UnistyleImage = DeepUniStyle<Omit<ImageStyle, NestedTypes>>
68
-
69
- export type StaticStyles =
70
- | UnistyleView
71
- | UnistyleText
72
- | UnistyleImage
73
- & UnistyleNested
74
-
75
- export type CustomNamedStyles<T> = {
76
- [K in keyof T]: T[K] extends (...args: infer A) => StaticStyles
77
- ? (...args: A) => StaticStyles
78
- : StaticStyles
40
+ export type ScreenSize = {
41
+ width: number,
42
+ height: number
79
43
  }
80
44
 
81
45
  export type RNStyle = ViewStyle | TextStyle | ImageStyle
@@ -83,4 +47,4 @@ export type RNValue = number | string | undefined
83
47
  export type NestedStyle = Record<keyof UnistylesBreakpoints | MediaQuery, RNValue>
84
48
  export type NestedStylePairs = Array<[keyof UnistylesBreakpoints | MediaQuery, RNValue]>
85
49
  export type UnistylesTheme = UnistylesThemes[keyof UnistylesThemes]
86
- export type CreateStylesFactory<ST, Theme> = (theme: Theme) => ST
50
+ export type CreateStylesFactory<ST> = (theme: UnistylesTheme) => ST
@@ -3,7 +3,6 @@ export * from './unistyles'
3
3
  export type { Optional, Nullable } from './common'
4
4
  export type { MediaQuery } from './mq'
5
5
  export type {
6
- CustomNamedStyles,
7
6
  NestedStylePairs,
8
7
  UnistylesTheme,
9
8
  CreateStylesFactory,
@@ -12,6 +11,7 @@ export type {
12
11
  RNValue,
13
12
  RNStyle
14
13
  } from './core'
14
+ export type { StyleSheetWithSuperPowers, StyleSheet } from './stylesheet'
15
15
  export type { ReactNativeStyleSheet } from './breakpoints'
16
16
  export type { ExtractVariantNames } from './variants'
17
17
  export type { UnistylesPlugin } from './plugin'
package/src/types/mq.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { MQSymbol } from '../utils'
1
+ import { MQSymbol, MQHeight, MQHeightAndWidth, MQWidth, MQWidthAndHeight } from '../utils'
2
2
 
3
- export type MediaQuery = typeof MQSymbol
3
+ export type MediaQuery = typeof MQSymbol | typeof MQHeight | typeof MQWidth | typeof MQHeightAndWidth | typeof MQWidthAndHeight
@@ -0,0 +1,56 @@
1
+ import type { ImageStyle, TextStyle, ViewStyle } from 'react-native'
2
+ import type { ShadowOffset, TransformStyles, UnistylesTheme } from './core'
3
+ import type { UnistylesBreakpoints } from '../global'
4
+ import type { MediaQuery } from './mq'
5
+
6
+ // these props are treated differently to nest breakpoints and media queries
7
+ type NestedTypes = 'shadowOffset' | 'transform' | 'textShadowOffset'
8
+
9
+ type UnistyleView = Omit<ViewStyle, NestedTypes>
10
+ type UnistyleText = Omit<TextStyle, NestedTypes>
11
+ type UnistyleImage = Omit<ImageStyle, NestedTypes>
12
+
13
+ type UnistyleNestedStyles = {
14
+ shadowOffset?: ToDeepUnistyles<ShadowOffset>,
15
+ textShadowOffset?: ToDeepUnistyles<ShadowOffset>,
16
+ transform?: Array<ToDeepUnistyles<TransformStyles>>
17
+ }
18
+
19
+ type Variants = {
20
+ variants?: {
21
+ [variantName: string]: {
22
+ [variant: string]: {
23
+ [propName in AllAvailableKeys]?: AllAvailableStyles[propName] | {
24
+ [key in BreakpointsOrMediaQueries]?: AllAvailableStyles[propName]
25
+ } & {
26
+ [propName in NestedTypes]?: UnistyleNestedStyles[propName]
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+
33
+ type ToDeepUnistyles<T> = {
34
+ [K in keyof T]?: T[K] | {
35
+ [key in BreakpointsOrMediaQueries]?: T[K]
36
+ }
37
+ }
38
+
39
+ type AllAvailableStyles = UnistyleView & UnistyleText & UnistyleImage & UnistyleNestedStyles
40
+
41
+ export type AllAvailableKeys = keyof (UnistyleView & UnistyleText & UnistyleImage)
42
+ export type BreakpointsOrMediaQueries = keyof UnistylesBreakpoints | MediaQuery
43
+
44
+ export type UnistylesValues = {
45
+ [propName in AllAvailableKeys]?: AllAvailableStyles[propName] | {
46
+ [key in BreakpointsOrMediaQueries]?: AllAvailableStyles[propName]
47
+ }
48
+ } & Variants & {
49
+ [propName in NestedTypes]?: UnistyleNestedStyles[propName]
50
+ }
51
+
52
+ export type StyleSheet = {
53
+ [styleName: string]: UnistylesValues | ((...args: any) => UnistylesValues)
54
+ }
55
+
56
+ export type StyleSheetWithSuperPowers = ((theme: UnistylesTheme) => StyleSheet) | StyleSheet
@@ -1,10 +1,9 @@
1
- import { CxxUnistylesEventTypes, ScreenOrientation } from '../common'
1
+ import { UnistylesEventType, ScreenOrientation } from '../common'
2
2
  import type { UnistylesThemes, UnistylesBreakpoints } from '../global'
3
3
  import type { ScreenSize } from './core'
4
- import type { Optional } from './common'
5
4
  import type { UnistylesPlugin } from './plugin'
6
5
 
7
- export type ColorSchemeName = Optional<'light' | 'dark'>
6
+ export type ColorSchemeName = 'light' | 'dark' | 'unspecified'
8
7
 
9
8
  export type UnistylesConfig = {
10
9
  adaptiveThemes?: boolean,
@@ -33,14 +32,14 @@ export type UnistylesBridge = {
33
32
  }
34
33
 
35
34
  export type UnistylesThemeEvent = {
36
- type: CxxUnistylesEventTypes.Theme,
35
+ type: UnistylesEventType.Theme,
37
36
  payload: {
38
37
  themeName: keyof UnistylesThemes
39
38
  }
40
39
  }
41
40
 
42
41
  export type UnistylesMobileLayoutEvent = {
43
- type: CxxUnistylesEventTypes.Layout,
42
+ type: UnistylesEventType.Layout,
44
43
  payload: {
45
44
  screen: ScreenSize,
46
45
  breakpoint: keyof UnistylesBreakpoints,
@@ -49,7 +48,7 @@ export type UnistylesMobileLayoutEvent = {
49
48
  }
50
49
 
51
50
  export type UnistylesPluginEvent = {
52
- type: CxxUnistylesEventTypes.Plugin
51
+ type: UnistylesEventType.Plugin
53
52
  }
54
53
 
55
54
  export type UnistylesEvents = UnistylesThemeEvent | UnistylesMobileLayoutEvent | UnistylesPluginEvent
@@ -1,11 +1,19 @@
1
- export type ExtractVariantNames<T> = T extends object
2
- ? {
3
- [K in keyof T]: T[K] extends { variants: infer V }
4
- ? V extends object
5
- ? { [VK in keyof V]: VK extends 'default'
6
- ? never : VK }[keyof V] | ExtractVariantNames<V>
7
- : never
8
- : ExtractVariantNames<T[K]>
9
- }[keyof T]
1
+ export type ExtractVariantNames<T> = T extends (...args: any) => infer R
2
+ ? ExtractVariantKeys<R>
3
+ : ExtractVariantKeys<T>
4
+
5
+ type ExtractVariantKeys<T> = T extends object
6
+ ? ExtractVariant<T[keyof T]>
7
+ : never
8
+
9
+ type ExtractSubVariantKeys<T> = T extends object
10
+ ? keyof Omit<T, 'default'> | undefined
10
11
  : never
11
12
 
13
+ type ExtractVariant<T> = T extends (...args: any) => infer R
14
+ ? R extends { variants: infer V }
15
+ ? { [key in keyof V]?: ExtractSubVariantKeys<V[key]> }
16
+ : never
17
+ : T extends { variants: infer V }
18
+ ? { [key in keyof V]?: ExtractSubVariantKeys<V[key]> }
19
+ : never
package/src/useStyles.ts CHANGED
@@ -1,26 +1,25 @@
1
1
  import { useMemo } from 'react'
2
2
  import { StyleSheet } from 'react-native'
3
3
  import { parseStyle, proxifyFunction } from './utils'
4
+ import { useUnistyles, useVariants } from './hooks'
5
+ import type { UnistylesBreakpoints } from './global'
6
+ import { unistyles } from './core'
4
7
  import type {
5
- CreateStylesFactory,
6
- CustomNamedStyles,
7
8
  ExtractVariantNames,
8
9
  ReactNativeStyleSheet,
10
+ StyleSheetWithSuperPowers,
9
11
  UnistylesTheme
10
12
  } from './types'
11
- import { useUnistyles } from './hooks'
12
- import type { UnistylesBreakpoints } from './global'
13
- import { unistyles } from './core'
14
13
 
15
- type ParsedStylesheet<ST extends CustomNamedStyles<ST>> = {
14
+ type ParsedStylesheet<ST extends StyleSheetWithSuperPowers> = {
16
15
  theme: UnistylesTheme,
17
16
  breakpoint: keyof UnistylesBreakpoints,
18
17
  styles: ReactNativeStyleSheet<ST>
19
18
  }
20
19
 
21
- export const useStyles = <ST extends CustomNamedStyles<ST>>(
22
- stylesheet?: ST | CreateStylesFactory<ST, UnistylesTheme>,
23
- variant?: ExtractVariantNames<typeof stylesheet> & string
20
+ export const useStyles = <ST extends StyleSheetWithSuperPowers>(
21
+ stylesheet?: ST,
22
+ variantsMap?: ExtractVariantNames<typeof stylesheet>
24
23
  ): ParsedStylesheet<ST> => {
25
24
  const { theme, layout, plugins } = useUnistyles()
26
25
 
@@ -32,6 +31,7 @@ export const useStyles = <ST extends CustomNamedStyles<ST>>(
32
31
  }
33
32
  }
34
33
 
34
+ const variants = useVariants(variantsMap)
35
35
  const parsedStyles = useMemo(() => typeof stylesheet === 'function'
36
36
  ? stylesheet(theme)
37
37
  : stylesheet, [theme, stylesheet, layout])
@@ -42,22 +42,22 @@ export const useStyles = <ST extends CustomNamedStyles<ST>>(
42
42
  if (typeof value === 'function') {
43
43
  return {
44
44
  ...acc,
45
- [key]: proxifyFunction(key, value,unistyles.registry.plugins, unistyles.runtime, variant)
45
+ [key]: proxifyFunction(key, value,unistyles.registry.plugins, unistyles.runtime, variants)
46
46
  }
47
47
  }
48
48
 
49
49
  return StyleSheet.create({
50
50
  ...acc,
51
- [key]: parseStyle<ST>(
51
+ [key]: parseStyle(
52
52
  key,
53
- value as CustomNamedStyles<ST>,
53
+ value,
54
54
  unistyles.registry.plugins,
55
55
  unistyles.runtime,
56
- variant
56
+ variants
57
57
  )
58
58
  })
59
- }, {} as ST),
60
- [layout, parsedStyles, variant, plugins]
59
+ }, {}),
60
+ [layout, parsedStyles, variants, plugins]
61
61
  ) as ReactNativeStyleSheet<ST>
62
62
 
63
63
  return {
@@ -1,4 +1,4 @@
1
- export { mq, MQSymbol } from './mq'
1
+ export { mq, MQSymbol, MQHeight, MQWidth, MQHeightAndWidth, MQWidthAndHeight } from './mq'
2
2
  export { getKeyForUnistylesMediaQuery, isWithinTheWidthAndHeight, isValidMq, parseMq } from './mqParser'
3
3
  export { getValueForBreakpoint } from './breakpoints'
4
4
  export { proxifyFunction, parseStyle } from './styles'
package/src/utils/mq.ts CHANGED
@@ -1,28 +1,32 @@
1
- import type { MediaQuery, Nullable } from '../types'
1
+ import type { Nullable } from '../types'
2
2
  import type { UnistylesBreakpoints } from '../global'
3
3
  import { unistyles } from '../core'
4
4
 
5
5
  export const MQSymbol = Symbol('unistyles-mq')
6
+ export const MQWidth = Symbol('unistyles-mq-width')
7
+ export const MQHeight = Symbol('unistyles-mq-height')
8
+ export const MQWidthAndHeight = Symbol('unistyles-mq-width-and-height')
9
+ export const MQHeightAndWidth = Symbol('unistyles-mq-height-and-width')
6
10
 
7
11
  type MQValue = keyof UnistylesBreakpoints | number
8
12
 
9
13
  type MQHandler = {
10
- w(wMin?: Nullable<MQValue>, wMax?: MQValue): WidthHandler,
11
- width(wMin?: Nullable<MQValue>, wMax?: MQValue): WidthHandler,
12
- h(hMin?: Nullable<MQValue>, hMax?: MQValue): HeightHandler,
13
- height(hMin?: Nullable<MQValue>, hMax?: MQValue): HeightHandler
14
+ only: {
15
+ width(wMin?: Nullable<MQValue>, wMax?: MQValue): typeof MQWidth,
16
+ height(hMin?: Nullable<MQValue>, hMax?: MQValue): typeof MQHeight,
17
+ },
18
+ width(wMin?: Nullable<MQValue>, wMax?: MQValue): {
19
+ and: {
20
+ height(hMin?: Nullable<MQValue>, hMax?: MQValue): typeof MQWidthAndHeight
21
+ }
22
+ },
23
+ height(hMin?: Nullable<MQValue>, hMax?: MQValue): {
24
+ and: {
25
+ width(wMin?: Nullable<MQValue>, wMax?: MQValue): typeof MQHeightAndWidth
26
+ }
27
+ }
14
28
  }
15
29
 
16
- type HeightHandler = {
17
- w(wMin?: Nullable<MQValue>, wMax?: MQValue): MediaQuery,
18
- width(wMin?: Nullable<MQValue>, wMax?: MQValue): MediaQuery
19
- } & MediaQuery
20
-
21
- type WidthHandler = {
22
- h(hMin?: Nullable<MQValue>, hMax?: MQValue): MediaQuery,
23
- height(hMin?: Nullable<MQValue>, hMax?: MQValue): MediaQuery
24
- } & MediaQuery
25
-
26
30
  type FinalHandler = {
27
31
  [MQSymbol]: true
28
32
  }
@@ -31,8 +35,8 @@ enum MQProp {
31
35
  toString = 'toString',
32
36
  width = 'width',
33
37
  height = 'height',
34
- shortW = 'w',
35
- shortH = 'h'
38
+ only = 'only',
39
+ and = 'and'
36
40
  }
37
41
 
38
42
  const getMQValue = (value: Nullable<MQValue>) => {
@@ -47,60 +51,71 @@ const getMQValue = (value: Nullable<MQValue>) => {
47
51
  return unistyles.registry.breakpoints[value] ?? 0
48
52
  }
49
53
 
50
- const widthHandler = (hMin: Nullable<MQValue> = 0, hMax: MQValue = Infinity) => new Proxy<HeightHandler>({} as HeightHandler, {
54
+ const widthHandler = (hMin: Nullable<MQValue> = 0, hMax: MQValue = Infinity) => new Proxy({} as MQHandler, {
51
55
  get: (target, prop, receiver) => {
52
56
  if (prop === Symbol.toPrimitive || prop === MQProp.toString) {
53
57
  return () => `:h[${getMQValue(hMin)}, ${getMQValue(hMax)}]`
54
58
  }
55
59
 
56
- if (prop === MQProp.width || prop === MQProp.shortW) {
57
- return (wMin: MQValue = 0, wMax: MQValue = Infinity) => new Proxy<FinalHandler>({} as FinalHandler, {
58
- get: (target, prop, receiver) => {
59
- if (prop === Symbol.toPrimitive || prop === MQProp.toString) {
60
- return () => `:w[${getMQValue(wMin)}, ${getMQValue(wMax)}]:h[${getMQValue(hMin)}, ${getMQValue(hMax)}]`
61
- }
60
+ if (prop === MQProp.and) {
61
+ return {
62
+ width: (wMin: MQValue = 0, wMax: MQValue = Infinity) => new Proxy<FinalHandler>({} as FinalHandler, {
63
+ get: (target, prop, receiver) => {
64
+ if (prop === Symbol.toPrimitive || prop === MQProp.toString) {
65
+ return () => `:w[${getMQValue(wMin)}, ${getMQValue(wMax)}]:h[${getMQValue(hMin)}, ${getMQValue(hMax)}]`
66
+ }
62
67
 
63
- return Reflect.get(target, prop, receiver)
64
- }
65
- })
68
+ return Reflect.get(target, prop, receiver)
69
+ }
70
+ })
71
+ }
66
72
  }
67
73
 
68
74
  return Reflect.get(target, prop, receiver)
69
75
  }
70
76
  })
71
77
 
72
- const heightHandler = (wMin: Nullable<MQValue> = 0, wMax: MQValue = Infinity) => new Proxy({} as WidthHandler, {
78
+ const heightHandler = (wMin: Nullable<MQValue> = 0, wMax: MQValue = Infinity) => new Proxy({} as MQHandler, {
73
79
  get: (target, prop, receiver) => {
74
80
  if (prop === Symbol.toPrimitive || prop === MQProp.toString) {
75
81
  return () => `:w[${getMQValue(wMin)}, ${getMQValue(wMax)}]`
76
82
  }
77
83
 
78
- if (prop === MQProp.height || prop === MQProp.shortH) {
79
- return (hMin: MQValue = 0, hMax: MQValue = Infinity) => new Proxy<FinalHandler>({} as FinalHandler, {
80
- get: (target, prop, receiver) => {
81
- if (prop === Symbol.toPrimitive || prop === MQProp.toString) {
82
- return () => `:w[${getMQValue(wMin)}, ${getMQValue(wMax)}]:h[${getMQValue(hMin)}, ${getMQValue(hMax)}]`
83
- }
84
+ if (prop === MQProp.and) {
85
+ return {
86
+ height: (hMin: MQValue = 0, hMax: MQValue = Infinity) => new Proxy<FinalHandler>({} as FinalHandler, {
87
+ get: (target, prop, receiver) => {
88
+ if (prop === Symbol.toPrimitive || prop === MQProp.toString) {
89
+ return () => `:w[${getMQValue(wMin)}, ${getMQValue(wMax)}]:h[${getMQValue(hMin)}, ${getMQValue(hMax)}]`
90
+ }
84
91
 
85
- return Reflect.get(target, prop, receiver)
86
- }
87
- })
92
+ return Reflect.get(target, prop, receiver)
93
+ }
94
+ })
95
+ }
88
96
  }
89
97
 
90
98
  return Reflect.get(target, prop, receiver)
91
99
  }
92
100
  })
93
101
 
94
- export const mq = new Proxy({} as MQHandler, {
102
+ export const mq = new Proxy<MQHandler>({} as MQHandler, {
95
103
  get: (target, prop, receiver) => {
96
- if (prop === MQProp.shortW || prop === MQProp.width) {
97
- return heightHandler
104
+ if (prop === MQProp.only) {
105
+ return {
106
+ width: heightHandler,
107
+ height: widthHandler
108
+ }
98
109
  }
99
110
 
100
- if (prop === MQProp.shortH || prop === MQProp.height) {
111
+ if (prop === MQProp.height) {
101
112
  return widthHandler
102
113
  }
103
114
 
115
+ if (prop === MQProp.width) {
116
+ return heightHandler
117
+ }
118
+
104
119
  return Reflect.get(target, prop, receiver)
105
120
  }
106
121
  })