@wireservers-ui/react-natives 1.0.0-rc.1 → 1.0.0-rc.3
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 +7 -1
- package/src/button/styles.ts +1 -1
- package/src/carousel/carousel.tsx +136 -60
- package/src/carousel/types.ts +10 -0
- package/src/divider/styles.ts +1 -1
- package/tailwind-preset.js +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wireservers-ui/react-natives",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.3",
|
|
4
4
|
"description": "70+ production-ready React Native components — TypeScript-first, themeable, accessible. Created by WireServers-UI.",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -48,6 +48,12 @@
|
|
|
48
48
|
"react-native-svg": ">=13"
|
|
49
49
|
},
|
|
50
50
|
"peerDependenciesMeta": {
|
|
51
|
+
"nativewind": {
|
|
52
|
+
"optional": true
|
|
53
|
+
},
|
|
54
|
+
"tailwind-variants": {
|
|
55
|
+
"optional": true
|
|
56
|
+
},
|
|
51
57
|
"react-native-reanimated": {
|
|
52
58
|
"optional": true
|
|
53
59
|
},
|
package/src/button/styles.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { tv } from 'tailwind-variants';
|
|
2
2
|
|
|
3
3
|
export const buttonStyle = tv({
|
|
4
|
-
base: 'group/button rounded bg-primary-500 self-start flex-row items-center justify-center data-[focus-visible=true]:web:outline-none data-[focus-visible=true]:web:ring-2 data-[disabled=true]:opacity-40 gap-2',
|
|
4
|
+
base: 'group/button overflow-visible rounded bg-primary-500 self-start flex-row items-center justify-center data-[focus-visible=true]:web:outline-none data-[focus-visible=true]:web:ring-2 data-[disabled=true]:opacity-40 gap-2',
|
|
5
5
|
variants: {
|
|
6
6
|
action: {
|
|
7
7
|
primary:
|
|
@@ -7,7 +7,7 @@ import { carouselStyle, carouselContentStyle, carouselItemStyle, carouselPreviou
|
|
|
7
7
|
export const [CarouselProvider, useCarouselContext] = createComponentContext<CarouselContextValue>('Carousel');
|
|
8
8
|
|
|
9
9
|
export const Carousel = React.forwardRef<React.ElementRef<typeof View>, CarouselProps>(
|
|
10
|
-
({ className, defaultIndex = 0, loop = false, onIndexChange, children, ...props }, ref) => {
|
|
10
|
+
({ className, defaultIndex = 0, loop = false, onIndexChange, itemWidth: itemWidthProp = 0, gap: gapProp = 0, autoPlay = false, autoPlayInterval = 3000, children, ...props }, ref) => {
|
|
11
11
|
const [activeIndex, _setActiveIndex] = useState(defaultIndex);
|
|
12
12
|
const [itemCount, setItemCount] = useState(0);
|
|
13
13
|
const [width, setWidth] = useState(0);
|
|
@@ -17,7 +17,12 @@ export const Carousel = React.forwardRef<React.ElementRef<typeof View>, Carousel
|
|
|
17
17
|
const animX = useRef(new Animated.Value(0)).current;
|
|
18
18
|
const animXValueRef = useRef(0);
|
|
19
19
|
|
|
20
|
-
//
|
|
20
|
+
// Keep prop refs stable for callbacks
|
|
21
|
+
const itemWidthRef = useRef(itemWidthProp);
|
|
22
|
+
itemWidthRef.current = itemWidthProp;
|
|
23
|
+
const gapRef = useRef(gapProp);
|
|
24
|
+
gapRef.current = gapProp;
|
|
25
|
+
|
|
21
26
|
useEffect(() => {
|
|
22
27
|
const id = animX.addListener(({ value }) => { animXValueRef.current = value; });
|
|
23
28
|
return () => animX.removeListener(id);
|
|
@@ -29,9 +34,27 @@ export const Carousel = React.forwardRef<React.ElementRef<typeof View>, Carousel
|
|
|
29
34
|
onIndexChange?.(index);
|
|
30
35
|
}, [onIndexChange]);
|
|
31
36
|
|
|
37
|
+
/** step = distance between one item start and the next */
|
|
38
|
+
const getStep = useCallback(() => {
|
|
39
|
+
const iw = itemWidthRef.current;
|
|
40
|
+
return iw > 0 ? iw + gapRef.current : widthRef.current;
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
/** How many items to clone on each side for seamless loop */
|
|
44
|
+
const getCloneCount = useCallback(() => {
|
|
45
|
+
const iw = itemWidthRef.current;
|
|
46
|
+
if (!loop) return 0;
|
|
47
|
+
if (iw > 0) {
|
|
48
|
+
const step = iw + gapRef.current;
|
|
49
|
+
return step > 0 ? Math.ceil(widthRef.current / step) + 1 : 1;
|
|
50
|
+
}
|
|
51
|
+
return 1;
|
|
52
|
+
}, [loop]);
|
|
53
|
+
|
|
32
54
|
const goTo = useCallback((index: number, animate = true) => {
|
|
33
|
-
const
|
|
34
|
-
const
|
|
55
|
+
const step = getStep();
|
|
56
|
+
const clones = getCloneCount();
|
|
57
|
+
const targetX = loop ? -(index + clones) * step : -index * step;
|
|
35
58
|
setActiveIndex(index);
|
|
36
59
|
if (animate) {
|
|
37
60
|
Animated.timing(animX, { toValue: targetX, duration: 300, useNativeDriver: true }).start();
|
|
@@ -39,18 +62,20 @@ export const Carousel = React.forwardRef<React.ElementRef<typeof View>, Carousel
|
|
|
39
62
|
animX.setValue(targetX);
|
|
40
63
|
animXValueRef.current = targetX;
|
|
41
64
|
}
|
|
42
|
-
}, [loop, animX, setActiveIndex]);
|
|
65
|
+
}, [loop, animX, setActiveIndex, getStep, getCloneCount]);
|
|
43
66
|
|
|
44
67
|
const next = useCallback(() => {
|
|
45
68
|
const count = itemCountRef.current;
|
|
46
|
-
const
|
|
69
|
+
const step = getStep();
|
|
70
|
+
const clones = getCloneCount();
|
|
47
71
|
if (loop) {
|
|
48
72
|
const nextIdx = activeIndexRef.current + 1;
|
|
49
73
|
if (nextIdx >= count) {
|
|
50
|
-
// Animate into clone
|
|
51
|
-
Animated.timing(animX, { toValue: -(count +
|
|
52
|
-
|
|
53
|
-
|
|
74
|
+
// Animate into first clone zone, then jump to real first
|
|
75
|
+
Animated.timing(animX, { toValue: -(count + clones) * step, duration: 300, useNativeDriver: true }).start(() => {
|
|
76
|
+
const jumpX = -clones * step;
|
|
77
|
+
animX.setValue(jumpX);
|
|
78
|
+
animXValueRef.current = jumpX;
|
|
54
79
|
setActiveIndex(0);
|
|
55
80
|
});
|
|
56
81
|
} else {
|
|
@@ -59,18 +84,20 @@ export const Carousel = React.forwardRef<React.ElementRef<typeof View>, Carousel
|
|
|
59
84
|
} else {
|
|
60
85
|
goTo(Math.min(activeIndexRef.current + 1, count - 1));
|
|
61
86
|
}
|
|
62
|
-
}, [loop, animX, goTo, setActiveIndex]);
|
|
87
|
+
}, [loop, animX, goTo, setActiveIndex, getStep, getCloneCount]);
|
|
63
88
|
|
|
64
89
|
const previous = useCallback(() => {
|
|
65
90
|
const count = itemCountRef.current;
|
|
66
|
-
const
|
|
91
|
+
const step = getStep();
|
|
92
|
+
const clones = getCloneCount();
|
|
67
93
|
if (loop) {
|
|
68
94
|
const prevIdx = activeIndexRef.current - 1;
|
|
69
95
|
if (prevIdx < 0) {
|
|
70
|
-
// Animate into clone
|
|
71
|
-
Animated.timing(animX, { toValue:
|
|
72
|
-
|
|
73
|
-
|
|
96
|
+
// Animate into last clone zone, then jump to real last
|
|
97
|
+
Animated.timing(animX, { toValue: -(clones - 1) * step, duration: 300, useNativeDriver: true }).start(() => {
|
|
98
|
+
const jumpX = -(count - 1 + clones) * step;
|
|
99
|
+
animX.setValue(jumpX);
|
|
100
|
+
animXValueRef.current = jumpX;
|
|
74
101
|
setActiveIndex(count - 1);
|
|
75
102
|
});
|
|
76
103
|
} else {
|
|
@@ -79,10 +106,17 @@ export const Carousel = React.forwardRef<React.ElementRef<typeof View>, Carousel
|
|
|
79
106
|
} else {
|
|
80
107
|
goTo(Math.max(activeIndexRef.current - 1, 0));
|
|
81
108
|
}
|
|
82
|
-
}, [loop, animX, goTo, setActiveIndex]);
|
|
109
|
+
}, [loop, animX, goTo, setActiveIndex, getStep, getCloneCount]);
|
|
110
|
+
|
|
111
|
+
// Auto-play
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (!autoPlay || itemCountRef.current === 0) return;
|
|
114
|
+
const id = setInterval(() => { next(); }, autoPlayInterval);
|
|
115
|
+
return () => clearInterval(id);
|
|
116
|
+
}, [autoPlay, autoPlayInterval, next]);
|
|
83
117
|
|
|
84
118
|
return (
|
|
85
|
-
<CarouselProvider value={{ activeIndex, setActiveIndex, activeIndexRef, itemCount, setItemCount, itemCountRef, loop, width, setWidth, widthRef, animX, animXValueRef, goTo, next, previous }}>
|
|
119
|
+
<CarouselProvider value={{ activeIndex, setActiveIndex, activeIndexRef, itemCount, setItemCount, itemCountRef, loop, width, setWidth, widthRef, animX, animXValueRef, goTo, next, previous, itemWidth: itemWidthProp, gap: gapProp }}>
|
|
86
120
|
<View ref={ref} className={carouselStyle({ class: className })} {...props}>{children}</View>
|
|
87
121
|
</CarouselProvider>
|
|
88
122
|
);
|
|
@@ -91,16 +125,19 @@ export const Carousel = React.forwardRef<React.ElementRef<typeof View>, Carousel
|
|
|
91
125
|
Carousel.displayName = 'Carousel';
|
|
92
126
|
|
|
93
127
|
export const CarouselContent = React.forwardRef<React.ElementRef<typeof View>, CarouselContentProps>(({ className, children, style, ...props }, ref) => {
|
|
94
|
-
const { setWidth, setItemCount, itemCountRef, loop, setActiveIndex, activeIndexRef, animX, animXValueRef, widthRef } = useCarouselContext();
|
|
128
|
+
const { setWidth, setItemCount, itemCountRef, loop, setActiveIndex, activeIndexRef, animX, animXValueRef, widthRef, itemWidth: itemWidthProp, gap: gapProp } = useCarouselContext();
|
|
95
129
|
const dragStartValue = useRef(0);
|
|
96
130
|
const dragStartIndex = useRef(0);
|
|
97
131
|
const internalRef = useRef<View>(null);
|
|
98
132
|
|
|
99
|
-
// Keep mutable refs for values used in gesture callbacks
|
|
100
133
|
const loopRef = useRef(loop);
|
|
101
134
|
loopRef.current = loop;
|
|
102
135
|
const setActiveIndexRef = useRef(setActiveIndex);
|
|
103
136
|
setActiveIndexRef.current = setActiveIndex;
|
|
137
|
+
const itemWidthRef = useRef(itemWidthProp);
|
|
138
|
+
itemWidthRef.current = itemWidthProp;
|
|
139
|
+
const gapRef = useRef(gapProp);
|
|
140
|
+
gapRef.current = gapProp;
|
|
104
141
|
|
|
105
142
|
const childArray = React.Children.toArray(children);
|
|
106
143
|
const count = childArray.length;
|
|
@@ -109,27 +146,58 @@ export const CarouselContent = React.forwardRef<React.ElementRef<typeof View>, C
|
|
|
109
146
|
itemCountRef.current = count;
|
|
110
147
|
}, [count]);
|
|
111
148
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
?
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
149
|
+
const getStep = () => {
|
|
150
|
+
const iw = itemWidthRef.current;
|
|
151
|
+
return iw > 0 ? iw + gapRef.current : widthRef.current;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const getCloneCount = () => {
|
|
155
|
+
const iw = itemWidthRef.current;
|
|
156
|
+
if (!loopRef.current) return 0;
|
|
157
|
+
if (iw > 0) {
|
|
158
|
+
const step = iw + gapRef.current;
|
|
159
|
+
return step > 0 ? Math.ceil(widthRef.current / step) + 1 : 1;
|
|
160
|
+
}
|
|
161
|
+
return 1;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Build displayed children with clones for loop mode
|
|
165
|
+
const cloneCount = getCloneCount();
|
|
166
|
+
let displayedChildren: React.ReactNode;
|
|
167
|
+
if (loop && count > 0 && cloneCount > 0) {
|
|
168
|
+
const leadClones: React.ReactElement[] = [];
|
|
169
|
+
const trailClones: React.ReactElement[] = [];
|
|
170
|
+
for (let i = 0; i < cloneCount; i++) {
|
|
171
|
+
// Lead clones: last `cloneCount` items
|
|
172
|
+
const leadIdx = ((count - cloneCount + i) % count + count) % count;
|
|
173
|
+
leadClones.push(
|
|
174
|
+
React.cloneElement(childArray[leadIdx] as React.ReactElement, { key: `__clone-lead-${i}__` }),
|
|
175
|
+
);
|
|
176
|
+
// Trail clones: first `cloneCount` items
|
|
177
|
+
const trailIdx = i % count;
|
|
178
|
+
trailClones.push(
|
|
179
|
+
React.cloneElement(childArray[trailIdx] as React.ReactElement, { key: `__clone-trail-${i}__` }),
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
displayedChildren = [...leadClones, ...childArray, ...trailClones];
|
|
183
|
+
} else {
|
|
184
|
+
displayedChildren = children;
|
|
185
|
+
}
|
|
120
186
|
|
|
121
187
|
const handleLayout = (e: LayoutChangeEvent) => {
|
|
122
188
|
const w = e.nativeEvent.layout.width;
|
|
123
189
|
widthRef.current = w;
|
|
124
190
|
setWidth(w);
|
|
125
191
|
if (loop && w > 0) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
192
|
+
const step = getStep();
|
|
193
|
+
const clones = getCloneCount();
|
|
194
|
+
const initialX = -clones * step;
|
|
195
|
+
animX.setValue(initialX);
|
|
196
|
+
animXValueRef.current = initialX;
|
|
129
197
|
}
|
|
130
198
|
};
|
|
131
199
|
|
|
132
|
-
// --- Shared gesture helpers
|
|
200
|
+
// --- Shared gesture helpers ---
|
|
133
201
|
const gestureStart = () => {
|
|
134
202
|
animX.stopAnimation();
|
|
135
203
|
dragStartValue.current = animXValueRef.current;
|
|
@@ -137,60 +205,67 @@ export const CarouselContent = React.forwardRef<React.ElementRef<typeof View>, C
|
|
|
137
205
|
};
|
|
138
206
|
|
|
139
207
|
const gestureMove = (dx: number) => {
|
|
140
|
-
const
|
|
141
|
-
const clamped = Math.max(-
|
|
208
|
+
const step = getStep();
|
|
209
|
+
const clamped = Math.max(-step, Math.min(step, dx));
|
|
142
210
|
animX.setValue(dragStartValue.current + clamped);
|
|
143
211
|
};
|
|
144
212
|
|
|
145
213
|
const gestureEnd = (dx: number, vx: number) => {
|
|
146
|
-
const
|
|
147
|
-
if (
|
|
214
|
+
const step = getStep();
|
|
215
|
+
if (step === 0) return;
|
|
148
216
|
const cnt = itemCountRef.current;
|
|
149
217
|
const start = dragStartIndex.current;
|
|
150
218
|
const isLoop = loopRef.current;
|
|
151
219
|
const setIdx = setActiveIndexRef.current;
|
|
220
|
+
const clones = getCloneCount();
|
|
152
221
|
|
|
153
222
|
let delta = 0;
|
|
154
|
-
if (vx < -0.3 || dx < -
|
|
155
|
-
else if (vx > 0.3 || dx >
|
|
223
|
+
if (vx < -0.3 || dx < -step * 0.3) delta = 1;
|
|
224
|
+
else if (vx > 0.3 || dx > step * 0.3) delta = -1;
|
|
156
225
|
|
|
157
226
|
const targetLogical = start + delta;
|
|
158
227
|
|
|
159
228
|
if (isLoop) {
|
|
160
|
-
const paddedStart = start +
|
|
229
|
+
const paddedStart = start + clones;
|
|
161
230
|
const targetPage = paddedStart + delta;
|
|
162
231
|
|
|
163
|
-
if (targetPage
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
232
|
+
if (targetPage < clones) {
|
|
233
|
+
// Went before first real item — animate to clone, then jump
|
|
234
|
+
Animated.timing(animX, { toValue: -targetPage * step, duration: 200, useNativeDriver: true }).start(() => {
|
|
235
|
+
const jumpIdx = cnt - 1;
|
|
236
|
+
const jumpX = -(jumpIdx + clones) * step;
|
|
237
|
+
animX.setValue(jumpX);
|
|
238
|
+
animXValueRef.current = jumpX;
|
|
239
|
+
setIdx(jumpIdx);
|
|
168
240
|
});
|
|
169
|
-
} else if (targetPage >= cnt +
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
241
|
+
} else if (targetPage >= cnt + clones) {
|
|
242
|
+
// Went past last real item — animate to clone, then jump
|
|
243
|
+
Animated.timing(animX, { toValue: -targetPage * step, duration: 200, useNativeDriver: true }).start(() => {
|
|
244
|
+
const jumpX = -clones * step;
|
|
245
|
+
animX.setValue(jumpX);
|
|
246
|
+
animXValueRef.current = jumpX;
|
|
173
247
|
setIdx(0);
|
|
174
248
|
});
|
|
175
249
|
} else {
|
|
176
|
-
|
|
177
|
-
|
|
250
|
+
const idx = Math.max(0, Math.min(cnt - 1, targetLogical));
|
|
251
|
+
setIdx(idx);
|
|
252
|
+
Animated.timing(animX, { toValue: -targetPage * step, duration: 200, useNativeDriver: true }).start();
|
|
178
253
|
}
|
|
179
254
|
} else {
|
|
180
255
|
const clampedIdx = Math.max(0, Math.min(cnt - 1, targetLogical));
|
|
181
256
|
setIdx(clampedIdx);
|
|
182
|
-
Animated.timing(animX, { toValue: -clampedIdx *
|
|
257
|
+
Animated.timing(animX, { toValue: -clampedIdx * step, duration: 200, useNativeDriver: true }).start();
|
|
183
258
|
}
|
|
184
259
|
};
|
|
185
260
|
|
|
186
261
|
const gestureCancel = () => {
|
|
187
|
-
const
|
|
188
|
-
if (
|
|
262
|
+
const step = getStep();
|
|
263
|
+
if (step === 0) return;
|
|
189
264
|
const start = dragStartIndex.current;
|
|
190
|
-
const
|
|
191
|
-
const targetPage =
|
|
265
|
+
const clones = getCloneCount();
|
|
266
|
+
const targetPage = loopRef.current ? start + clones : start;
|
|
192
267
|
setActiveIndexRef.current(start);
|
|
193
|
-
Animated.timing(animX, { toValue: -targetPage *
|
|
268
|
+
Animated.timing(animX, { toValue: -targetPage * step, duration: 200, useNativeDriver: true }).start();
|
|
194
269
|
};
|
|
195
270
|
|
|
196
271
|
// --- Native: PanResponder ---
|
|
@@ -207,7 +282,7 @@ export const CarouselContent = React.forwardRef<React.ElementRef<typeof View>, C
|
|
|
207
282
|
: null
|
|
208
283
|
).current;
|
|
209
284
|
|
|
210
|
-
// --- Web: Pointer events
|
|
285
|
+
// --- Web: Pointer events ---
|
|
211
286
|
useEffect(() => {
|
|
212
287
|
if (Platform.OS !== 'web') return;
|
|
213
288
|
const el = internalRef.current as unknown as HTMLElement;
|
|
@@ -296,7 +371,7 @@ export const CarouselContent = React.forwardRef<React.ElementRef<typeof View>, C
|
|
|
296
371
|
{...(panResponder?.panHandlers ?? {})}
|
|
297
372
|
{...props}
|
|
298
373
|
>
|
|
299
|
-
<Animated.View style={{ flexDirection: 'row', transform: [{ translateX: animX }] }}>
|
|
374
|
+
<Animated.View style={{ flexDirection: 'row', gap: gapProp, transform: [{ translateX: animX }] }}>
|
|
300
375
|
{displayedChildren}
|
|
301
376
|
</Animated.View>
|
|
302
377
|
</View>
|
|
@@ -305,12 +380,13 @@ export const CarouselContent = React.forwardRef<React.ElementRef<typeof View>, C
|
|
|
305
380
|
CarouselContent.displayName = 'CarouselContent';
|
|
306
381
|
|
|
307
382
|
export const CarouselItem = React.forwardRef<React.ElementRef<typeof View>, CarouselItemProps>(({ className, style, onPress, children, ...props }, ref) => {
|
|
308
|
-
const { width } = useCarouselContext();
|
|
383
|
+
const { width, itemWidth } = useCarouselContext();
|
|
384
|
+
const effectiveWidth = itemWidth > 0 ? itemWidth : width;
|
|
309
385
|
return (
|
|
310
386
|
<View
|
|
311
387
|
ref={ref}
|
|
312
388
|
className={carouselItemStyle({ class: className })}
|
|
313
|
-
style={[
|
|
389
|
+
style={[effectiveWidth > 0 ? { width: effectiveWidth } : undefined, style]}
|
|
314
390
|
{...props}
|
|
315
391
|
>
|
|
316
392
|
{onPress ? (
|
package/src/carousel/types.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface CarouselContextValue {
|
|
|
16
16
|
goTo: (index: number, animate?: boolean) => void;
|
|
17
17
|
next: () => void;
|
|
18
18
|
previous: () => void;
|
|
19
|
+
itemWidth: number;
|
|
20
|
+
gap: number;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export interface CarouselProps extends React.ComponentPropsWithoutRef<typeof View> {
|
|
@@ -23,6 +25,14 @@ export interface CarouselProps extends React.ComponentPropsWithoutRef<typeof Vie
|
|
|
23
25
|
defaultIndex?: number;
|
|
24
26
|
loop?: boolean;
|
|
25
27
|
onIndexChange?: (index: number) => void;
|
|
28
|
+
/** Fixed width for each item. When set, multiple items are visible. */
|
|
29
|
+
itemWidth?: number;
|
|
30
|
+
/** Gap between items in pixels. */
|
|
31
|
+
gap?: number;
|
|
32
|
+
/** Automatically advance slides. */
|
|
33
|
+
autoPlay?: boolean;
|
|
34
|
+
/** Interval in ms between auto-advances (default 3000). */
|
|
35
|
+
autoPlayInterval?: number;
|
|
26
36
|
}
|
|
27
37
|
export interface CarouselContentProps extends React.ComponentPropsWithoutRef<typeof View> { className?: string; }
|
|
28
38
|
export interface CarouselItemProps extends React.ComponentPropsWithoutRef<typeof View> { className?: string; onPress?: () => void; }
|
package/src/divider/styles.ts
CHANGED
package/tailwind-preset.js
CHANGED
|
@@ -172,9 +172,9 @@ module.exports = {
|
|
|
172
172
|
},
|
|
173
173
|
},
|
|
174
174
|
fontFamily: {
|
|
175
|
-
heading:
|
|
176
|
-
body:
|
|
177
|
-
mono:
|
|
175
|
+
heading: ['System', 'ui-sans-serif', 'system-ui', 'sans-serif'],
|
|
176
|
+
body: ['System', 'ui-sans-serif', 'system-ui', 'sans-serif'],
|
|
177
|
+
mono: ['ui-monospace', 'SFMono-Regular', 'monospace'],
|
|
178
178
|
jakarta: ['var(--font-plus-jakarta-sans)'],
|
|
179
179
|
roboto: ['var(--font-roboto)'],
|
|
180
180
|
code: ['var(--font-source-code-pro)'],
|