react-native-varia 0.2.2 → 0.2.4
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/bin/cli.js +316 -139
- package/lib/components/Accordion.tsx +113 -0
- package/lib/components/Button.tsx +19 -8
- package/lib/components/CircleProgress.tsx +46 -28
- package/lib/components/Divider.tsx +18 -15
- package/lib/components/Drawer.tsx +496 -0
- package/lib/components/Field.tsx +24 -39
- package/lib/components/GradientBackground.tsx +25 -7
- package/lib/components/GradientText.tsx +38 -11
- package/lib/components/IconWrapper.tsx +20 -14
- package/lib/components/Input.tsx +106 -25
- package/lib/components/NumberInput.tsx +88 -19
- package/lib/components/OldSlider.tsx +327 -0
- package/lib/components/RadioGroup.tsx +55 -17
- package/lib/components/ReText.tsx +1 -1
- package/lib/components/Select.tsx +58 -22
- package/lib/components/Slider.tsx +176 -115
- package/lib/components/Slideshow.tsx +68 -69
- package/lib/components/SlidingDrawer.tsx +72 -29
- package/lib/components/Spinner.tsx +6 -2
- package/lib/components/Toast.tsx +89 -0
- package/lib/components/context/Field.tsx +27 -0
- package/lib/icons/Minus.tsx +24 -0
- package/lib/icons/Plus.tsx +23 -0
- package/lib/theme/Button.recipe.tsx +11 -1
- package/lib/theme/CircleProgress.recipe.tsx +3 -3
- package/lib/theme/Field.recipe.tsx +17 -2
- package/lib/theme/Input.recipe.tsx +12 -3
- package/lib/theme/NumberInput.recipe.tsx +9 -4
- package/lib/theme/RadioGroup.recipe.tsx +7 -1
- package/lib/theme/Select.recipe.tsx +7 -7
- package/lib/theme/Slider.recipe.tsx +366 -22
- package/lib/theme/Slideshow.recipe.tsx +1 -1
- package/lib/theme/SlidingDrawer.recipe.tsx +58 -4
- package/lib/theme/Toast.recipe.tsx +71 -0
- package/package.json +3 -2
- package/lib/components/NewSelect.tsx +0 -202
- package/lib/components/index.tsx +0 -83
- package/lib/components/layoutTest.tsx +0 -74
- package/lib/theme/Button.recipe-old.tsx +0 -67
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
4
|
+
useImperativeHandle,
|
|
5
|
+
useMemo,
|
|
6
|
+
} from 'react'
|
|
7
|
+
import {TouchableWithoutFeedback} from 'react-native'
|
|
8
|
+
import {Gesture, GestureDetector} from 'react-native-gesture-handler'
|
|
9
|
+
import Animated, {
|
|
10
|
+
measure,
|
|
11
|
+
SharedValue,
|
|
12
|
+
useAnimatedReaction,
|
|
13
|
+
useAnimatedRef,
|
|
14
|
+
useAnimatedStyle,
|
|
15
|
+
useSharedValue,
|
|
16
|
+
withSpring,
|
|
17
|
+
withTiming,
|
|
18
|
+
} from 'react-native-reanimated'
|
|
19
|
+
import {runOnUI, scheduleOnRN, scheduleOnUI} from 'react-native-worklets'
|
|
20
|
+
import {
|
|
21
|
+
SlidingDrawerTokens,
|
|
22
|
+
SlidingDrawerStyles,
|
|
23
|
+
} from '../theme/SlidingDrawer.recipe'
|
|
24
|
+
import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
25
|
+
import {
|
|
26
|
+
StyleSheet,
|
|
27
|
+
UnistylesRuntime,
|
|
28
|
+
UnistylesVariants,
|
|
29
|
+
} from 'react-native-unistyles'
|
|
30
|
+
import {HStack} from '../patterns'
|
|
31
|
+
|
|
32
|
+
/* -----------------------------
|
|
33
|
+
* Types
|
|
34
|
+
* ----------------------------*/
|
|
35
|
+
|
|
36
|
+
export type SlidingDrawerRef = {
|
|
37
|
+
expand: () => void | null
|
|
38
|
+
collapse: () => void | null
|
|
39
|
+
snapTo: (point: number) => void | null
|
|
40
|
+
isCollapsed: () => boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type SlidingDrawerVariants = UnistylesVariants<typeof SlidingDrawerStyles>
|
|
44
|
+
|
|
45
|
+
type DrawerContextType = SlidingDrawerVariants & {
|
|
46
|
+
colorPalette: PalettesWithNestedKeys
|
|
47
|
+
overlayOpacity: SharedValue<number>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type DrawerRootProps = SlidingDrawerVariants & {
|
|
51
|
+
colorPalette?: PalettesWithNestedKeys
|
|
52
|
+
children?: React.ReactNode
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* -----------------------------
|
|
56
|
+
* Context
|
|
57
|
+
* ----------------------------*/
|
|
58
|
+
|
|
59
|
+
const DrawerContext = createContext<DrawerContextType | null>(null)
|
|
60
|
+
const useDrawer = () => {
|
|
61
|
+
const ctx = useContext(DrawerContext)
|
|
62
|
+
if (!ctx)
|
|
63
|
+
throw new Error('Drawer subcomponents must be used within Drawer.Root')
|
|
64
|
+
return ctx
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* -----------------------------
|
|
68
|
+
* Root
|
|
69
|
+
* ----------------------------*/
|
|
70
|
+
|
|
71
|
+
const DrawerRoot = ({
|
|
72
|
+
colorPalette = 'accent',
|
|
73
|
+
variant = SlidingDrawerTokens.defaultProps.variant,
|
|
74
|
+
children,
|
|
75
|
+
}: DrawerRootProps) => {
|
|
76
|
+
SlidingDrawerStyles.useVariants({variant})
|
|
77
|
+
|
|
78
|
+
const overlayOpacity = useSharedValue(0)
|
|
79
|
+
const value = useMemo(
|
|
80
|
+
() => ({
|
|
81
|
+
colorPalette,
|
|
82
|
+
variant,
|
|
83
|
+
overlayOpacity,
|
|
84
|
+
}),
|
|
85
|
+
[colorPalette, variant],
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<DrawerContext.Provider value={value}>{children}</DrawerContext.Provider>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* -----------------------------
|
|
94
|
+
* Positioner
|
|
95
|
+
* ----------------------------*/
|
|
96
|
+
const DrawerPositioner = ({
|
|
97
|
+
children,
|
|
98
|
+
direction,
|
|
99
|
+
axis,
|
|
100
|
+
}: {
|
|
101
|
+
children?: React.ReactNode
|
|
102
|
+
direction: 1 | -1
|
|
103
|
+
axis: 'x' | 'y'
|
|
104
|
+
}) => {
|
|
105
|
+
const {variant} = useDrawer()
|
|
106
|
+
SlidingDrawerStyles.useVariants({variant})
|
|
107
|
+
|
|
108
|
+
type WithDirection = {direction?: 1 | -1; axis?: 'x' | 'y'}
|
|
109
|
+
|
|
110
|
+
const enhancedChildren = React.Children.map(children, child => {
|
|
111
|
+
if (React.isValidElement(child)) {
|
|
112
|
+
return React.cloneElement(child as React.ReactElement<WithDirection>, {
|
|
113
|
+
direction,
|
|
114
|
+
axis,
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
return child
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<HStack
|
|
122
|
+
style={[
|
|
123
|
+
styles.positioner,
|
|
124
|
+
SlidingDrawerStyles.positioner,
|
|
125
|
+
{
|
|
126
|
+
justifyContent:
|
|
127
|
+
axis === 'y'
|
|
128
|
+
? 'center'
|
|
129
|
+
: direction === 1
|
|
130
|
+
? 'flex-start'
|
|
131
|
+
: 'flex-end',
|
|
132
|
+
alignItems:
|
|
133
|
+
axis === 'x'
|
|
134
|
+
? 'center'
|
|
135
|
+
: direction === 1
|
|
136
|
+
? 'flex-start'
|
|
137
|
+
: 'flex-end',
|
|
138
|
+
},
|
|
139
|
+
]}>
|
|
140
|
+
{enhancedChildren}
|
|
141
|
+
</HStack>
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* -----------------------------
|
|
146
|
+
* Overlay
|
|
147
|
+
* ----------------------------*/
|
|
148
|
+
const AnimatedTouchable = Animated.createAnimatedComponent(
|
|
149
|
+
TouchableWithoutFeedback,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
const DrawerOverlay = ({onPress}: {onPress?: () => void}) => {
|
|
153
|
+
const {colorPalette, overlayOpacity, variant} = useDrawer()
|
|
154
|
+
SlidingDrawerStyles.useVariants({variant})
|
|
155
|
+
const visible = useSharedValue(0)
|
|
156
|
+
|
|
157
|
+
useAnimatedReaction(
|
|
158
|
+
() => overlayOpacity.value,
|
|
159
|
+
value => {
|
|
160
|
+
if (value === 0) {
|
|
161
|
+
visible.value = 0
|
|
162
|
+
} else {
|
|
163
|
+
visible.value = 1
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
const displayOverlayStyle = useAnimatedStyle(() => ({
|
|
169
|
+
opacity: withTiming(overlayOpacity.value, {duration: 50}),
|
|
170
|
+
display: visible.value === 0 ? 'none' : 'flex',
|
|
171
|
+
}))
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<AnimatedTouchable onPress={onPress}>
|
|
175
|
+
<Animated.View
|
|
176
|
+
style={[
|
|
177
|
+
StyleSheet.absoluteFillObject,
|
|
178
|
+
displayOverlayStyle,
|
|
179
|
+
SlidingDrawerStyles.overlay(colorPalette),
|
|
180
|
+
]}
|
|
181
|
+
/>
|
|
182
|
+
</AnimatedTouchable>
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* -----------------------------
|
|
187
|
+
* Slider (gestión independiente)
|
|
188
|
+
* ----------------------------*/
|
|
189
|
+
|
|
190
|
+
type InternalDrawerSliderProps = {
|
|
191
|
+
axis: 'x' | 'y'
|
|
192
|
+
direction: 1 | -1
|
|
193
|
+
lockAtEdges?: boolean
|
|
194
|
+
snapPoints?: number[] | ('hidden' | 'content')[]
|
|
195
|
+
animation?: keyof typeof SlidingDrawerTokens.variants.animation
|
|
196
|
+
onExpand?: () => void
|
|
197
|
+
onCollapse?: () => void
|
|
198
|
+
onSnap?: (point: number) => void
|
|
199
|
+
allowGestures?: boolean
|
|
200
|
+
children?: React.ReactNode
|
|
201
|
+
ref?: React.RefObject<SlidingDrawerRef | null>
|
|
202
|
+
externalTranslate?: SharedValue<number>
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export type DrawerSliderProps = Omit<
|
|
206
|
+
InternalDrawerSliderProps,
|
|
207
|
+
'direction' | 'axis'
|
|
208
|
+
>
|
|
209
|
+
|
|
210
|
+
export const DrawerSlider = (props: DrawerSliderProps) => {
|
|
211
|
+
return <DrawerSliderInternal {...(props as InternalDrawerSliderProps)} />
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const DrawerSliderInternal = ({
|
|
215
|
+
axis,
|
|
216
|
+
direction,
|
|
217
|
+
lockAtEdges = false,
|
|
218
|
+
snapPoints = ['hidden', 'content'],
|
|
219
|
+
animation = SlidingDrawerTokens.defaultProps.animation,
|
|
220
|
+
onExpand,
|
|
221
|
+
onCollapse,
|
|
222
|
+
onSnap,
|
|
223
|
+
allowGestures = true,
|
|
224
|
+
children,
|
|
225
|
+
externalTranslate,
|
|
226
|
+
ref,
|
|
227
|
+
}: InternalDrawerSliderProps) => {
|
|
228
|
+
const {variant, colorPalette, overlayOpacity} = useDrawer()
|
|
229
|
+
|
|
230
|
+
SlidingDrawerStyles.useVariants({variant})
|
|
231
|
+
|
|
232
|
+
const screenHeight =
|
|
233
|
+
UnistylesRuntime.screen.height - UnistylesRuntime.insets.top
|
|
234
|
+
const screenWidth = UnistylesRuntime.screen.width
|
|
235
|
+
|
|
236
|
+
const animations = {withSpring, withTiming}
|
|
237
|
+
const animationVariant = SlidingDrawerTokens.variants.animation[animation]
|
|
238
|
+
const VELOCITY_THRESHOLD = 2000
|
|
239
|
+
|
|
240
|
+
const viewRef = useAnimatedRef<Animated.View>()
|
|
241
|
+
const translate = useSharedValue(screenHeight)
|
|
242
|
+
const context = useSharedValue({position: screenHeight, snapPoint: 0})
|
|
243
|
+
const contentHeight = useSharedValue(0)
|
|
244
|
+
const resolvedSnapPoints = useSharedValue<number[]>([])
|
|
245
|
+
|
|
246
|
+
if (externalTranslate) {
|
|
247
|
+
useAnimatedReaction(
|
|
248
|
+
() => translate.value,
|
|
249
|
+
value => {
|
|
250
|
+
externalTranslate.value = value
|
|
251
|
+
},
|
|
252
|
+
)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const onLayout = () => {
|
|
256
|
+
const _screenHeight = screenHeight
|
|
257
|
+
const _screenWidth = screenWidth
|
|
258
|
+
const _axis = axis
|
|
259
|
+
const _direction = direction
|
|
260
|
+
const _snapPoints = snapPoints
|
|
261
|
+
|
|
262
|
+
scheduleOnUI(() => {
|
|
263
|
+
'worklet'
|
|
264
|
+
const measured = measure(viewRef)
|
|
265
|
+
if (measured) {
|
|
266
|
+
const {height, width} = measured
|
|
267
|
+
const size = _axis === 'y' ? height : width
|
|
268
|
+
const screenSize = _axis === 'y' ? _screenHeight : _screenWidth
|
|
269
|
+
|
|
270
|
+
const resolved = _snapPoints.map(p => {
|
|
271
|
+
if (p === 'hidden') return screenSize * _direction
|
|
272
|
+
if (p === 'content') return (screenSize - size) * _direction
|
|
273
|
+
return (p as number) * _direction
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
resolvedSnapPoints.value = resolved
|
|
277
|
+
translate.value = resolved[0]
|
|
278
|
+
context.value = {position: resolved[0], snapPoint: 0}
|
|
279
|
+
}
|
|
280
|
+
})
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const getPoints = () => {
|
|
284
|
+
'worklet'
|
|
285
|
+
return resolvedSnapPoints.value.length > 0
|
|
286
|
+
? resolvedSnapPoints.value
|
|
287
|
+
: snapPoints.map(p => {
|
|
288
|
+
// if (p === 'hidden') return screenHeight * direction
|
|
289
|
+
// if (p === 'content') return (screenHeight - contentHeight.value) * direction
|
|
290
|
+
return (p as number) * direction
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const updateCurrentSnapPoint = (snapPoint: number) => {
|
|
295
|
+
'worklet'
|
|
296
|
+
context.value = {position: context.value.position, snapPoint}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const snapTo = (destination: number) => {
|
|
300
|
+
'worklet'
|
|
301
|
+
const points = getPoints()
|
|
302
|
+
const point = points[destination]
|
|
303
|
+
if (animationVariant?.type && point != null) {
|
|
304
|
+
translate.value = animations[animationVariant.type](
|
|
305
|
+
point,
|
|
306
|
+
animationVariant.props,
|
|
307
|
+
)
|
|
308
|
+
updateCurrentSnapPoint(destination)
|
|
309
|
+
onSnap && scheduleOnRN(onSnap, destination)
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const isCollapsed = () => {
|
|
314
|
+
'worklet'
|
|
315
|
+
return context.value.snapPoint === 0
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const showOverlay = () => {
|
|
319
|
+
'worklet'
|
|
320
|
+
overlayOpacity.value = withTiming(1, {duration: 200})
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const hideOverlay = () => {
|
|
324
|
+
'worklet'
|
|
325
|
+
overlayOpacity.value = withTiming(0, {duration: 200})
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const expand = () => {
|
|
329
|
+
const points = getPoints()
|
|
330
|
+
snapTo(points.length - 1)
|
|
331
|
+
showOverlay()
|
|
332
|
+
onExpand && scheduleOnRN(onExpand)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const collapse = () => {
|
|
336
|
+
snapTo(0)
|
|
337
|
+
hideOverlay()
|
|
338
|
+
onCollapse && scheduleOnRN(onCollapse)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
useImperativeHandle(ref, () => ({
|
|
342
|
+
expand,
|
|
343
|
+
collapse,
|
|
344
|
+
snapTo,
|
|
345
|
+
isCollapsed,
|
|
346
|
+
}))
|
|
347
|
+
|
|
348
|
+
useAnimatedReaction(
|
|
349
|
+
() => translate.value,
|
|
350
|
+
value => {
|
|
351
|
+
const points = getPoints()
|
|
352
|
+
if (points.length < 2) return
|
|
353
|
+
|
|
354
|
+
const collapsed = points[0]
|
|
355
|
+
const next = points[1] ?? collapsed
|
|
356
|
+
const threshold = 20
|
|
357
|
+
const opensUpward = next < collapsed
|
|
358
|
+
const delta = value - collapsed
|
|
359
|
+
const isExpanded = opensUpward ? delta < -threshold : delta > threshold
|
|
360
|
+
|
|
361
|
+
overlayOpacity.value = withTiming(isExpanded ? 1 : 0, {duration: 150})
|
|
362
|
+
},
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
const slideGesture = Gesture.Pan()
|
|
366
|
+
.enabled(allowGestures)
|
|
367
|
+
.onBegin(() => {
|
|
368
|
+
context.value.position = translate.value
|
|
369
|
+
})
|
|
370
|
+
.onUpdate(event => {
|
|
371
|
+
const delta = axis === 'y' ? event.translationY : event.translationX
|
|
372
|
+
const proposed = delta + (context.value.position ?? 0)
|
|
373
|
+
const points = getPoints()
|
|
374
|
+
const minPoint = Math.min(...points)
|
|
375
|
+
const maxPoint = Math.max(...points)
|
|
376
|
+
let clamped = proposed
|
|
377
|
+
|
|
378
|
+
if (proposed < minPoint) {
|
|
379
|
+
if (lockAtEdges) {
|
|
380
|
+
clamped = minPoint
|
|
381
|
+
} else {
|
|
382
|
+
const overdrag = minPoint - proposed
|
|
383
|
+
clamped = minPoint - overdrag / (1 + overdrag / 60)
|
|
384
|
+
}
|
|
385
|
+
} else if (proposed > maxPoint) {
|
|
386
|
+
if (lockAtEdges) {
|
|
387
|
+
clamped = maxPoint
|
|
388
|
+
} else {
|
|
389
|
+
const overdrag = proposed - maxPoint
|
|
390
|
+
clamped = maxPoint + overdrag / (1 + overdrag / 60)
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
translate.value = clamped
|
|
395
|
+
})
|
|
396
|
+
.onEnd(({velocityX, velocityY, translationX, translationY}) => {
|
|
397
|
+
const velocity = axis === 'y' ? velocityY : velocityX
|
|
398
|
+
const translation = axis === 'y' ? translationY : translationX
|
|
399
|
+
const points = getPoints()
|
|
400
|
+
|
|
401
|
+
const minPoint = Math.min(...points)
|
|
402
|
+
const maxPoint = Math.max(...points)
|
|
403
|
+
|
|
404
|
+
if (translate.value < minPoint) {
|
|
405
|
+
translate.value = withSpring(minPoint, {velocity})
|
|
406
|
+
return
|
|
407
|
+
} else if (translate.value > maxPoint) {
|
|
408
|
+
translate.value = withSpring(maxPoint, {velocity})
|
|
409
|
+
return
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const forwardsThreshold =
|
|
413
|
+
(points[context.value.snapPoint] +
|
|
414
|
+
points[context.value.snapPoint + 1]) /
|
|
415
|
+
2
|
|
416
|
+
const backwardsThreshold =
|
|
417
|
+
(points[context.value.snapPoint] +
|
|
418
|
+
points[context.value.snapPoint - 1]) /
|
|
419
|
+
2
|
|
420
|
+
|
|
421
|
+
if (translation * direction < 0) {
|
|
422
|
+
if (
|
|
423
|
+
((direction === 1 && translate.value < forwardsThreshold) ||
|
|
424
|
+
(direction === -1 && translate.value > forwardsThreshold) ||
|
|
425
|
+
velocity * direction < -VELOCITY_THRESHOLD) &&
|
|
426
|
+
context.value.snapPoint < points.length - 1
|
|
427
|
+
) {
|
|
428
|
+
snapTo(context.value.snapPoint + 1)
|
|
429
|
+
} else {
|
|
430
|
+
snapTo(context.value.snapPoint)
|
|
431
|
+
}
|
|
432
|
+
} else {
|
|
433
|
+
if (
|
|
434
|
+
((direction === 1 && translate.value > backwardsThreshold) ||
|
|
435
|
+
(direction === -1 && translate.value < backwardsThreshold) ||
|
|
436
|
+
velocity * direction > VELOCITY_THRESHOLD) &&
|
|
437
|
+
context.value.snapPoint > 0
|
|
438
|
+
) {
|
|
439
|
+
snapTo(context.value.snapPoint - 1)
|
|
440
|
+
} else {
|
|
441
|
+
snapTo(context.value.snapPoint)
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
})
|
|
445
|
+
|
|
446
|
+
const blockAnimatedStyle = useAnimatedStyle(() => {
|
|
447
|
+
return {
|
|
448
|
+
transform: [
|
|
449
|
+
axis === 'y'
|
|
450
|
+
? {translateY: translate.value}
|
|
451
|
+
: {translateX: translate.value},
|
|
452
|
+
],
|
|
453
|
+
}
|
|
454
|
+
})
|
|
455
|
+
|
|
456
|
+
return (
|
|
457
|
+
<GestureDetector gesture={slideGesture}>
|
|
458
|
+
<Animated.View
|
|
459
|
+
ref={viewRef}
|
|
460
|
+
onLayout={onLayout}
|
|
461
|
+
style={[
|
|
462
|
+
styles.slider,
|
|
463
|
+
blockAnimatedStyle,
|
|
464
|
+
SlidingDrawerStyles.slider(colorPalette),
|
|
465
|
+
]}>
|
|
466
|
+
{children}
|
|
467
|
+
</Animated.View>
|
|
468
|
+
</GestureDetector>
|
|
469
|
+
)
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
export const Drawer = {
|
|
473
|
+
Root: DrawerRoot,
|
|
474
|
+
Positioner: DrawerPositioner,
|
|
475
|
+
Overlay: DrawerOverlay,
|
|
476
|
+
Slider: DrawerSlider,
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const styles = StyleSheet.create((theme, rt) => ({
|
|
480
|
+
positioner: {
|
|
481
|
+
flex: 1,
|
|
482
|
+
alignSelf: 'stretch',
|
|
483
|
+
position: 'absolute',
|
|
484
|
+
top: 0,
|
|
485
|
+
left: 0,
|
|
486
|
+
right: 0,
|
|
487
|
+
bottom: 0,
|
|
488
|
+
},
|
|
489
|
+
slider: {
|
|
490
|
+
flex: 1,
|
|
491
|
+
alignSelf: 'stretch',
|
|
492
|
+
alignItems: 'center',
|
|
493
|
+
justifyContent: 'flex-start',
|
|
494
|
+
zIndex: 100,
|
|
495
|
+
},
|
|
496
|
+
}))
|
package/lib/components/Field.tsx
CHANGED
|
@@ -1,36 +1,21 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {UnistylesVariants} from 'react-native-unistyles'
|
|
1
|
+
import React from 'react'
|
|
3
2
|
import Text from './Text'
|
|
4
|
-
import {VStack} from '../patterns'
|
|
5
3
|
import {DefaultFieldVariants, FieldStyles} from '../theme/Field.recipe'
|
|
6
|
-
import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
colorPalette?: PalettesWithNestedKeys
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const FieldContext = createContext<FieldContextType | undefined>(undefined)
|
|
18
|
-
|
|
19
|
-
function useField() {
|
|
20
|
-
const context = useContext(FieldContext)
|
|
21
|
-
if (!context) {
|
|
22
|
-
throw new Error(
|
|
23
|
-
'Field subcomponents (Label, Error) must be used inside Field.Root',
|
|
24
|
-
)
|
|
25
|
-
}
|
|
26
|
-
return context
|
|
27
|
-
}
|
|
4
|
+
import {Flex, PalettesWithNestedKeys} from '../style/varia/types'
|
|
5
|
+
import FieldContext, {
|
|
6
|
+
FieldContextType,
|
|
7
|
+
FieldVariants,
|
|
8
|
+
useField,
|
|
9
|
+
} from './context/Field'
|
|
10
|
+
import {StyleProp, View, ViewStyle} from 'react-native'
|
|
11
|
+
import {StyleSheet} from 'react-native-unistyles'
|
|
28
12
|
|
|
29
13
|
type FieldRootProps = FieldVariants & {
|
|
30
14
|
children: React.ReactNode
|
|
31
15
|
error?: string
|
|
32
16
|
colorPalette?: PalettesWithNestedKeys
|
|
33
17
|
flex?: number
|
|
18
|
+
style?: StyleProp<ViewStyle>
|
|
34
19
|
}
|
|
35
20
|
|
|
36
21
|
const FieldRoot = ({
|
|
@@ -39,7 +24,8 @@ const FieldRoot = ({
|
|
|
39
24
|
variant = DefaultFieldVariants.variant,
|
|
40
25
|
size = DefaultFieldVariants.size,
|
|
41
26
|
colorPalette = 'accent',
|
|
42
|
-
flex =
|
|
27
|
+
flex = 0,
|
|
28
|
+
style,
|
|
43
29
|
}: FieldRootProps) => {
|
|
44
30
|
FieldStyles.useVariants({size})
|
|
45
31
|
|
|
@@ -53,20 +39,16 @@ const FieldRoot = ({
|
|
|
53
39
|
FieldStyles.useVariants({variant, size})
|
|
54
40
|
|
|
55
41
|
return (
|
|
56
|
-
<
|
|
42
|
+
<View
|
|
57
43
|
style={[
|
|
58
|
-
|
|
59
|
-
flexShrink: 1,
|
|
60
|
-
flexGrow: flex,
|
|
61
|
-
alignItems: 'stretch',
|
|
62
|
-
alignSelf: 'stretch',
|
|
63
|
-
},
|
|
44
|
+
styles.root(flex),
|
|
64
45
|
FieldStyles.root(colorPalette),
|
|
46
|
+
style && style,
|
|
65
47
|
]}>
|
|
66
48
|
<FieldContext.Provider value={contextValue}>
|
|
67
49
|
{children}
|
|
68
50
|
</FieldContext.Provider>
|
|
69
|
-
</
|
|
51
|
+
</View>
|
|
70
52
|
)
|
|
71
53
|
}
|
|
72
54
|
|
|
@@ -89,11 +71,7 @@ const FieldLabel = ({children, ...props}: FieldLabelProps) => {
|
|
|
89
71
|
|
|
90
72
|
FieldStyles.useVariants({variant, size})
|
|
91
73
|
|
|
92
|
-
return (
|
|
93
|
-
<Text size={size} color={FieldStyles.label(colorPalette).color}>
|
|
94
|
-
{children}
|
|
95
|
-
</Text>
|
|
96
|
-
)
|
|
74
|
+
return <Text style={FieldStyles.label(colorPalette)}>{children}</Text>
|
|
97
75
|
}
|
|
98
76
|
|
|
99
77
|
type FieldErrorProps = {
|
|
@@ -124,6 +102,13 @@ const FieldError = ({...props}: FieldErrorProps) => {
|
|
|
124
102
|
)
|
|
125
103
|
}
|
|
126
104
|
|
|
105
|
+
const styles = StyleSheet.create({
|
|
106
|
+
root: (flex: Flex) => ({
|
|
107
|
+
flex,
|
|
108
|
+
flexDirection: 'column',
|
|
109
|
+
}),
|
|
110
|
+
})
|
|
111
|
+
|
|
127
112
|
export const Field = Object.assign(FieldRoot, {
|
|
128
113
|
Root: FieldRoot,
|
|
129
114
|
Label: FieldLabel,
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import {View,
|
|
1
|
+
import {View, StyleProp, ViewStyle} from 'react-native'
|
|
2
2
|
import Svg, {Defs, LinearGradient, Stop, Rect} from 'react-native-svg'
|
|
3
3
|
import {withUnistyles} from 'react-native-unistyles'
|
|
4
4
|
import {gradientBackgroundTokens} from '../theme/GradientBackground.recipe'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
NestedColorsType,
|
|
7
|
+
PalettesWithNestedKeys,
|
|
8
|
+
ThemeColors,
|
|
9
|
+
} from '../style/varia/types'
|
|
6
10
|
import {resolveColor} from '../style/varia/utils'
|
|
11
|
+
import {StyleSheet} from 'react-native-unistyles'
|
|
7
12
|
|
|
8
13
|
interface GradientBackgroundProps {
|
|
9
14
|
colorPalette?: PalettesWithNestedKeys
|
|
10
15
|
variant?: keyof typeof gradientBackgroundTokens.variants.variant
|
|
11
16
|
direction?: keyof typeof gradientBackgroundTokens.variants.direction
|
|
12
17
|
containerStyles?: StyleProp<ViewStyle>
|
|
13
|
-
colors:
|
|
18
|
+
colors: NestedColorsType
|
|
19
|
+
startColor?: ThemeColors
|
|
20
|
+
endColor?: ThemeColors
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
const BaseGradientBackground = ({
|
|
@@ -19,10 +26,20 @@ const BaseGradientBackground = ({
|
|
|
19
26
|
direction = gradientBackgroundTokens.defaultProps.direction,
|
|
20
27
|
containerStyles,
|
|
21
28
|
colors,
|
|
29
|
+
startColor,
|
|
30
|
+
endColor,
|
|
22
31
|
}: GradientBackgroundProps) => {
|
|
23
32
|
const colorValue = gradientBackgroundTokens.variants.variant[variant]
|
|
24
|
-
const
|
|
25
|
-
|
|
33
|
+
const resolvedStartColor = resolveColor(
|
|
34
|
+
startColor || colorValue.startColor,
|
|
35
|
+
colors,
|
|
36
|
+
colorPalette,
|
|
37
|
+
)
|
|
38
|
+
const resolvedEndColor = resolveColor(
|
|
39
|
+
endColor || colorValue.endColor,
|
|
40
|
+
colors,
|
|
41
|
+
colorPalette,
|
|
42
|
+
)
|
|
26
43
|
|
|
27
44
|
const directionVariant =
|
|
28
45
|
gradientBackgroundTokens.variants.direction[direction]
|
|
@@ -41,8 +58,8 @@ const BaseGradientBackground = ({
|
|
|
41
58
|
y1={directionVariant?.y1}
|
|
42
59
|
x2={directionVariant?.x2}
|
|
43
60
|
y2={directionVariant?.y2}>
|
|
44
|
-
<Stop offset="0%" stopColor={
|
|
45
|
-
<Stop offset="100%" stopColor={
|
|
61
|
+
<Stop offset="0%" stopColor={resolvedStartColor} stopOpacity="1" />
|
|
62
|
+
<Stop offset="100%" stopColor={resolvedEndColor} stopOpacity="1" />
|
|
46
63
|
</LinearGradient>
|
|
47
64
|
</Defs>
|
|
48
65
|
<Rect width="100" height="100" fill="url(#grad)" />
|
|
@@ -54,6 +71,7 @@ const BaseGradientBackground = ({
|
|
|
54
71
|
const styles = StyleSheet.create({
|
|
55
72
|
container: {
|
|
56
73
|
...StyleSheet.absoluteFillObject,
|
|
74
|
+
alignSelf: 'stretch',
|
|
57
75
|
borderWidth: 0,
|
|
58
76
|
overflow: 'hidden',
|
|
59
77
|
borderColor: 'transparent',
|