@tamagui/helpers 1.0.1-beta.59 → 1.0.1-beta.60

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/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@tamagui/helpers",
3
- "version": "1.0.1-beta.59",
3
+ "version": "1.0.1-beta.60",
4
4
  "source": "src/index.ts",
5
5
  "types": "./types/index.d.ts",
6
6
  "main": "dist/cjs",
7
7
  "module": "dist/esm",
8
8
  "module:jsx": "dist/jsx",
9
9
  "files": [
10
+ "src",
10
11
  "types",
11
12
  "dist"
12
13
  ],
@@ -17,7 +18,7 @@
17
18
  "clean:build": "tamagui-build clean:build"
18
19
  },
19
20
  "devDependencies": {
20
- "@tamagui/build": "^1.0.1-beta.59",
21
+ "@tamagui/build": "^1.0.1-beta.60",
21
22
  "react": "*",
22
23
  "react-native": "*"
23
24
  },
package/src/clamp.ts ADDED
@@ -0,0 +1,3 @@
1
+ export function clamp(value: number, [min, max]: [number, number]): number {
2
+ return Math.min(max, Math.max(min, value))
3
+ }
@@ -0,0 +1,17 @@
1
+ import { FocusEvent } from 'react'
2
+ import { GestureResponderEvent } from 'react-native'
3
+
4
+ export type EventHandler<E extends Event | GestureResponderEvent | FocusEvent> = (event: E) => void
5
+
6
+ export function composeEventHandlers<E extends Event | GestureResponderEvent | FocusEvent>(
7
+ og?: EventHandler<E>,
8
+ next?: EventHandler<E>,
9
+ { checkDefaultPrevented = true } = {}
10
+ ) {
11
+ return function composedEventHandler(event: E) {
12
+ og?.(event)
13
+ if (!checkDefaultPrevented || !event.defaultPrevented) {
14
+ return next?.(event)
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,92 @@
1
+ // perf sensitive so doing some weird stuff
2
+
3
+ import { ViewStyle } from 'react-native'
4
+
5
+ export function concatClassName(...args: any[]): any
6
+ export function concatClassName(_cn: ViewStyle | null | undefined): string {
7
+ const cnOrPropObjcet = arguments
8
+ const usedPrefixes: string[] = []
9
+ let final = ''
10
+
11
+ const len = cnOrPropObjcet.length
12
+ let propObjects: any = null
13
+ for (let x = len; x >= 0; x--) {
14
+ const cns = cnOrPropObjcet[x]
15
+
16
+ if (!cns) continue
17
+ if (!Array.isArray(cns) && typeof cns !== 'string') {
18
+ // is prop object
19
+ propObjects = propObjects || []
20
+ propObjects.push(cns)
21
+ continue
22
+ }
23
+
24
+ const names = Array.isArray(cns) ? cns : cns.split(' ')
25
+ const numNames = names.length
26
+ for (let i = numNames - 1; i >= 0; i--) {
27
+ const name = names[i]
28
+
29
+ if (!name || name === ' ') continue
30
+ if (name[0] !== '_') {
31
+ // not snack style (todo slightly stronger heuristic)
32
+ final = name + ' ' + final
33
+ continue
34
+ }
35
+
36
+ const splitIndex = name.indexOf('-')
37
+ if (splitIndex < 1) {
38
+ final = name + ' ' + final
39
+ // if (shouldDebug) console.log('debug exclude:', name, final)
40
+ continue
41
+ }
42
+
43
+ const nextChar = name[splitIndex + 1]
44
+ // synced to static-ui constants
45
+ // MEDIA_SEP
46
+ const isMediaQuery = nextChar === '_'
47
+ // PSEUDO_SEP
48
+ // commenting out three things to make pseudos override properly
49
+ // (leave in for a bit to see if other bugs pop up later):
50
+ // 1. const isPsuedoQuery = nextChar === '0'
51
+ const styleKey = name.slice(1, name.lastIndexOf('-'))
52
+ // 2. isMediaQuery || isPsuedoQuery
53
+ const mediaKey = isMediaQuery ? name.slice(splitIndex + 2, splitIndex + 7) : null
54
+ const uid = mediaKey ? styleKey + mediaKey : styleKey
55
+ // 3. && !isPsuedoQuery
56
+
57
+ if (usedPrefixes.indexOf(uid) > -1) {
58
+ // if (shouldDebug) console.log('debug exclude:', usedPrefixes, name)
59
+ continue
60
+ }
61
+ usedPrefixes.push(uid)
62
+
63
+ // overrides for full safety
64
+ const propName = styleKey
65
+ if (propName && propObjects) {
66
+ if (
67
+ propObjects.some((po) => {
68
+ if (mediaKey) {
69
+ const propKey = pseudoInvert[mediaKey]
70
+ return po && po[propKey] && propName in po[propKey] && po[propKey] !== null
71
+ }
72
+ const res = po && propName in po && po[propName] !== null
73
+ return res
74
+ })
75
+ ) {
76
+ // if (shouldDebug) console.log('debug exclude:', name)
77
+ continue
78
+ }
79
+ }
80
+
81
+ final = name + ' ' + final
82
+ }
83
+ }
84
+
85
+ return final
86
+ }
87
+
88
+ const pseudoInvert = {
89
+ hover: 'hoverStyle',
90
+ focus: 'focusStyle',
91
+ press: 'pressStyle',
92
+ }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from './clamp'
2
+ export * from './composeEventHandlers'
3
+ export * from './concatClassName'
4
+ export * from './validStyleProps'
5
+ export * from './types'
6
+ export * from './log'
7
+ export * from './simpleHash'
package/src/log.ts ADDED
@@ -0,0 +1,4 @@
1
+ export const log = (...args: any) => {
2
+ console.log(...args)
3
+ return args[0]
4
+ }
@@ -0,0 +1,9 @@
1
+ export const simpleHash = (str: string) => {
2
+ let hash = 0
3
+ for (let i = 0; i < str.length; i++) {
4
+ const char = str.charCodeAt(i)
5
+ hash = (hash << 5) - hash + char
6
+ hash &= hash // Convert to 32bit integer
7
+ }
8
+ return new Uint32Array([hash])[0].toString(36)
9
+ }
package/src/types.ts ADDED
@@ -0,0 +1,8 @@
1
+ export type StyleObject = {
2
+ property: string
3
+ pseudo?: 'hover' | 'focus' | 'active'
4
+ value: string
5
+ className: string
6
+ identifier: string
7
+ rules: string[]
8
+ }
@@ -0,0 +1,163 @@
1
+ // flat transform props
2
+ export const stylePropsTransform = Object.freeze({
3
+ x: true,
4
+ y: true,
5
+ scale: true,
6
+ perspective: true,
7
+ scaleX: true,
8
+ scaleY: true,
9
+ skewX: true,
10
+ skewY: true,
11
+ matrix: true,
12
+ rotate: true,
13
+ rotateY: true,
14
+ rotateX: true,
15
+ rotateZ: true,
16
+ })
17
+
18
+ export const stylePropsView = Object.freeze({
19
+ backfaceVisibility: true,
20
+ backgroundColor: true,
21
+ borderBottomColor: true,
22
+ borderBottomStyle: true,
23
+ borderTopStyle: true,
24
+ borderLeftStyle: true,
25
+ borderRightStyle: true,
26
+ borderBottomEndRadius: true,
27
+ borderBottomLeftRadius: true,
28
+ borderBottomRightRadius: true,
29
+ borderBottomStartRadius: true,
30
+ borderBottomWidth: true,
31
+ borderColor: true,
32
+ borderEndColor: true,
33
+ borderLeftColor: true,
34
+ borderLeftWidth: true,
35
+ borderRadius: true,
36
+ borderRightColor: true,
37
+ borderRightWidth: true,
38
+ borderStartColor: true,
39
+ borderStyle: true,
40
+ borderTopColor: true,
41
+ borderTopEndRadius: true,
42
+ borderTopLeftRadius: true,
43
+ borderTopRightRadius: true,
44
+ borderTopStartRadius: true,
45
+ borderTopWidth: true,
46
+ borderWidth: true,
47
+ opacity: true,
48
+ transform: true,
49
+ alignContent: true,
50
+ alignItems: true,
51
+ alignSelf: true,
52
+ aspectRatio: true,
53
+ borderEndWidth: true,
54
+ borderStartWidth: true,
55
+ bottom: true,
56
+ display: true,
57
+ end: true,
58
+ flex: true,
59
+ flexBasis: true,
60
+ flexDirection: true,
61
+ flexGrow: true,
62
+ flexShrink: true,
63
+ flexWrap: true,
64
+ height: true,
65
+ justifyContent: true,
66
+ left: true,
67
+ margin: true,
68
+ marginBottom: true,
69
+ marginEnd: true,
70
+ marginHorizontal: true,
71
+ marginLeft: true,
72
+ marginRight: true,
73
+ marginStart: true,
74
+ marginTop: true,
75
+ marginVertical: true,
76
+ maxHeight: true,
77
+ maxWidth: true,
78
+ minHeight: true,
79
+ minWidth: true,
80
+ overflow: true,
81
+ padding: true,
82
+ paddingBottom: true,
83
+ paddingEnd: true,
84
+ paddingHorizontal: true,
85
+ paddingLeft: true,
86
+ paddingRight: true,
87
+ paddingStart: true,
88
+ paddingTop: true,
89
+ paddingVertical: true,
90
+ position: true,
91
+ right: true,
92
+ start: true,
93
+ top: true,
94
+ width: true,
95
+ zIndex: true,
96
+ direction: true,
97
+ shadowColor: true,
98
+ shadowOffset: true,
99
+ shadowOpacity: true,
100
+ shadowRadius: true,
101
+ ...stylePropsTransform,
102
+
103
+ // allow a few web only ones
104
+ ...(process.env.TAMAGUI_TARGET === 'web' && {
105
+ overflowX: true,
106
+ overflowY: true,
107
+ userSelect: true,
108
+ cursor: true,
109
+ contain: true,
110
+ pointerEvents: true,
111
+ boxSizing: true,
112
+ boxShadow: true,
113
+ }),
114
+ })
115
+
116
+ export const stylePropsTextOnly = Object.freeze({
117
+ color: true,
118
+ fontFamily: true,
119
+ fontSize: true,
120
+ fontStyle: true,
121
+ fontWeight: true,
122
+ letterSpacing: true,
123
+ lineHeight: true,
124
+ textAlign: true,
125
+ textDecorationLine: true,
126
+ textDecorationStyle: true,
127
+ textDecorationColor: true,
128
+ textShadowColor: true,
129
+ textShadowOffset: true,
130
+ textShadowRadius: true,
131
+ textTransform: true,
132
+
133
+ // allow some web only ones
134
+ ...(process.env.TAMAGUI_TARGET === 'web' && {
135
+ whiteSpace: true,
136
+ wordWrap: true,
137
+ textOverflow: true,
138
+ textDecorationDistance: true,
139
+ userSelect: true,
140
+ selectable: true,
141
+ cursor: true,
142
+ }),
143
+ })
144
+
145
+ export const stylePropsText = Object.freeze({
146
+ ...stylePropsView,
147
+ ...stylePropsTextOnly,
148
+ })
149
+
150
+ export const stylePropsAll = stylePropsText
151
+
152
+ export const validPseudoKeys = Object.freeze({
153
+ enterStyle: true,
154
+ exitStyle: true,
155
+ hoverStyle: true,
156
+ pressStyle: true,
157
+ focusStyle: true,
158
+ })
159
+
160
+ export const validStyles = Object.freeze({
161
+ ...validPseudoKeys,
162
+ ...stylePropsView,
163
+ })