jfs-components 0.0.70 → 0.0.72
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/CHANGELOG.md +49 -0
- package/lib/commonjs/components/CardAdvisory/CardAdvisory.js +203 -0
- package/lib/commonjs/components/CardCTA/CardCTA.js +198 -16
- package/lib/commonjs/components/CardFinancialCondition/CardFinancialCondition.js +213 -0
- package/lib/commonjs/components/Carousel/Carousel.js +9 -7
- package/lib/commonjs/components/CircularProgressBar/CircularProgressBar.js +147 -0
- package/lib/commonjs/components/CircularProgressBarDoted/CircularProgressBarDoted.js +258 -0
- package/lib/commonjs/components/CircularRating/CircularRating.js +161 -0
- package/lib/commonjs/components/Gauge/Gauge.js +223 -0
- package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +2 -2
- package/lib/commonjs/components/InstitutionBadge/InstitutionBadge.js +132 -0
- package/lib/commonjs/components/ListGroup/ListGroup.js +3 -1
- package/lib/commonjs/components/Nudge/Nudge.js +179 -87
- package/lib/commonjs/components/Radio/Radio.js +194 -0
- package/lib/commonjs/components/RadioButton/RadioButton.js +21 -188
- package/lib/commonjs/components/index.js +56 -0
- package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/module/components/CardAdvisory/CardAdvisory.js +197 -0
- package/lib/module/components/CardCTA/CardCTA.js +199 -17
- package/lib/module/components/CardFinancialCondition/CardFinancialCondition.js +207 -0
- package/lib/module/components/Carousel/Carousel.js +9 -7
- package/lib/module/components/CircularProgressBar/CircularProgressBar.js +141 -0
- package/lib/module/components/CircularProgressBarDoted/CircularProgressBarDoted.js +253 -0
- package/lib/module/components/CircularRating/CircularRating.js +155 -0
- package/lib/module/components/Gauge/Gauge.js +217 -0
- package/lib/module/components/HoldingsCard/HoldingsCard.js +2 -2
- package/lib/module/components/InstitutionBadge/InstitutionBadge.js +127 -0
- package/lib/module/components/ListGroup/ListGroup.js +3 -1
- package/lib/module/components/Nudge/Nudge.js +178 -87
- package/lib/module/components/Radio/Radio.js +188 -0
- package/lib/module/components/RadioButton/RadioButton.js +20 -185
- package/lib/module/components/index.js +12 -0
- package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/module/icons/registry.js +1 -1
- package/lib/typescript/src/components/CardAdvisory/CardAdvisory.d.ts +49 -0
- package/lib/typescript/src/components/CardCTA/CardCTA.d.ts +16 -1
- package/lib/typescript/src/components/CardFinancialCondition/CardFinancialCondition.d.ts +50 -0
- package/lib/typescript/src/components/CircularProgressBar/CircularProgressBar.d.ts +27 -0
- package/lib/typescript/src/components/CircularProgressBarDoted/CircularProgressBarDoted.d.ts +48 -0
- package/lib/typescript/src/components/CircularRating/CircularRating.d.ts +49 -0
- package/lib/typescript/src/components/Gauge/Gauge.d.ts +53 -0
- package/lib/typescript/src/components/InstitutionBadge/InstitutionBadge.d.ts +30 -0
- package/lib/typescript/src/components/Nudge/Nudge.d.ts +14 -11
- package/lib/typescript/src/components/Radio/Radio.d.ts +30 -0
- package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +20 -28
- package/lib/typescript/src/components/index.d.ts +13 -1
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/CardAdvisory/CardAdvisory.tsx +283 -0
- package/src/components/CardCTA/CardCTA.tsx +236 -13
- package/src/components/CardFinancialCondition/CardFinancialCondition.tsx +366 -0
- package/src/components/Carousel/Carousel.tsx +14 -6
- package/src/components/CircularProgressBar/CircularProgressBar.tsx +190 -0
- package/src/components/CircularProgressBarDoted/CircularProgressBarDoted.tsx +357 -0
- package/src/components/CircularRating/CircularRating.tsx +241 -0
- package/src/components/Gauge/Gauge.tsx +303 -0
- package/src/components/HoldingsCard/HoldingsCard.tsx +2 -2
- package/src/components/InstitutionBadge/InstitutionBadge.tsx +216 -0
- package/src/components/ListGroup/ListGroup.tsx +3 -1
- package/src/components/Nudge/Nudge.tsx +222 -82
- package/src/components/Radio/Radio.tsx +227 -0
- package/src/components/RadioButton/RadioButton.tsx +23 -225
- package/src/components/index.ts +13 -1
- package/src/design-tokens/Coin Variables-variables-full.json +1 -1
- package/src/icons/registry.ts +1 -1
|
@@ -1,31 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
3
|
+
import React, { useMemo } from 'react';
|
|
4
4
|
import { View, Text } from 'react-native';
|
|
5
5
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
6
6
|
import { useTokens } from '../../design-tokens/JFSThemeProvider';
|
|
7
7
|
import { cloneChildrenWithModes, EMPTY_MODES } from '../../utils/react-utils';
|
|
8
8
|
import Button from '../Button/Button';
|
|
9
|
+
import Icon from '../../icons/Icon';
|
|
9
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
buttonSlot,
|
|
17
|
-
startSlot,
|
|
18
|
-
children,
|
|
19
|
-
modes: propModes = EMPTY_MODES,
|
|
20
|
-
style
|
|
21
|
-
}) {
|
|
22
|
-
const {
|
|
23
|
-
modes: globalModes
|
|
24
|
-
} = useTokens();
|
|
25
|
-
const modes = {
|
|
26
|
-
...globalModes,
|
|
27
|
-
...propModes
|
|
28
|
-
};
|
|
11
|
+
function toFontWeight(value, fallback) {
|
|
12
|
+
if (typeof value === 'number') return value.toString();
|
|
13
|
+
if (typeof value === 'string') return value;
|
|
14
|
+
return fallback;
|
|
15
|
+
}
|
|
16
|
+
function resolveNudgeTokens(modes) {
|
|
29
17
|
const background = getVariableByName('nudge/background', modes) || '#f5f5f5';
|
|
30
18
|
const radius = getVariableByName('nudge/radius', modes) || 12;
|
|
31
19
|
const paddingH = getVariableByName('nudge/padding/horizontal', modes) || 12;
|
|
@@ -33,106 +21,209 @@ function Nudge({
|
|
|
33
21
|
const gap = getVariableByName('nudge/gap', modes) || 6;
|
|
34
22
|
const titleColor = getVariableByName('nudge/title/color', modes) || '#0d0d0f';
|
|
35
23
|
const titleFontSize = getVariableByName('nudge/title/fontSize', modes) || 14;
|
|
36
|
-
const titleFontFamily = getVariableByName('nudge/title/fontFamily', modes) || '
|
|
24
|
+
const titleFontFamily = getVariableByName('nudge/title/fontFamily', modes) || 'System';
|
|
37
25
|
const titleLineHeight = getVariableByName('nudge/title/lineHeight', modes) || 15;
|
|
38
|
-
const
|
|
39
|
-
const titleFontWeight = typeof titleFontWeightRaw === 'number' ? titleFontWeightRaw.toString() : titleFontWeightRaw;
|
|
26
|
+
const titleFontWeight = toFontWeight(getVariableByName('nudge/title/fontWeight', modes), '700');
|
|
40
27
|
const bodyColor = getVariableByName('nudge/body/color', modes) || '#1a1c1f';
|
|
41
28
|
const bodyFontSize = getVariableByName('nudge/body/fontSize', modes) || 12;
|
|
42
|
-
const bodyFontFamily = getVariableByName('nudge/body/fontFamily', modes) || '
|
|
29
|
+
const bodyFontFamily = getVariableByName('nudge/body/fontFamily', modes) || 'System';
|
|
43
30
|
const bodyLineHeight = getVariableByName('nudge/body/lineHeight', modes) || 16;
|
|
44
|
-
const
|
|
45
|
-
const bodyFontWeight = typeof bodyFontWeightRaw === 'number' ? bodyFontWeightRaw.toString() : bodyFontWeightRaw;
|
|
31
|
+
const bodyFontWeight = toFontWeight(getVariableByName('nudge/body/fontWeight', modes), '500');
|
|
46
32
|
const textGap = getVariableByName('nudge/text/gap', modes) || 4;
|
|
47
33
|
const contentGap = getVariableByName('nudge/content/gap', modes) || 8;
|
|
48
34
|
const contentMinHeight = getVariableByName('nudge/content/minHeight', modes) || 20;
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
35
|
+
const startSlotGap = getVariableByName('nudge/startSlot/gap', modes) || 4;
|
|
36
|
+
return {
|
|
37
|
+
containerBaseStyle: {
|
|
38
|
+
backgroundColor: background,
|
|
39
|
+
borderRadius: radius,
|
|
40
|
+
paddingHorizontal: paddingH,
|
|
41
|
+
paddingVertical: paddingV,
|
|
42
|
+
gap: gap,
|
|
43
|
+
overflow: 'hidden'
|
|
44
|
+
},
|
|
45
|
+
prominentContainerStyle: {
|
|
46
|
+
flexDirection: 'row',
|
|
47
|
+
alignItems: 'flex-start'
|
|
48
|
+
},
|
|
49
|
+
compactContainerStyle: {
|
|
50
|
+
flexDirection: 'row',
|
|
51
|
+
alignItems: 'center'
|
|
52
|
+
},
|
|
53
|
+
detailedContainerStyle: {
|
|
57
54
|
flexDirection: 'column',
|
|
58
55
|
alignItems: 'flex-start'
|
|
59
|
-
}
|
|
56
|
+
},
|
|
57
|
+
contentStyle: {
|
|
58
|
+
flex: 1,
|
|
59
|
+
minWidth: 1,
|
|
60
|
+
minHeight: contentMinHeight,
|
|
61
|
+
justifyContent: 'center',
|
|
62
|
+
overflow: 'hidden'
|
|
63
|
+
},
|
|
64
|
+
compactOuterContentStyle: {
|
|
65
|
+
flex: 1,
|
|
66
|
+
minWidth: 1,
|
|
67
|
+
alignSelf: 'stretch',
|
|
68
|
+
justifyContent: 'center'
|
|
69
|
+
},
|
|
70
|
+
compactContentWrapStyle: {
|
|
60
71
|
flexDirection: 'row',
|
|
72
|
+
alignItems: 'center',
|
|
73
|
+
gap: contentGap,
|
|
74
|
+
width: '100%'
|
|
75
|
+
},
|
|
76
|
+
textWrapStyle: {
|
|
77
|
+
gap: textGap,
|
|
78
|
+
alignItems: 'flex-start',
|
|
79
|
+
width: '100%'
|
|
80
|
+
},
|
|
81
|
+
compactTextWrapStyle: {
|
|
82
|
+
flex: 1,
|
|
83
|
+
minWidth: 1,
|
|
61
84
|
alignItems: 'flex-start'
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
85
|
+
},
|
|
86
|
+
headerStyle: {
|
|
87
|
+
flexDirection: 'row',
|
|
88
|
+
alignItems: 'center',
|
|
89
|
+
gap: gap,
|
|
90
|
+
width: '100%'
|
|
91
|
+
},
|
|
92
|
+
detailSlotStyle: {
|
|
93
|
+
gap: getVariableByName('slot/gap', modes) || 8,
|
|
94
|
+
width: '100%'
|
|
95
|
+
},
|
|
96
|
+
titleTextStyle: {
|
|
97
|
+
color: titleColor,
|
|
98
|
+
fontSize: titleFontSize,
|
|
99
|
+
fontFamily: titleFontFamily,
|
|
100
|
+
lineHeight: titleLineHeight,
|
|
101
|
+
fontWeight: titleFontWeight
|
|
102
|
+
},
|
|
103
|
+
bodyTextStyle: {
|
|
104
|
+
color: bodyColor,
|
|
105
|
+
fontSize: bodyFontSize,
|
|
106
|
+
fontFamily: bodyFontFamily,
|
|
107
|
+
lineHeight: bodyLineHeight,
|
|
108
|
+
fontWeight: bodyFontWeight
|
|
109
|
+
},
|
|
110
|
+
iconColor: getVariableByName('appearance/nudge/icon/color', modes) || '#5d00b5',
|
|
111
|
+
iconSize: getVariableByName('nudge/icon/size', modes) || 20,
|
|
112
|
+
startSlotGap: startSlotGap
|
|
77
113
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
114
|
+
}
|
|
115
|
+
function NudgeImpl({
|
|
116
|
+
type = 'stacked-prominent',
|
|
117
|
+
title = 'Split payment',
|
|
118
|
+
body = 'Split this transaction into installments',
|
|
119
|
+
buttonLabel = 'Button',
|
|
120
|
+
onPressButton,
|
|
121
|
+
buttonSlot,
|
|
122
|
+
startSlot,
|
|
123
|
+
children,
|
|
124
|
+
modes: propModes = EMPTY_MODES,
|
|
125
|
+
style
|
|
126
|
+
}) {
|
|
127
|
+
const {
|
|
128
|
+
modes: globalModes
|
|
129
|
+
} = useTokens();
|
|
130
|
+
const modes = useMemo(() => globalModes === EMPTY_MODES && propModes === EMPTY_MODES ? EMPTY_MODES : {
|
|
131
|
+
...globalModes,
|
|
132
|
+
...propModes
|
|
133
|
+
}, [globalModes, propModes]);
|
|
134
|
+
const tokens = useMemo(() => resolveNudgeTokens(modes), [modes]);
|
|
135
|
+
const startSlotElement = useMemo(() => {
|
|
136
|
+
if (startSlot === null || startSlot === false) return null;
|
|
137
|
+
if (startSlot !== undefined) {
|
|
138
|
+
const processed = cloneChildrenWithModes(React.Children.toArray(startSlot), modes);
|
|
139
|
+
return processed.length === 1 ? processed[0] : processed;
|
|
140
|
+
}
|
|
141
|
+
return /*#__PURE__*/_jsx(Icon, {
|
|
142
|
+
name: "ic_ai_sparkle",
|
|
143
|
+
size: tokens.iconSize,
|
|
144
|
+
color: tokens.iconColor,
|
|
145
|
+
accessibilityElementsHidden: true,
|
|
146
|
+
importantForAccessibility: "no"
|
|
147
|
+
});
|
|
148
|
+
}, [startSlot, modes, tokens.iconColor, tokens.iconSize]);
|
|
149
|
+
const startSlotWrapper = startSlotElement ? /*#__PURE__*/_jsx(View, {
|
|
150
|
+
style: {
|
|
151
|
+
gap: tokens.startSlotGap,
|
|
152
|
+
alignItems: 'center'
|
|
153
|
+
},
|
|
154
|
+
children: startSlotElement
|
|
155
|
+
}) : null;
|
|
156
|
+
const processedChildren = useMemo(() => {
|
|
157
|
+
if (!children) return null;
|
|
158
|
+
const processed = cloneChildrenWithModes(React.Children.toArray(children), modes);
|
|
159
|
+
return processed.length === 1 ? processed[0] : processed;
|
|
160
|
+
}, [children, modes]);
|
|
161
|
+
const buttonElement = buttonSlot ? cloneChildrenWithModes(React.Children.toArray(buttonSlot), modes) : /*#__PURE__*/_jsx(Button, {
|
|
162
|
+
label: buttonLabel,
|
|
163
|
+
modes: modes,
|
|
164
|
+
...(onPressButton ? {
|
|
165
|
+
onPress: onPressButton
|
|
166
|
+
} : {})
|
|
167
|
+
});
|
|
168
|
+
if (type === 'stacked-detailed') {
|
|
81
169
|
return /*#__PURE__*/_jsxs(View, {
|
|
82
|
-
style: [
|
|
170
|
+
style: [tokens.containerBaseStyle, tokens.detailedContainerStyle, style],
|
|
83
171
|
children: [/*#__PURE__*/_jsxs(View, {
|
|
84
|
-
style:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
gap: 6,
|
|
88
|
-
width: '100%'
|
|
89
|
-
},
|
|
90
|
-
children: [startSlotElement, /*#__PURE__*/_jsx(Text, {
|
|
91
|
-
style: [titleStyle, {
|
|
172
|
+
style: tokens.headerStyle,
|
|
173
|
+
children: [startSlotWrapper, /*#__PURE__*/_jsx(Text, {
|
|
174
|
+
style: [tokens.titleTextStyle, {
|
|
92
175
|
flex: 1
|
|
93
176
|
}],
|
|
94
177
|
children: title
|
|
95
178
|
})]
|
|
96
|
-
}),
|
|
179
|
+
}), processedChildren ? /*#__PURE__*/_jsx(View, {
|
|
180
|
+
style: tokens.detailSlotStyle,
|
|
181
|
+
children: processedChildren
|
|
182
|
+
}) : null]
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
if (type === 'inline-compact') {
|
|
186
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
187
|
+
style: [tokens.containerBaseStyle, tokens.compactContainerStyle, style],
|
|
188
|
+
children: [startSlotWrapper, /*#__PURE__*/_jsx(View, {
|
|
189
|
+
style: tokens.compactOuterContentStyle,
|
|
190
|
+
children: processedChildren || /*#__PURE__*/_jsxs(View, {
|
|
191
|
+
style: tokens.compactContentWrapStyle,
|
|
192
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
193
|
+
style: tokens.compactTextWrapStyle,
|
|
194
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
195
|
+
style: tokens.bodyTextStyle,
|
|
196
|
+
children: body
|
|
197
|
+
})
|
|
198
|
+
}), buttonElement]
|
|
199
|
+
})
|
|
200
|
+
})]
|
|
97
201
|
});
|
|
98
202
|
}
|
|
99
|
-
const
|
|
203
|
+
const prominentContent = /*#__PURE__*/_jsxs(View, {
|
|
100
204
|
style: {
|
|
101
|
-
gap:
|
|
205
|
+
gap: tokens.compactContentWrapStyle.gap,
|
|
102
206
|
alignItems: 'flex-start',
|
|
103
207
|
width: '100%'
|
|
104
208
|
},
|
|
105
209
|
children: [/*#__PURE__*/_jsxs(View, {
|
|
106
|
-
style:
|
|
107
|
-
gap: textGap,
|
|
108
|
-
alignItems: 'flex-start',
|
|
109
|
-
width: '100%'
|
|
110
|
-
},
|
|
210
|
+
style: tokens.textWrapStyle,
|
|
111
211
|
children: [/*#__PURE__*/_jsx(Text, {
|
|
112
|
-
style:
|
|
212
|
+
style: tokens.titleTextStyle,
|
|
113
213
|
children: title
|
|
114
214
|
}), /*#__PURE__*/_jsx(Text, {
|
|
115
|
-
style:
|
|
215
|
+
style: tokens.bodyTextStyle,
|
|
116
216
|
children: body
|
|
117
217
|
})]
|
|
118
|
-
}),
|
|
119
|
-
label: buttonLabel,
|
|
120
|
-
onPress: onPressButton,
|
|
121
|
-
modes: modes
|
|
122
|
-
})]
|
|
218
|
+
}), buttonElement]
|
|
123
219
|
});
|
|
124
220
|
return /*#__PURE__*/_jsxs(View, {
|
|
125
|
-
style: [
|
|
126
|
-
children: [
|
|
127
|
-
style:
|
|
128
|
-
|
|
129
|
-
minWidth: 1,
|
|
130
|
-
minHeight: contentMinHeight,
|
|
131
|
-
justifyContent: 'center',
|
|
132
|
-
overflow: 'hidden'
|
|
133
|
-
},
|
|
134
|
-
children: children ? cloneChildrenWithModes(React.Children.toArray(children), modes) : defaultContent
|
|
221
|
+
style: [tokens.containerBaseStyle, tokens.prominentContainerStyle, style],
|
|
222
|
+
children: [startSlotWrapper, /*#__PURE__*/_jsx(View, {
|
|
223
|
+
style: tokens.contentStyle,
|
|
224
|
+
children: processedChildren || prominentContent
|
|
135
225
|
})]
|
|
136
226
|
});
|
|
137
227
|
}
|
|
228
|
+
const Nudge = /*#__PURE__*/React.memo(NudgeImpl);
|
|
138
229
|
export default Nudge;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { Pressable, View, Platform } from 'react-native';
|
|
5
|
+
import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
|
|
6
|
+
import { EMPTY_MODES } from '../../utils/react-utils';
|
|
7
|
+
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Props
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Radio
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
export function Radio({
|
|
17
|
+
selected = false,
|
|
18
|
+
disabled = false,
|
|
19
|
+
onPress,
|
|
20
|
+
modes = EMPTY_MODES,
|
|
21
|
+
style,
|
|
22
|
+
testID
|
|
23
|
+
}) {
|
|
24
|
+
// ---- Refs & State ----
|
|
25
|
+
const [hovered, setHovered] = useState(false);
|
|
26
|
+
const [focused, setFocused] = useState(false);
|
|
27
|
+
const [pressed, setPressed] = useState(false);
|
|
28
|
+
|
|
29
|
+
// ---- Dimensions ----
|
|
30
|
+
const widthStr = getVariableByName('radio/width', modes) || '18';
|
|
31
|
+
const heightStr = getVariableByName('radio/height', modes) || '18';
|
|
32
|
+
const selectorSizeStr = getVariableByName('radio/selector/size', modes) || '10';
|
|
33
|
+
const width = parseFloat(widthStr?.toString() || '18');
|
|
34
|
+
const height = parseFloat(heightStr?.toString() || '18');
|
|
35
|
+
const selectorSize = parseFloat(selectorSizeStr?.toString() || '10');
|
|
36
|
+
|
|
37
|
+
// ---- State Logic ----
|
|
38
|
+
// Priority: Disabled -> Focused -> Hover/Pressed -> Idle
|
|
39
|
+
// Note: Design treats Active (Pressed) similar to Selected for some styles,
|
|
40
|
+
// but usually in Radios, Pressed is a transient state.
|
|
41
|
+
// We will map:
|
|
42
|
+
// - Disabled -> 'disabled'
|
|
43
|
+
// - Focused -> 'focus'
|
|
44
|
+
// - Hovered -> 'hover'
|
|
45
|
+
// - Idle -> 'idle'
|
|
46
|
+
|
|
47
|
+
// We handle `selected` as a separate dimension derived from state.
|
|
48
|
+
|
|
49
|
+
let visualState = 'idle';
|
|
50
|
+
if (disabled) {
|
|
51
|
+
visualState = 'disabled';
|
|
52
|
+
} else if (focused) {
|
|
53
|
+
visualState = 'focus';
|
|
54
|
+
} else if (hovered || pressed) {
|
|
55
|
+
visualState = 'hover';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Construct token paths based on state + selected
|
|
59
|
+
let prefix = `radio/${visualState}`;
|
|
60
|
+
if (visualState === 'idle' && selected) {
|
|
61
|
+
prefix = `radio/selected`;
|
|
62
|
+
} else if (selected) {
|
|
63
|
+
prefix = `radio/${visualState}Selected`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ---- Colors & Border ----
|
|
67
|
+
|
|
68
|
+
const resolveColor = (path, fallback) => {
|
|
69
|
+
return getVariableByName(path, modes) || fallback;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// Background Color
|
|
73
|
+
let bgColorVar = `${prefix}/background/color`;
|
|
74
|
+
// Fix for disabledSelected weirdness if needed
|
|
75
|
+
if (visualState === 'disabled' && selected) {
|
|
76
|
+
// Check specific path from dump: `radio/disabledSelected/background`
|
|
77
|
+
if (!getVariableByName(`${prefix}/background/color`, modes)) {
|
|
78
|
+
bgColorVar = `${prefix}/background`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Border Color
|
|
83
|
+
let borderColorVar = `${prefix}/border/color`;
|
|
84
|
+
|
|
85
|
+
// Border Width
|
|
86
|
+
let borderWidthVar = `${prefix}/border/size`;
|
|
87
|
+
// Fix for huge path: `radio/disabled/radio/disabled/border/size`
|
|
88
|
+
if (visualState === 'disabled' && !selected) {
|
|
89
|
+
if (getVariableByName('radio/disabled/radio/disabled/border/size', modes)) {
|
|
90
|
+
borderWidthVar = 'radio/disabled/radio/disabled/border/size';
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Selector Color
|
|
95
|
+
let selectorBgVar = `${prefix}/selector/background/color`;
|
|
96
|
+
if (!selected) {
|
|
97
|
+
selectorBgVar = 'transparent';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Shadows (Glow)
|
|
101
|
+
let shadowSizeVar = `${prefix}/boxShadow/size`;
|
|
102
|
+
let shadowColorVar = `${prefix}/shadow/color`;
|
|
103
|
+
|
|
104
|
+
// Resolve Values
|
|
105
|
+
const backgroundColor = resolveColor(bgColorVar, 'transparent');
|
|
106
|
+
const borderColor = resolveColor(borderColorVar, 'transparent');
|
|
107
|
+
const borderWidth = parseFloat(getVariableByName(borderWidthVar, modes)?.toString() || '1');
|
|
108
|
+
const selectorColor = resolveColor(selectorBgVar, 'transparent');
|
|
109
|
+
const shadowSize = parseFloat(getVariableByName(shadowSizeVar, modes)?.toString() || '0');
|
|
110
|
+
const shadowColor = resolveColor(shadowColorVar, 'transparent');
|
|
111
|
+
|
|
112
|
+
// Styles
|
|
113
|
+
const containerStyle = {
|
|
114
|
+
width,
|
|
115
|
+
height,
|
|
116
|
+
borderRadius: width / 2,
|
|
117
|
+
// 9999px -> circle
|
|
118
|
+
borderWidth,
|
|
119
|
+
borderColor,
|
|
120
|
+
backgroundColor,
|
|
121
|
+
justifyContent: 'center',
|
|
122
|
+
alignItems: 'center',
|
|
123
|
+
// Web shadow (ring)
|
|
124
|
+
...(Platform.OS === 'web' && shadowSize > 0 ? {
|
|
125
|
+
boxShadow: `0px 0px 0px ${shadowSize}px ${shadowColor}`
|
|
126
|
+
} : {})
|
|
127
|
+
};
|
|
128
|
+
const selectorStyle = {
|
|
129
|
+
width: selectorSize,
|
|
130
|
+
height: selectorSize,
|
|
131
|
+
borderRadius: selectorSize / 2,
|
|
132
|
+
backgroundColor: selectorColor
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Dummy block for token extraction (static analysis)
|
|
136
|
+
if (false) {
|
|
137
|
+
getVariableByName('radio/idle/background/color');
|
|
138
|
+
getVariableByName('radio/idle/border/color');
|
|
139
|
+
getVariableByName('radio/selector/size');
|
|
140
|
+
getVariableByName('radio/width');
|
|
141
|
+
getVariableByName('radio/height');
|
|
142
|
+
getVariableByName('radio/background/color');
|
|
143
|
+
getVariableByName('radio/hover/background/color');
|
|
144
|
+
getVariableByName('radio/hover/border/color');
|
|
145
|
+
getVariableByName('radio/hover/boxShadow/size');
|
|
146
|
+
getVariableByName('radio/hover/shadow/color');
|
|
147
|
+
getVariableByName('radio/selected/background/color');
|
|
148
|
+
getVariableByName('radio/selected/border/color');
|
|
149
|
+
getVariableByName('radio/selected/selector/background/color');
|
|
150
|
+
getVariableByName('radio/hoverSelected/background/color');
|
|
151
|
+
getVariableByName('radio/hoverSelected/border/color');
|
|
152
|
+
getVariableByName('radio/hoverSelected/boxShadow/size');
|
|
153
|
+
getVariableByName('radio/hoverSelected/shadow/color');
|
|
154
|
+
getVariableByName('radio/hoverSelected/selector/background/color');
|
|
155
|
+
getVariableByName('radio/focus/background/color');
|
|
156
|
+
getVariableByName('radio/focus/border/color');
|
|
157
|
+
getVariableByName('radio/focus/border/size');
|
|
158
|
+
getVariableByName('radio/focus/boxShadow/size');
|
|
159
|
+
getVariableByName('radio/focus/shadow/color');
|
|
160
|
+
getVariableByName('radio/focusSelected/background/color');
|
|
161
|
+
getVariableByName('radio/focusSelected/selector/background/color');
|
|
162
|
+
getVariableByName('radio/focusSelected/border/size');
|
|
163
|
+
getVariableByName('radio/disabled/radio/disabled/border/size');
|
|
164
|
+
getVariableByName('radio/disabled/background/color');
|
|
165
|
+
getVariableByName('radio/disabled/border/color');
|
|
166
|
+
getVariableByName('radio/disabledSelected/selector/background/color');
|
|
167
|
+
getVariableByName('radio/disabledSelected/background');
|
|
168
|
+
getVariableByName('radio/disabledSelected/border/color');
|
|
169
|
+
}
|
|
170
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
171
|
+
testID: testID,
|
|
172
|
+
disabled: disabled,
|
|
173
|
+
onPress: onPress,
|
|
174
|
+
onHoverIn: () => setHovered(true),
|
|
175
|
+
onHoverOut: () => setHovered(false),
|
|
176
|
+
onFocus: () => setFocused(true),
|
|
177
|
+
onBlur: () => setFocused(false),
|
|
178
|
+
onPressIn: () => setPressed(true),
|
|
179
|
+
onPressOut: () => setPressed(false),
|
|
180
|
+
style: ({
|
|
181
|
+
pressed: isPressed
|
|
182
|
+
}) => [containerStyle, style],
|
|
183
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
184
|
+
style: selectorStyle
|
|
185
|
+
})
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
export default Radio;
|