fluent-styles 1.62.1 → 1.62.2
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/README.md +81 -3709
- package/lib/commonjs/circularProgress/index.js +102 -83
- package/lib/commonjs/circularProgress/index.js.map +1 -1
- package/lib/commonjs/utiles/styled.js +26 -5
- package/lib/commonjs/utiles/styled.js.map +1 -1
- package/lib/module/circularProgress/index.js +103 -84
- package/lib/module/circularProgress/index.js.map +1 -1
- package/lib/module/utiles/styled.js +26 -5
- package/lib/module/utiles/styled.js.map +1 -1
- package/lib/typescript/badge/index.d.ts +3 -1
- package/lib/typescript/badge/index.d.ts.map +1 -1
- package/lib/typescript/button/index.d.ts +5 -1
- package/lib/typescript/button/index.d.ts.map +1 -1
- package/lib/typescript/card/index.d.ts +3 -1
- package/lib/typescript/card/index.d.ts.map +1 -1
- package/lib/typescript/circularProgress/index.d.ts +4 -5
- package/lib/typescript/circularProgress/index.d.ts.map +1 -1
- package/lib/typescript/dialog/index.d.ts +3 -1
- package/lib/typescript/dialog/index.d.ts.map +1 -1
- package/lib/typescript/divider/index.d.ts +3 -1
- package/lib/typescript/divider/index.d.ts.map +1 -1
- package/lib/typescript/header/index.d.ts +3 -1
- package/lib/typescript/header/index.d.ts.map +1 -1
- package/lib/typescript/image/index.d.ts +3 -1
- package/lib/typescript/image/index.d.ts.map +1 -1
- package/lib/typescript/pressable/index.d.ts +3 -1
- package/lib/typescript/pressable/index.d.ts.map +1 -1
- package/lib/typescript/safeAreaProvider/index.d.ts +3 -1
- package/lib/typescript/safeAreaProvider/index.d.ts.map +1 -1
- package/lib/typescript/safeAreaView/index.d.ts +3 -1
- package/lib/typescript/safeAreaView/index.d.ts.map +1 -1
- package/lib/typescript/scrollView/index.d.ts +3 -1
- package/lib/typescript/scrollView/index.d.ts.map +1 -1
- package/lib/typescript/shape/cycle.d.ts +3 -1
- package/lib/typescript/shape/cycle.d.ts.map +1 -1
- package/lib/typescript/shape/index.d.ts +3 -1
- package/lib/typescript/shape/index.d.ts.map +1 -1
- package/lib/typescript/spacer/index.d.ts +3 -1
- package/lib/typescript/spacer/index.d.ts.map +1 -1
- package/lib/typescript/stack/index.d.ts +9 -3
- package/lib/typescript/stack/index.d.ts.map +1 -1
- package/lib/typescript/text/index.d.ts +3 -1
- package/lib/typescript/text/index.d.ts.map +1 -1
- package/lib/typescript/utiles/styled.d.ts +4 -2
- package/lib/typescript/utiles/styled.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/circularProgress/index.tsx +177 -164
- package/src/utiles/styled.tsx +22 -6
|
@@ -6,7 +6,6 @@ import React, {
|
|
|
6
6
|
import {
|
|
7
7
|
Animated,
|
|
8
8
|
Easing,
|
|
9
|
-
StyleSheet,
|
|
10
9
|
} from 'react-native'
|
|
11
10
|
import Svg, { Circle, Defs, LinearGradient, Stop } from 'react-native-svg'
|
|
12
11
|
|
|
@@ -54,38 +53,41 @@ export interface StyledCircularProgressProps {
|
|
|
54
53
|
colors?: Partial<CircularProgressColors>
|
|
55
54
|
|
|
56
55
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* @default 'stacked'
|
|
56
|
+
* 'inside' — percentage / label rendered centred inside the ring (default)
|
|
57
|
+
* 'stacked' — text sits below the ring
|
|
58
|
+
* 'center' — alias for 'inside' (backwards-compat)
|
|
61
59
|
*/
|
|
62
|
-
contentPosition?: 'center' | 'stacked'
|
|
60
|
+
contentPosition?: 'inside' | 'center' | 'stacked'
|
|
63
61
|
|
|
64
62
|
children?: React.ReactNode
|
|
65
63
|
}
|
|
66
64
|
|
|
65
|
+
// ─── Size presets ─────────────────────────────────────────────────────────────
|
|
66
|
+
|
|
67
67
|
const SIZE_MAP: Record<
|
|
68
68
|
CircularProgressSize,
|
|
69
69
|
{ diameter: number; stroke: number; primaryFont: number; secondaryFont: number }
|
|
70
70
|
> = {
|
|
71
|
-
xs: { diameter: 48,
|
|
72
|
-
sm: { diameter: 64,
|
|
73
|
-
md: { diameter: 80,
|
|
71
|
+
xs: { diameter: 48, stroke: 4, primaryFont: 11, secondaryFont: 8 },
|
|
72
|
+
sm: { diameter: 64, stroke: 5, primaryFont: 13, secondaryFont: 9 },
|
|
73
|
+
md: { diameter: 80, stroke: 6, primaryFont: 15, secondaryFont: 10 },
|
|
74
74
|
lg: { diameter: 100, stroke: 7, primaryFont: 18, secondaryFont: 11 },
|
|
75
75
|
xl: { diameter: 128, stroke: 8, primaryFont: 22, secondaryFont: 12 },
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
const DEFAULT_COLORS: CircularProgressColors = {
|
|
79
|
-
arc:
|
|
80
|
-
track:
|
|
81
|
-
label:
|
|
82
|
-
sublabel:
|
|
79
|
+
arc: theme.colors.indigo?.[500] ?? '#6366f1',
|
|
80
|
+
track: theme.colors.gray[200],
|
|
81
|
+
label: theme.colors.gray[800],
|
|
82
|
+
sublabel: theme.colors.gray[400],
|
|
83
83
|
gradientFrom: theme.colors.violet?.[500] ?? '#8b5cf6',
|
|
84
|
-
gradientTo:
|
|
84
|
+
gradientTo: theme.colors.cyan?.[400] ?? '#22d3ee',
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle)
|
|
88
88
|
|
|
89
|
+
// ─── Component ────────────────────────────────────────────────────────────────
|
|
90
|
+
|
|
89
91
|
export const StyledCircularProgress: React.FC<StyledCircularProgressProps> = ({
|
|
90
92
|
value,
|
|
91
93
|
total = 100,
|
|
@@ -100,25 +102,25 @@ export const StyledCircularProgress: React.FC<StyledCircularProgressProps> = ({
|
|
|
100
102
|
animated = true,
|
|
101
103
|
duration = 900,
|
|
102
104
|
colors: colorOverrides,
|
|
103
|
-
contentPosition = '
|
|
105
|
+
contentPosition = 'inside',
|
|
104
106
|
children,
|
|
105
107
|
}) => {
|
|
106
|
-
const preset
|
|
107
|
-
const diameter
|
|
108
|
+
const preset = SIZE_MAP[size]
|
|
109
|
+
const diameter = diameterProp ?? preset.diameter
|
|
108
110
|
const strokeWidth = strokeWidthProp ?? preset.stroke
|
|
109
111
|
|
|
110
112
|
const isDashboard = variant === 'dashboard'
|
|
111
113
|
|
|
112
|
-
const radius
|
|
114
|
+
const radius = (diameter - strokeWidth) / 2
|
|
113
115
|
const circumference = 2 * Math.PI * radius
|
|
114
|
-
const arcLength
|
|
116
|
+
const arcLength = isDashboard ? circumference / 2 : circumference
|
|
115
117
|
|
|
116
118
|
const colors: CircularProgressColors = useMemo(
|
|
117
119
|
() => (colorOverrides ? { ...DEFAULT_COLORS, ...colorOverrides } : DEFAULT_COLORS),
|
|
118
|
-
[colorOverrides]
|
|
120
|
+
[colorOverrides],
|
|
119
121
|
)
|
|
120
122
|
|
|
121
|
-
const clamped
|
|
123
|
+
const clamped = Math.min(Math.max(value, 0), total)
|
|
122
124
|
const fraction = total > 0 ? clamped / total : 0
|
|
123
125
|
|
|
124
126
|
const progress = useRef(new Animated.Value(animated ? 0 : fraction)).current
|
|
@@ -128,59 +130,117 @@ export const StyledCircularProgress: React.FC<StyledCircularProgressProps> = ({
|
|
|
128
130
|
progress.setValue(fraction)
|
|
129
131
|
return
|
|
130
132
|
}
|
|
131
|
-
|
|
132
133
|
Animated.timing(progress, {
|
|
133
|
-
toValue:
|
|
134
|
+
toValue: fraction,
|
|
134
135
|
duration,
|
|
135
|
-
easing:
|
|
136
|
+
easing: Easing.out(Easing.cubic),
|
|
136
137
|
useNativeDriver: false,
|
|
137
138
|
}).start()
|
|
138
139
|
}, [fraction, animated, duration, progress])
|
|
139
140
|
|
|
140
141
|
const strokeDashoffset = progress.interpolate({
|
|
141
|
-
inputRange:
|
|
142
|
+
inputRange: [0, 1],
|
|
142
143
|
outputRange: [arcLength, 0],
|
|
143
144
|
})
|
|
144
145
|
|
|
145
|
-
const center
|
|
146
|
+
const center = diameter / 2
|
|
146
147
|
const gradientId = `cpGrad-${Math.round(diameter)}-${variant}`
|
|
147
148
|
|
|
148
149
|
const centreText = useMemo(() => {
|
|
149
150
|
switch (display) {
|
|
150
|
-
case 'percent':
|
|
151
|
-
|
|
152
|
-
case '
|
|
153
|
-
|
|
154
|
-
case '
|
|
155
|
-
|
|
156
|
-
case 'label':
|
|
157
|
-
return label ?? ''
|
|
158
|
-
case 'none':
|
|
159
|
-
return null
|
|
160
|
-
default:
|
|
161
|
-
return null
|
|
151
|
+
case 'percent': return `${Math.round(fraction * 100)}%`
|
|
152
|
+
case 'fraction': return `${clamped}/${total}`
|
|
153
|
+
case 'value': return String(clamped)
|
|
154
|
+
case 'label': return label ?? ''
|
|
155
|
+
case 'none': return null
|
|
156
|
+
default: return null
|
|
162
157
|
}
|
|
163
158
|
}, [display, fraction, clamped, total, label])
|
|
164
159
|
|
|
165
|
-
const arcStroke
|
|
160
|
+
const arcStroke = variant === 'gradient' ? `url(#${gradientId})` : colors.arc
|
|
166
161
|
const trackOpacity = variant === 'ghost' ? 0 : 1
|
|
167
|
-
const trackDash
|
|
162
|
+
const trackDash = isDashboard ? [arcLength, circumference - arcLength] : undefined
|
|
163
|
+
|
|
164
|
+
// 'inside' and 'center' both mean text lives inside the ring
|
|
165
|
+
const isInside = contentPosition === 'inside' || contentPosition === 'center'
|
|
168
166
|
|
|
169
|
-
|
|
167
|
+
// ── SVG height for dashboard variant ──────────────────────────────────────
|
|
168
|
+
const svgHeight = isDashboard ? diameter / 2 + strokeWidth : diameter
|
|
169
|
+
const containerH = isDashboard ? diameter / 2 + strokeWidth : diameter
|
|
170
|
+
|
|
171
|
+
// ── Text overlay rendered inside the ring ─────────────────────────────────
|
|
172
|
+
const renderInsideText = () => {
|
|
173
|
+
if (children) return null // custom children take over
|
|
170
174
|
|
|
171
|
-
const renderTextBlock = () => {
|
|
172
|
-
if (contentPosition === 'center') {
|
|
173
175
|
return (
|
|
174
176
|
<Stack
|
|
175
177
|
position="absolute"
|
|
176
|
-
left={strokeWidth + 6}
|
|
177
|
-
right={strokeWidth + 6}
|
|
178
178
|
top={0}
|
|
179
|
-
|
|
179
|
+
left={0}
|
|
180
|
+
width={diameter}
|
|
181
|
+
height={containerH}
|
|
180
182
|
alignItems="center"
|
|
181
183
|
justifyContent="center"
|
|
182
|
-
gap={1}
|
|
183
184
|
pointerEvents="none"
|
|
185
|
+
>
|
|
186
|
+
<Stack
|
|
187
|
+
alignItems="center"
|
|
188
|
+
justifyContent="center"
|
|
189
|
+
gap={2}
|
|
190
|
+
paddingBottom={isDashboard ? strokeWidth + 4 : 0}
|
|
191
|
+
>
|
|
192
|
+
{centreText !== null && centreText !== '' && (
|
|
193
|
+
<StyledText
|
|
194
|
+
fontSize={preset.primaryFont}
|
|
195
|
+
fontWeight={theme.fontWeight.bold}
|
|
196
|
+
color={colors.label}
|
|
197
|
+
lineHeight={preset.primaryFont + 3}
|
|
198
|
+
textAlign="center"
|
|
199
|
+
>
|
|
200
|
+
{centreText}
|
|
201
|
+
</StyledText>
|
|
202
|
+
)}
|
|
203
|
+
|
|
204
|
+
{display !== 'label' && display !== 'none' && !!label && (
|
|
205
|
+
<StyledText
|
|
206
|
+
fontSize={preset.secondaryFont}
|
|
207
|
+
color={colors.sublabel}
|
|
208
|
+
lineHeight={preset.secondaryFont + 2}
|
|
209
|
+
textAlign="center"
|
|
210
|
+
>
|
|
211
|
+
{label}
|
|
212
|
+
</StyledText>
|
|
213
|
+
)}
|
|
214
|
+
|
|
215
|
+
{!!sublabel && (
|
|
216
|
+
<StyledText
|
|
217
|
+
fontSize={Math.max(preset.secondaryFont - 1, 8)}
|
|
218
|
+
color={colors.sublabel}
|
|
219
|
+
lineHeight={preset.secondaryFont + 1}
|
|
220
|
+
textAlign="center"
|
|
221
|
+
>
|
|
222
|
+
{sublabel}
|
|
223
|
+
</StyledText>
|
|
224
|
+
)}
|
|
225
|
+
</Stack>
|
|
226
|
+
</Stack>
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ── Text block rendered below the ring ────────────────────────────────────
|
|
231
|
+
const renderStackedText = () => {
|
|
232
|
+
if (children) return null
|
|
233
|
+
|
|
234
|
+
const showLabel = display !== 'label' && display !== 'none' && !!label
|
|
235
|
+
const showSublabel = !!sublabel
|
|
236
|
+
|
|
237
|
+
return (
|
|
238
|
+
<Stack
|
|
239
|
+
alignItems="center"
|
|
240
|
+
justifyContent="center"
|
|
241
|
+
gap={1}
|
|
242
|
+
marginTop={isDashboard ? -(diameter / 4) : 0}
|
|
243
|
+
paddingHorizontal={strokeWidth + 4}
|
|
184
244
|
>
|
|
185
245
|
{centreText !== null && centreText !== '' && (
|
|
186
246
|
<StyledText
|
|
@@ -194,7 +254,7 @@ export const StyledCircularProgress: React.FC<StyledCircularProgressProps> = ({
|
|
|
194
254
|
</StyledText>
|
|
195
255
|
)}
|
|
196
256
|
|
|
197
|
-
{
|
|
257
|
+
{showLabel && (
|
|
198
258
|
<StyledText
|
|
199
259
|
fontSize={preset.secondaryFont}
|
|
200
260
|
color={colors.sublabel}
|
|
@@ -205,11 +265,13 @@ export const StyledCircularProgress: React.FC<StyledCircularProgressProps> = ({
|
|
|
205
265
|
</StyledText>
|
|
206
266
|
)}
|
|
207
267
|
|
|
208
|
-
{
|
|
268
|
+
{showSublabel && (
|
|
209
269
|
<StyledText
|
|
210
|
-
fontSize={
|
|
270
|
+
fontSize={showLabel
|
|
271
|
+
? Math.max(preset.secondaryFont - 1, 8)
|
|
272
|
+
: preset.secondaryFont}
|
|
211
273
|
color={colors.sublabel}
|
|
212
|
-
lineHeight={preset.secondaryFont +
|
|
274
|
+
lineHeight={preset.secondaryFont + 2}
|
|
213
275
|
textAlign="center"
|
|
214
276
|
>
|
|
215
277
|
{sublabel}
|
|
@@ -219,131 +281,82 @@ export const StyledCircularProgress: React.FC<StyledCircularProgressProps> = ({
|
|
|
219
281
|
)
|
|
220
282
|
}
|
|
221
283
|
|
|
222
|
-
|
|
223
|
-
const showSubLabel = !!sublabel
|
|
224
|
-
|
|
225
|
-
return (
|
|
226
|
-
<Stack
|
|
227
|
-
alignItems="center"
|
|
228
|
-
justifyContent="center"
|
|
229
|
-
gap={1}
|
|
230
|
-
marginTop={dashboardTextOffset}
|
|
231
|
-
paddingHorizontal={strokeWidth + 4}
|
|
232
|
-
>
|
|
233
|
-
{centreText !== null && centreText !== '' && (
|
|
234
|
-
<StyledText
|
|
235
|
-
fontSize={preset.primaryFont}
|
|
236
|
-
fontWeight={theme.fontWeight.bold}
|
|
237
|
-
color={colors.label}
|
|
238
|
-
lineHeight={preset.primaryFont + 3}
|
|
239
|
-
textAlign="center"
|
|
240
|
-
>
|
|
241
|
-
{centreText}
|
|
242
|
-
</StyledText>
|
|
243
|
-
)}
|
|
244
|
-
|
|
245
|
-
{showSecondLine && (
|
|
246
|
-
<StyledText
|
|
247
|
-
fontSize={preset.secondaryFont}
|
|
248
|
-
color={colors.sublabel}
|
|
249
|
-
lineHeight={preset.secondaryFont + 2}
|
|
250
|
-
textAlign="center"
|
|
251
|
-
>
|
|
252
|
-
{label}
|
|
253
|
-
</StyledText>
|
|
254
|
-
)}
|
|
255
|
-
|
|
256
|
-
{showSubLabel && !showSecondLine && (
|
|
257
|
-
<StyledText
|
|
258
|
-
fontSize={preset.secondaryFont}
|
|
259
|
-
color={colors.sublabel}
|
|
260
|
-
lineHeight={preset.secondaryFont + 2}
|
|
261
|
-
textAlign="center"
|
|
262
|
-
>
|
|
263
|
-
{sublabel}
|
|
264
|
-
</StyledText>
|
|
265
|
-
)}
|
|
266
|
-
|
|
267
|
-
{showSubLabel && showSecondLine && (
|
|
268
|
-
<StyledText
|
|
269
|
-
fontSize={Math.max(preset.secondaryFont - 1, 8)}
|
|
270
|
-
color={colors.sublabel}
|
|
271
|
-
lineHeight={preset.secondaryFont + 1}
|
|
272
|
-
textAlign="center"
|
|
273
|
-
>
|
|
274
|
-
{sublabel}
|
|
275
|
-
</StyledText>
|
|
276
|
-
)}
|
|
277
|
-
</Stack>
|
|
278
|
-
)
|
|
279
|
-
}
|
|
284
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
280
285
|
|
|
281
286
|
return (
|
|
282
287
|
<Stack
|
|
283
288
|
width={diameter}
|
|
284
|
-
height={
|
|
289
|
+
height={isInside ? containerH : undefined}
|
|
285
290
|
alignItems="center"
|
|
286
291
|
justifyContent="center"
|
|
287
|
-
|
|
292
|
+
position="relative"
|
|
288
293
|
>
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
<Circle
|
|
305
|
-
cx={center}
|
|
306
|
-
cy={center}
|
|
307
|
-
r={radius}
|
|
308
|
-
stroke={colors.track}
|
|
309
|
-
strokeWidth={strokeWidth}
|
|
310
|
-
strokeDasharray={trackDash}
|
|
311
|
-
strokeLinecap="butt"
|
|
312
|
-
fill="none"
|
|
313
|
-
opacity={trackOpacity}
|
|
314
|
-
rotation={isDashboard ? 90 : 0}
|
|
315
|
-
origin={`${center}, ${center}`}
|
|
316
|
-
/>
|
|
317
|
-
|
|
318
|
-
<AnimatedCircle
|
|
319
|
-
cx={center}
|
|
320
|
-
cy={center}
|
|
321
|
-
r={radius}
|
|
322
|
-
stroke={arcStroke as any}
|
|
323
|
-
strokeWidth={strokeWidth}
|
|
324
|
-
fill="none"
|
|
325
|
-
strokeDasharray={arcLength}
|
|
326
|
-
strokeDashoffset={strokeDashoffset as any}
|
|
327
|
-
strokeLinecap={lineCap}
|
|
328
|
-
rotation={isDashboard ? 90 : -90}
|
|
329
|
-
origin={`${center}, ${center}`}
|
|
330
|
-
/>
|
|
331
|
-
</Svg>
|
|
332
|
-
</Stack>
|
|
294
|
+
{/* SVG ring */}
|
|
295
|
+
<Svg
|
|
296
|
+
width={diameter}
|
|
297
|
+
height={svgHeight}
|
|
298
|
+
style={isDashboard ? { marginTop: -(diameter / 2) } : undefined}
|
|
299
|
+
>
|
|
300
|
+
{variant === 'gradient' && (
|
|
301
|
+
<Defs>
|
|
302
|
+
<LinearGradient id={gradientId} x1="0%" y1="0%" x2="100%" y2="0%">
|
|
303
|
+
<Stop offset="0%" stopColor={colors.gradientFrom} />
|
|
304
|
+
<Stop offset="100%" stopColor={colors.gradientTo} />
|
|
305
|
+
</LinearGradient>
|
|
306
|
+
</Defs>
|
|
307
|
+
)}
|
|
333
308
|
|
|
309
|
+
{/* Track */}
|
|
310
|
+
<Circle
|
|
311
|
+
cx={center}
|
|
312
|
+
cy={center}
|
|
313
|
+
r={radius}
|
|
314
|
+
stroke={colors.track}
|
|
315
|
+
strokeWidth={strokeWidth}
|
|
316
|
+
strokeDasharray={trackDash}
|
|
317
|
+
strokeLinecap="butt"
|
|
318
|
+
fill="none"
|
|
319
|
+
opacity={trackOpacity}
|
|
320
|
+
rotation={isDashboard ? 90 : 0}
|
|
321
|
+
origin={`${center}, ${center}`}
|
|
322
|
+
/>
|
|
323
|
+
|
|
324
|
+
{/* Progress arc */}
|
|
325
|
+
<AnimatedCircle
|
|
326
|
+
cx={center}
|
|
327
|
+
cy={center}
|
|
328
|
+
r={radius}
|
|
329
|
+
stroke={arcStroke as any}
|
|
330
|
+
strokeWidth={strokeWidth}
|
|
331
|
+
fill="none"
|
|
332
|
+
strokeDasharray={arcLength}
|
|
333
|
+
strokeDashoffset={strokeDashoffset as any}
|
|
334
|
+
strokeLinecap={lineCap}
|
|
335
|
+
rotation={isDashboard ? 90 : -90}
|
|
336
|
+
origin={`${center}, ${center}`}
|
|
337
|
+
/>
|
|
338
|
+
</Svg>
|
|
339
|
+
|
|
340
|
+
{/* Text / children */}
|
|
334
341
|
{children ? (
|
|
335
|
-
<Stack
|
|
342
|
+
<Stack
|
|
343
|
+
position="absolute"
|
|
344
|
+
top={0}
|
|
345
|
+
left={0}
|
|
346
|
+
width={diameter}
|
|
347
|
+
height={containerH}
|
|
348
|
+
alignItems="center"
|
|
349
|
+
justifyContent="center"
|
|
350
|
+
pointerEvents="none"
|
|
351
|
+
gap={2}
|
|
352
|
+
>
|
|
336
353
|
{children}
|
|
337
354
|
</Stack>
|
|
355
|
+
) : isInside ? (
|
|
356
|
+
renderInsideText()
|
|
338
357
|
) : (
|
|
339
|
-
|
|
358
|
+
renderStackedText()
|
|
340
359
|
)}
|
|
341
360
|
</Stack>
|
|
342
361
|
)
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
const S = StyleSheet.create({
|
|
346
|
-
svg_wrap: {
|
|
347
|
-
position: 'absolute',
|
|
348
|
-
},
|
|
349
|
-
})
|
|
362
|
+
}
|
package/src/utiles/styled.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { ComponentType, Ref, forwardRef } from "react";
|
|
3
3
|
import { ViewStyle, TextStyle, ImageStyle } from "react-native";
|
|
4
4
|
|
|
5
5
|
type Style = ViewStyle | TextStyle | ImageStyle;
|
|
@@ -13,13 +13,15 @@ interface StyledOptions {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
// React 19 passes ref as a regular prop; React 18 and below do not.
|
|
17
|
+
const isReact19 = typeof React.version === "string" && parseInt(React.version) >= 19;
|
|
18
|
+
|
|
16
19
|
const styled = <P extends object>(
|
|
17
20
|
Component: ComponentType<P>,
|
|
18
21
|
{ base, variants }: StyledOptions = {}
|
|
19
22
|
) => {
|
|
20
|
-
|
|
23
|
+
function buildStyles(options: Record<string, any>): Style {
|
|
21
24
|
const styles: Style = { ...(base || {}) };
|
|
22
|
-
const options = props as Record<string, any>;
|
|
23
25
|
|
|
24
26
|
if (variants) {
|
|
25
27
|
Object.keys(variants).forEach((category) => {
|
|
@@ -28,9 +30,7 @@ const styled = <P extends object>(
|
|
|
28
30
|
|
|
29
31
|
if (typeof variantValue === "function") {
|
|
30
32
|
const style = variantValue(variantSelected, options);
|
|
31
|
-
if (style)
|
|
32
|
-
Object.assign(styles, style);
|
|
33
|
-
}
|
|
33
|
+
if (style) Object.assign(styles, style);
|
|
34
34
|
} else if (variantValue && variantValue[variantSelected]) {
|
|
35
35
|
const value = variantValue[variantSelected];
|
|
36
36
|
Object.assign(
|
|
@@ -41,6 +41,22 @@ const styled = <P extends object>(
|
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
return styles;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (isReact19) {
|
|
48
|
+
// React 19: ref is a plain prop
|
|
49
|
+
function StyledComponent19(props: P & { ref?: Ref<any> }) {
|
|
50
|
+
const { ref, ...rest } = props as any;
|
|
51
|
+
const styles = buildStyles(rest);
|
|
52
|
+
return <Component {...(rest as any)} style={styles} ref={ref} />;
|
|
53
|
+
}
|
|
54
|
+
return StyledComponent19;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// React 18 and below: use forwardRef
|
|
58
|
+
return forwardRef<any, P>((props, ref) => {
|
|
59
|
+
const styles = buildStyles(props as Record<string, any>);
|
|
44
60
|
return <Component {...(props as any)} style={styles} ref={ref} />;
|
|
45
61
|
});
|
|
46
62
|
};
|