@tamagui/core 1.0.1-beta.148 → 1.0.1-beta.151

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/dist/cjs/constants/platform.js.map +2 -2
  2. package/dist/cjs/createComponent.js +161 -52
  3. package/dist/cjs/createComponent.js.map +2 -2
  4. package/dist/cjs/createFont.js +2 -1
  5. package/dist/cjs/createFont.js.map +2 -2
  6. package/dist/cjs/helpers/getSplitStyles.js +60 -50
  7. package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
  8. package/dist/cjs/helpers/mergeTransform.js.map +2 -2
  9. package/dist/cjs/hooks/useFeatures.js +0 -120
  10. package/dist/cjs/hooks/useFeatures.js.map +2 -2
  11. package/dist/cjs/insertFont.js +1 -1
  12. package/dist/cjs/insertFont.js.map +2 -2
  13. package/dist/cjs/types.js.map +1 -1
  14. package/dist/esm/constants/platform.js.map +2 -2
  15. package/dist/esm/createComponent.js +169 -55
  16. package/dist/esm/createComponent.js.map +2 -2
  17. package/dist/esm/createFont.js +2 -1
  18. package/dist/esm/createFont.js.map +2 -2
  19. package/dist/esm/helpers/getSplitStyles.js +60 -50
  20. package/dist/esm/helpers/getSplitStyles.js.map +2 -2
  21. package/dist/esm/helpers/mergeTransform.js.map +2 -2
  22. package/dist/esm/hooks/useFeatures.js +0 -120
  23. package/dist/esm/hooks/useFeatures.js.map +2 -2
  24. package/dist/esm/insertFont.js +1 -1
  25. package/dist/esm/insertFont.js.map +2 -2
  26. package/package.json +10 -9
  27. package/src/constants/platform.ts +1 -0
  28. package/src/createComponent.tsx +246 -57
  29. package/src/createFont.ts +4 -1
  30. package/src/helpers/getSplitStyles.tsx +73 -65
  31. package/src/helpers/mergeTransform.ts +2 -0
  32. package/src/insertFont.ts +1 -1
  33. package/src/types.tsx +7 -5
  34. package/types/helpers/getSplitStyles.d.ts +1 -0
  35. package/types/hooks/useFeatures.d.ts +0 -1
  36. package/types/types.d.ts +11 -3
  37. package/src/hooks/useFeatures.tsx +0 -289
package/src/types.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  // TODO split this into own package @tamagui/types to share with animations packages
2
2
 
3
3
  import { Properties } from 'csstype'
4
- import React from 'react'
4
+ import React, { RefObject } from 'react'
5
5
  import {
6
6
  GestureResponderEvent,
7
7
  Image,
@@ -336,6 +336,8 @@ export type GenericFont<Key extends number | string = number | string> = {
336
336
  style?: Partial<{ [key in Key]: TextStyle['fontStyle'] | Variable }>
337
337
  transform?: Partial<{ [key in Key]: TextStyle['textTransform'] | Variable }>
338
338
  color?: Partial<{ [key in Key]: string | Variable }>
339
+ // for native use only, lets you map to alternative fonts
340
+ face?: { [key in FontWeightSteps]: { normal?: string; italic?: string } }
339
341
  }
340
342
 
341
343
  // media
@@ -429,9 +431,8 @@ export type RadiusTokens = GetTokenString<keyof Tokens['radius']> | number
429
431
  export type FontTokens = GetTokenString<keyof TamaguiConfig['fonts']>
430
432
  export type FontSizeTokens = GetTokenString<GetTokenFontKeysFor<'size'>> | number
431
433
  export type FontLineHeightTokens = `$${GetTokenFontKeysFor<'lineHeight'>}` | number
432
- export type FontWeightTokens =
433
- | `$${GetTokenFontKeysFor<'weight'>}`
434
- | `${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}00`
434
+ export type FontWeightSteps = `${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}00`
435
+ export type FontWeightTokens = `$${GetTokenFontKeysFor<'weight'>}` | FontWeightSteps
435
436
  export type FontColorTokens = `$${GetTokenFontKeysFor<'color'>}` | number
436
437
  export type FontLetterSpacingTokens = `$${GetTokenFontKeysFor<'letterSpacing'>}` | number
437
438
  export type FontStyleTokens = `$${GetTokenFontKeysFor<'style'>}` | TextStyle['fontStyle']
@@ -1242,6 +1243,7 @@ export type AnimationDriver<A extends AnimationConfig = AnimationConfig> = {
1242
1243
  export type UseAnimationProps = TamaguiComponentPropsBase & Record<string, any>
1243
1244
 
1244
1245
  export type UseAnimationHelpers = {
1246
+ hostRef: RefObject<HTMLElement | View>
1245
1247
  staticConfig: StaticConfigParsed
1246
1248
  getStyle: (props?: {
1247
1249
  isEntering?: boolean
@@ -1262,6 +1264,6 @@ export type UseAnimationHelpers = {
1262
1264
  export type UseAnimationHook = (
1263
1265
  props: UseAnimationProps,
1264
1266
  helpers: UseAnimationHelpers
1265
- ) => {
1267
+ ) => null | {
1266
1268
  style?: StackStylePropsBase | StackStylePropsBase[]
1267
1269
  }
@@ -15,6 +15,7 @@ declare type StyleSplitter = (props: {
15
15
  rulesToInsert: RulesToInsert;
16
16
  viewProps: StackProps;
17
17
  fontFamily: string | undefined;
18
+ mediaKeys: string[];
18
19
  };
19
20
  export declare const PROP_SPLIT = "-";
20
21
  export declare const pseudoCNInverse: {
@@ -16,7 +16,6 @@ declare type FeatureUtils = {
16
16
  export declare const useFeatures: (props: any, utils?: FeatureUtils) => {
17
17
  elements: JSX.Element[];
18
18
  enabled: {
19
- animation?: boolean | undefined;
20
19
  mediaQuery?: boolean | undefined;
21
20
  };
22
21
  };
package/types/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Properties } from 'csstype';
2
- import React from 'react';
2
+ import React, { RefObject } from 'react';
3
3
  import { GestureResponderEvent, Image, PressableProps, TextProps as ReactTextProps, Text, TextInput, TextStyle, View, ViewProps, ViewStyle } from 'react-native';
4
4
  import { Variable } from './createVariable';
5
5
  import { ResolveVariableTypes } from './helpers/createPropMapper';
@@ -205,6 +205,12 @@ export declare type GenericFont<Key extends number | string = number | string> =
205
205
  color?: Partial<{
206
206
  [key in Key]: string | Variable;
207
207
  }>;
208
+ face?: {
209
+ [key in FontWeightSteps]: {
210
+ normal?: string;
211
+ italic?: string;
212
+ };
213
+ };
208
214
  };
209
215
  export declare type MediaQueryObject = {
210
216
  [key: string]: string | number | string;
@@ -264,7 +270,8 @@ export declare type RadiusTokens = GetTokenString<keyof Tokens['radius']> | numb
264
270
  export declare type FontTokens = GetTokenString<keyof TamaguiConfig['fonts']>;
265
271
  export declare type FontSizeTokens = GetTokenString<GetTokenFontKeysFor<'size'>> | number;
266
272
  export declare type FontLineHeightTokens = `$${GetTokenFontKeysFor<'lineHeight'>}` | number;
267
- export declare type FontWeightTokens = `$${GetTokenFontKeysFor<'weight'>}` | `${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}00`;
273
+ export declare type FontWeightSteps = `${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}00`;
274
+ export declare type FontWeightTokens = `$${GetTokenFontKeysFor<'weight'>}` | FontWeightSteps;
268
275
  export declare type FontColorTokens = `$${GetTokenFontKeysFor<'color'>}` | number;
269
276
  export declare type FontLetterSpacingTokens = `$${GetTokenFontKeysFor<'letterSpacing'>}` | number;
270
277
  export declare type FontStyleTokens = `$${GetTokenFontKeysFor<'style'>}` | TextStyle['fontStyle'];
@@ -492,6 +499,7 @@ export declare type AnimationDriver<A extends AnimationConfig = AnimationConfig>
492
499
  };
493
500
  export declare type UseAnimationProps = TamaguiComponentPropsBase & Record<string, any>;
494
501
  export declare type UseAnimationHelpers = {
502
+ hostRef: RefObject<HTMLElement | View>;
495
503
  staticConfig: StaticConfigParsed;
496
504
  getStyle: (props?: {
497
505
  isEntering?: boolean;
@@ -504,7 +512,7 @@ export declare type UseAnimationHelpers = {
504
512
  onDidAnimate?: any;
505
513
  delay?: number;
506
514
  };
507
- export declare type UseAnimationHook = (props: UseAnimationProps, helpers: UseAnimationHelpers) => {
515
+ export declare type UseAnimationHook = (props: UseAnimationProps, helpers: UseAnimationHelpers) => null | {
508
516
  style?: StackStylePropsBase | StackStylePropsBase[];
509
517
  };
510
518
  export {};
@@ -1,289 +0,0 @@
1
- import React from 'react'
2
- import { RefObject } from 'react'
3
- import { View, ViewStyle } from 'react-native'
4
-
5
- import { getConfig } from '../config'
6
- import { useIsomorphicLayoutEffect } from '../constants/platform'
7
- import { getSubStyle } from '../helpers/getSplitStyles'
8
- import {
9
- PseudoStyles,
10
- SplitStyleState,
11
- StaticConfigParsed,
12
- TamaguiComponentState,
13
- TamaguiInternalConfig,
14
- UseAnimationHook,
15
- UseAnimationProps,
16
- } from '../types'
17
- import { addMediaQueryListener, mediaState, removeMediaQueryListener } from './useMedia'
18
-
19
- type FeatureDefinition = {
20
- isEnabled: (props: any) => boolean
21
- Component: any
22
- }
23
-
24
- type FeatureUtils = {
25
- forceUpdate: Function
26
- state: SplitStyleState
27
- setStateShallow: (next: Partial<TamaguiComponentState>) => void
28
- useAnimations?: UseAnimationHook
29
- pseudos: PseudoStyles
30
- style: ViewStyle | null | undefined
31
- staticConfig: StaticConfigParsed
32
- theme: any
33
- onDidAnimate?: () => void
34
- hostRef: RefObject<HTMLElement | View>
35
- }
36
-
37
- const createDefinition = ({
38
- Component,
39
- propNames,
40
- }: {
41
- Component: (props: { _utils: FeatureUtils; [key: string]: any }) => void
42
- propNames: string[]
43
- }): FeatureDefinition => ({
44
- isEnabled: (props: any) => propNames.some((name) => !!props[name]),
45
- Component,
46
- })
47
-
48
- let featureDefinitions: Record<string, FeatureDefinition> | null = null
49
- let tamaguiConfig: TamaguiInternalConfig
50
-
51
- type FeatureKeys = keyof ReturnType<typeof loadFeatures>
52
-
53
- export const useFeatures = (props: any, utils?: FeatureUtils) => {
54
- if (!featureDefinitions) {
55
- featureDefinitions = loadFeatures()
56
- }
57
- const elements: JSX.Element[] = []
58
- const enabled: { [key in FeatureKeys]?: boolean } = {}
59
- for (const name in featureDefinitions) {
60
- const { isEnabled, Component } = featureDefinitions[name]
61
- if (isEnabled(props) && Component) {
62
- enabled[name] = true
63
- elements.push(<Component key={name} {...props} _utils={utils} />)
64
- }
65
- }
66
- return {
67
- elements,
68
- enabled,
69
- }
70
- }
71
-
72
- function loadFeatures() {
73
- return {
74
- // loads animations and sets state with the results
75
- animation: loadAnimationFeature(),
76
-
77
- // will update the parent whenever media query changes
78
- // no need on web, media queries are inserted and run in css
79
- mediaQuery: loadMediaQueryFeature(),
80
- } as const
81
- }
82
-
83
- function loadAnimationFeature() {
84
- tamaguiConfig = tamaguiConfig || getConfig()
85
-
86
- return createDefinition({
87
- Component: ({ _utils, ...props }) => {
88
- const {
89
- state,
90
- useAnimations,
91
- pseudos,
92
- style: inStyle,
93
- setStateShallow,
94
- staticConfig,
95
- theme,
96
- onDidAnimate,
97
- } = _utils
98
-
99
- if (!useAnimations) {
100
- // eslint-disable-next-line no-console
101
- console.error('no useAnimations hook provided')
102
- return null
103
- }
104
-
105
- // we always have .animation set
106
- const propsWithAnimation = props as UseAnimationProps
107
-
108
- const res = useAnimations(propsWithAnimation, {
109
- state,
110
- pseudos,
111
- onDidAnimate,
112
- staticConfig,
113
- getStyle({ isExiting, isEntering, exitVariant, enterVariant } = {}) {
114
- // we have to merge such that transforms keys all exist
115
- const style = inStyle || {}
116
-
117
- const enterStyle = isEntering
118
- ? enterVariant && staticConfig.variants?.[enterVariant]['true']
119
- ? getSubStyle(
120
- '',
121
- staticConfig.variants?.[enterVariant]['true'],
122
- staticConfig,
123
- theme,
124
- props,
125
- state,
126
- tamaguiConfig
127
- ) || pseudos.enterStyle
128
- : null || pseudos.enterStyle
129
- : null
130
-
131
- const exitStyle = isExiting
132
- ? exitVariant && staticConfig.variants?.[exitVariant]['true']
133
- ? getSubStyle(
134
- '',
135
- staticConfig.variants?.[exitVariant]['true'],
136
- staticConfig,
137
- theme,
138
- props,
139
- state,
140
- tamaguiConfig
141
- ) || pseudos.exitStyle
142
- : null || pseudos.exitStyle
143
- : null
144
-
145
- // if you have hoverStyle={{ scale: 1.1 }} and don't have scale set on the base style
146
- // no animation will run! this is really confusing. this will look at all variants,
147
- // and fill in base styles if they don't exist. eg:
148
- // input:
149
- // base: {}
150
- // hoverStyle: { scale: 2 }
151
- // enterStyle: { x: 100 }
152
- // output:
153
- // base: { x: 0, scale: 1 }
154
- ensureBaseHasDefaults(
155
- style,
156
- enterStyle,
157
- pseudos.hoverStyle,
158
- pseudos.focusStyle,
159
- pseudos.pressStyle,
160
- pseudos.pressStyle
161
- )
162
-
163
- enterStyle && merge(style, enterStyle)
164
- state.hover && pseudos.hoverStyle && merge(style, pseudos.hoverStyle)
165
- state.focus && pseudos.focusStyle && merge(style, pseudos.focusStyle)
166
- state.press && pseudos.pressStyle && merge(style, pseudos.pressStyle)
167
- exitStyle && merge(style, exitStyle)
168
-
169
- if (process.env.NODE_ENV === 'development') {
170
- if (props['debug']) {
171
- // eslint-disable-next-line no-console
172
- console.log('animation style', style)
173
- }
174
- }
175
-
176
- return style
177
- },
178
- //, delay
179
- })
180
-
181
- useIsomorphicLayoutEffect(() => {
182
- setStateShallow({
183
- animation: res,
184
- })
185
- }, [res])
186
-
187
- return null
188
- },
189
- propNames: ['animation'],
190
- })
191
- }
192
-
193
- const defaults = {
194
- left: 0,
195
- right: 0,
196
- top: 0,
197
- bottom: 0,
198
- opacity: 1,
199
- translateX: 0,
200
- translateY: 0,
201
- skew: 0,
202
- skewX: 0,
203
- skewY: 0,
204
- scale: 1,
205
- rotate: '0deg',
206
- rotateY: '0deg',
207
- rotateX: '0deg',
208
- }
209
-
210
- function ensureBaseHasDefaults(base: ViewStyle, ...pseudos: (ViewStyle | null | undefined)[]) {
211
- for (const pseudo of pseudos) {
212
- if (!pseudo) continue
213
- for (const key in pseudo) {
214
- const val = pseudo[key]
215
- if (key === 'transform') {
216
- if (typeof val === 'string') {
217
- continue
218
- }
219
- for (const t of val) {
220
- const tkey = Object.keys(t)[0]
221
- const defaultVal = defaults[tkey]
222
- const tDefaultVal = { [tkey]: defaultVal } as any
223
- if (!base.transform) {
224
- base.transform = [tDefaultVal]
225
- } else {
226
- if (!base.transform.find((x) => x[tkey])) {
227
- base.transform.push(tDefaultVal)
228
- }
229
- }
230
- }
231
- } else {
232
- if (!(key in base)) {
233
- base[key] = defaults[key]
234
- }
235
- }
236
- }
237
- }
238
- }
239
-
240
- function merge(base: ViewStyle, next: ViewStyle) {
241
- if (!next.transform || !base.transform) {
242
- Object.assign(base, next)
243
- return
244
- }
245
- const { transform, ...rest } = next
246
- Object.assign(base, rest)
247
- for (const t of transform) {
248
- const key = Object.keys(t)[0]
249
- const existing = base.transform.find((x) => key in x)
250
- if (existing) {
251
- existing[key] = t[key]
252
- } else {
253
- base.transform.push(t)
254
- }
255
- }
256
- }
257
-
258
- function loadMediaQueryFeature() {
259
- const mediaPropNames = Object.keys(mediaState)
260
-
261
- return createDefinition({
262
- Component: (props: any) => {
263
- const mediaKeys = mediaPropNames.filter((x) => x in props)
264
-
265
- useIsomorphicLayoutEffect(() => {
266
- for (const key of mediaKeys) {
267
- addMediaQueryListener(key, props._utils.forceUpdate)
268
- }
269
- return () => {
270
- for (const key of mediaKeys) {
271
- removeMediaQueryListener(key, props._utils.forceUpdate)
272
- }
273
- }
274
- }, [mediaKeys.join(',')])
275
-
276
- return null
277
- },
278
- propNames: mediaPropNames,
279
- })
280
- }
281
-
282
- // TODO
283
- // measureLayout: createDefinition({
284
- // Component: (props) => {
285
- // console.log('measure', props)
286
- // return null
287
- // },
288
- // propNames: ['onLayout'],
289
- // }),