jfs-components 0.0.71 → 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.
Files changed (35) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/lib/commonjs/components/CardAdvisory/CardAdvisory.js +2 -2
  3. package/lib/commonjs/components/CardFinancialCondition/CardFinancialCondition.js +213 -0
  4. package/lib/commonjs/components/Carousel/Carousel.js +9 -7
  5. package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +2 -2
  6. package/lib/commonjs/components/InstitutionBadge/InstitutionBadge.js +132 -0
  7. package/lib/commonjs/components/Radio/Radio.js +194 -0
  8. package/lib/commonjs/components/RadioButton/RadioButton.js +21 -188
  9. package/lib/commonjs/components/index.js +21 -0
  10. package/lib/commonjs/icons/registry.js +1 -1
  11. package/lib/module/components/CardAdvisory/CardAdvisory.js +2 -2
  12. package/lib/module/components/CardFinancialCondition/CardFinancialCondition.js +207 -0
  13. package/lib/module/components/Carousel/Carousel.js +9 -7
  14. package/lib/module/components/HoldingsCard/HoldingsCard.js +2 -2
  15. package/lib/module/components/InstitutionBadge/InstitutionBadge.js +127 -0
  16. package/lib/module/components/Radio/Radio.js +188 -0
  17. package/lib/module/components/RadioButton/RadioButton.js +20 -185
  18. package/lib/module/components/index.js +7 -0
  19. package/lib/module/icons/registry.js +1 -1
  20. package/lib/typescript/src/components/CardFinancialCondition/CardFinancialCondition.d.ts +50 -0
  21. package/lib/typescript/src/components/InstitutionBadge/InstitutionBadge.d.ts +30 -0
  22. package/lib/typescript/src/components/Radio/Radio.d.ts +30 -0
  23. package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +20 -28
  24. package/lib/typescript/src/components/index.d.ts +7 -0
  25. package/lib/typescript/src/icons/registry.d.ts +1 -1
  26. package/package.json +1 -1
  27. package/src/components/CardAdvisory/CardAdvisory.tsx +2 -2
  28. package/src/components/CardFinancialCondition/CardFinancialCondition.tsx +366 -0
  29. package/src/components/Carousel/Carousel.tsx +14 -6
  30. package/src/components/HoldingsCard/HoldingsCard.tsx +2 -2
  31. package/src/components/InstitutionBadge/InstitutionBadge.tsx +216 -0
  32. package/src/components/Radio/Radio.tsx +227 -0
  33. package/src/components/RadioButton/RadioButton.tsx +23 -225
  34. package/src/components/index.ts +7 -0
  35. package/src/icons/registry.ts +1 -1
@@ -0,0 +1,216 @@
1
+ import React, { useMemo } from 'react'
2
+ import {
3
+ Text,
4
+ View,
5
+ type StyleProp,
6
+ type TextStyle,
7
+ type ViewStyle,
8
+ } from 'react-native'
9
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
10
+ import { useTokens } from '../../design-tokens/JFSThemeProvider'
11
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
12
+ import MediaSource, { type UnifiedSource } from '../../utils/MediaSource'
13
+
14
+ // Default avatar asset (shared with the Avatar component) so that
15
+ // InstitutionBadge has a sensible visual fallback when no `source` is
16
+ // provided in stories or playgrounds.
17
+ const DEFAULT_AVATAR_IMAGE = require('../Avatar/31595e70c4181263f9971590224b12934b280c9b.png')
18
+
19
+ type InstitutionBadgeBaseProps = Omit<
20
+ React.ComponentProps<typeof View>,
21
+ 'children' | 'style'
22
+ >
23
+
24
+ export type InstitutionBadgeProps = InstitutionBadgeBaseProps & {
25
+ /** Visible label for the institution (e.g. bank name). */
26
+ label?: string
27
+ /**
28
+ * Unified avatar source. Accepts a remote URI (raster or `.svg`), an
29
+ * inline SVG XML string, a `require()` asset, an SVG React component,
30
+ * or an already-rendered React element. Smart-detects raster vs SVG so
31
+ * the same prop works on iOS, Android and web. See {@link UnifiedSource}.
32
+ * Ignored when `avatarSlot` is provided.
33
+ */
34
+ source?: UnifiedSource
35
+ /** Slot replacing the default Avatar (e.g. for monogram avatars). Receives `modes` recursively. */
36
+ avatarSlot?: React.ReactNode
37
+ /** Design token modes forwarded to token lookups and the Avatar slot. */
38
+ modes?: Record<string, any>
39
+ /** Container style override. */
40
+ style?: StyleProp<ViewStyle>
41
+ /** Label style override. */
42
+ labelStyle?: StyleProp<TextStyle>
43
+ /** Accessibility label. Defaults to `label`. */
44
+ accessibilityLabel?: string
45
+ }
46
+
47
+ interface InstitutionBadgeTokens {
48
+ containerStyle: ViewStyle
49
+ avatarStyle: ViewStyle
50
+ avatarSize: number
51
+ labelStyle: TextStyle
52
+ }
53
+
54
+ const toNumber = (value: unknown, fallback: number) => {
55
+ if (typeof value === 'number') {
56
+ return Number.isFinite(value) ? value : fallback
57
+ }
58
+
59
+ if (typeof value === 'string') {
60
+ const parsed = Number(value)
61
+ return Number.isFinite(parsed) ? parsed : fallback
62
+ }
63
+
64
+ return fallback
65
+ }
66
+
67
+ const toFontWeight = (value: unknown, fallback: TextStyle['fontWeight']) => {
68
+ if (typeof value === 'number') {
69
+ return String(value) as TextStyle['fontWeight']
70
+ }
71
+
72
+ if (typeof value === 'string') {
73
+ return value as TextStyle['fontWeight']
74
+ }
75
+
76
+ return fallback
77
+ }
78
+
79
+ function resolveInstitutionBadgeTokens(
80
+ modes: Record<string, any>
81
+ ): InstitutionBadgeTokens {
82
+ const gap = toNumber(getVariableByName('institutionBadge/gap', modes), 8)
83
+
84
+ const foreground =
85
+ (getVariableByName('institutionBadge/foreground', modes) as string) ||
86
+ '#080d1a'
87
+ const fontSize = toNumber(
88
+ getVariableByName('institutionBadge/fontSize', modes),
89
+ 14
90
+ )
91
+ const fontFamily =
92
+ (getVariableByName('institutionBadge/fontFamily', modes) as string) ||
93
+ 'JioType Var'
94
+ const lineHeight = toNumber(
95
+ getVariableByName('institutionBadge/lineHeight', modes),
96
+ 18
97
+ )
98
+ const fontWeight = toFontWeight(
99
+ getVariableByName('institutionBadge/fontWeight', modes),
100
+ '500'
101
+ )
102
+
103
+ // Avatar wrapper styled from shared `avatar/*` tokens so the badge stays
104
+ // visually consistent with other Avatar-bearing components.
105
+ const avatarSize = toNumber(getVariableByName('avatar/size', modes), 36)
106
+ const avatarRadiusRaw = toNumber(
107
+ getVariableByName('avatar/radius', modes),
108
+ 9999
109
+ )
110
+ // 9999 is the design-token sentinel for "perfect circle".
111
+ const avatarRadius = avatarRadiusRaw === 9999 ? avatarSize / 2 : avatarRadiusRaw
112
+ const avatarBorderColor =
113
+ (getVariableByName('avatar/border/color', modes) as string) ||
114
+ 'rgba(255,255,255,0)'
115
+ const avatarBorderSize = toNumber(
116
+ getVariableByName('avatar/border/size', modes),
117
+ 1
118
+ )
119
+
120
+ return {
121
+ containerStyle: {
122
+ alignItems: 'center',
123
+ flexDirection: 'row',
124
+ gap,
125
+ },
126
+ avatarStyle: {
127
+ width: avatarSize,
128
+ height: avatarSize,
129
+ borderRadius: avatarRadius,
130
+ borderWidth: avatarBorderSize,
131
+ borderColor: avatarBorderColor,
132
+ overflow: 'hidden',
133
+ },
134
+ avatarSize,
135
+ labelStyle: {
136
+ color: foreground,
137
+ fontFamily,
138
+ fontSize,
139
+ fontWeight,
140
+ lineHeight,
141
+ },
142
+ }
143
+ }
144
+
145
+ // Default Avatar Size = M (36px in tokens) — matches the Figma badge. Callers
146
+ // can override via `modes` if needed.
147
+ const DEFAULT_AVATAR_MODE = 'M'
148
+
149
+ function InstitutionBadge({
150
+ label = 'State Bank of India',
151
+ source,
152
+ avatarSlot,
153
+ modes: propModes = EMPTY_MODES,
154
+ style,
155
+ labelStyle,
156
+ accessibilityLabel,
157
+ ...rest
158
+ }: InstitutionBadgeProps) {
159
+ const { modes: globalModes } = useTokens()
160
+ const modes = useMemo(
161
+ () =>
162
+ globalModes === EMPTY_MODES && propModes === EMPTY_MODES
163
+ ? EMPTY_MODES
164
+ : { ...globalModes, ...propModes },
165
+ [globalModes, propModes]
166
+ )
167
+
168
+ const avatarModes = useMemo(
169
+ () => ({ 'Avatar Size': DEFAULT_AVATAR_MODE, ...modes }),
170
+ [modes]
171
+ )
172
+
173
+ const tokens = useMemo(
174
+ () => resolveInstitutionBadgeTokens(avatarModes),
175
+ [avatarModes]
176
+ )
177
+
178
+ const processedAvatarSlot = useMemo(() => {
179
+ if (!avatarSlot) return null
180
+ const processed = cloneChildrenWithModes(
181
+ React.Children.toArray(avatarSlot),
182
+ avatarModes
183
+ )
184
+ return processed.length === 1 ? processed[0] : processed
185
+ }, [avatarSlot, avatarModes])
186
+
187
+ const resolvedSource: UnifiedSource =
188
+ (source as UnifiedSource | undefined) ?? (DEFAULT_AVATAR_IMAGE as UnifiedSource)
189
+
190
+ const defaultAccessibilityLabel = accessibilityLabel ?? label
191
+
192
+ return (
193
+ <View
194
+ accessibilityLabel={defaultAccessibilityLabel}
195
+ style={[tokens.containerStyle, style]}
196
+ {...rest}
197
+ >
198
+ {processedAvatarSlot || (
199
+ <View style={tokens.avatarStyle}>
200
+ <MediaSource
201
+ source={resolvedSource}
202
+ size={tokens.avatarSize}
203
+ resizeMode="cover"
204
+ accessibilityElementsHidden={true}
205
+ importantForAccessibility="no"
206
+ />
207
+ </View>
208
+ )}
209
+ <Text style={[tokens.labelStyle, labelStyle]} numberOfLines={1}>
210
+ {label}
211
+ </Text>
212
+ </View>
213
+ )
214
+ }
215
+
216
+ export default React.memo(InstitutionBadge)
@@ -0,0 +1,227 @@
1
+ import React, { useMemo, useState } from 'react'
2
+ import {
3
+ Pressable,
4
+ View,
5
+ StyleSheet,
6
+ Platform,
7
+ ViewStyle,
8
+ DimensionValue,
9
+ StyleProp,
10
+ } from 'react-native'
11
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
12
+ import { EMPTY_MODES } from '../../utils/react-utils'
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Props
16
+ // ---------------------------------------------------------------------------
17
+
18
+ export interface RadioProps {
19
+ /**
20
+ * Whether the radio is selected.
21
+ */
22
+ selected?: boolean
23
+ /**
24
+ * Whether the radio is disabled.
25
+ */
26
+ disabled?: boolean
27
+ /**
28
+ * Function to call when the radio is pressed.
29
+ */
30
+ onPress?: () => void
31
+ /**
32
+ * Modes object for design-token resolution.
33
+ */
34
+ modes?: Record<string, any>
35
+ /**
36
+ * Custom style for the radio container.
37
+ */
38
+ style?: StyleProp<ViewStyle>
39
+ /**
40
+ * Test ID for testing.
41
+ */
42
+ testID?: string
43
+ }
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Radio
47
+ // ---------------------------------------------------------------------------
48
+
49
+ export function Radio({
50
+ selected = false,
51
+ disabled = false,
52
+ onPress,
53
+ modes = EMPTY_MODES,
54
+ style,
55
+ testID,
56
+ }: RadioProps) {
57
+ // ---- Refs & State ----
58
+ const [hovered, setHovered] = useState(false)
59
+ const [focused, setFocused] = useState(false)
60
+ const [pressed, setPressed] = useState(false)
61
+
62
+ // ---- Dimensions ----
63
+ const widthStr = getVariableByName('radio/width', modes) || '18'
64
+ const heightStr = getVariableByName('radio/height', modes) || '18'
65
+ const selectorSizeStr = getVariableByName('radio/selector/size', modes) || '10'
66
+
67
+ const width = parseFloat(widthStr?.toString() || '18')
68
+ const height = parseFloat(heightStr?.toString() || '18')
69
+ const selectorSize = parseFloat(selectorSizeStr?.toString() || '10')
70
+
71
+ // ---- State Logic ----
72
+ // Priority: Disabled -> Focused -> Hover/Pressed -> Idle
73
+ // Note: Design treats Active (Pressed) similar to Selected for some styles,
74
+ // but usually in Radios, Pressed is a transient state.
75
+ // We will map:
76
+ // - Disabled -> 'disabled'
77
+ // - Focused -> 'focus'
78
+ // - Hovered -> 'hover'
79
+ // - Idle -> 'idle'
80
+
81
+ // We handle `selected` as a separate dimension derived from state.
82
+
83
+ let visualState = 'idle'
84
+ if (disabled) {
85
+ visualState = 'disabled'
86
+ } else if (focused) {
87
+ visualState = 'focus'
88
+ } else if (hovered || pressed) {
89
+ visualState = 'hover'
90
+ }
91
+
92
+ // Construct token paths based on state + selected
93
+ let prefix = `radio/${visualState}`
94
+ if (visualState === 'idle' && selected) {
95
+ prefix = `radio/selected`
96
+ } else if (selected) {
97
+ prefix = `radio/${visualState}Selected`
98
+ }
99
+
100
+ // ---- Colors & Border ----
101
+
102
+ const resolveColor = (path: string, fallback: string) => {
103
+ return getVariableByName(path, modes) || fallback
104
+ }
105
+
106
+ // Background Color
107
+ let bgColorVar = `${prefix}/background/color`
108
+ // Fix for disabledSelected weirdness if needed
109
+ if (visualState === 'disabled' && selected) {
110
+ // Check specific path from dump: `radio/disabledSelected/background`
111
+ if (!getVariableByName(`${prefix}/background/color`, modes)) {
112
+ bgColorVar = `${prefix}/background`
113
+ }
114
+ }
115
+
116
+ // Border Color
117
+ let borderColorVar = `${prefix}/border/color`
118
+
119
+ // Border Width
120
+ let borderWidthVar = `${prefix}/border/size`
121
+ // Fix for huge path: `radio/disabled/radio/disabled/border/size`
122
+ if (visualState === 'disabled' && !selected) {
123
+ if (getVariableByName('radio/disabled/radio/disabled/border/size', modes)) {
124
+ borderWidthVar = 'radio/disabled/radio/disabled/border/size'
125
+ }
126
+ }
127
+
128
+ // Selector Color
129
+ let selectorBgVar = `${prefix}/selector/background/color`
130
+ if (!selected) {
131
+ selectorBgVar = 'transparent'
132
+ }
133
+
134
+ // Shadows (Glow)
135
+ let shadowSizeVar = `${prefix}/boxShadow/size`
136
+ let shadowColorVar = `${prefix}/shadow/color`
137
+
138
+ // Resolve Values
139
+ const backgroundColor = resolveColor(bgColorVar, 'transparent')
140
+ const borderColor = resolveColor(borderColorVar, 'transparent')
141
+ const borderWidth = parseFloat(getVariableByName(borderWidthVar, modes)?.toString() || '1')
142
+ const selectorColor = resolveColor(selectorBgVar, 'transparent')
143
+
144
+ const shadowSize = parseFloat(getVariableByName(shadowSizeVar, modes)?.toString() || '0')
145
+ const shadowColor = resolveColor(shadowColorVar, 'transparent')
146
+
147
+ // Styles
148
+ const containerStyle: any = {
149
+ width,
150
+ height,
151
+ borderRadius: width / 2, // 9999px -> circle
152
+ borderWidth,
153
+ borderColor,
154
+ backgroundColor,
155
+ justifyContent: 'center',
156
+ alignItems: 'center',
157
+ // Web shadow (ring)
158
+ ...(Platform.OS === 'web' && shadowSize > 0 ? {
159
+ boxShadow: `0px 0px 0px ${shadowSize}px ${shadowColor}`,
160
+ } : {}),
161
+ }
162
+
163
+ const selectorStyle: ViewStyle = {
164
+ width: selectorSize,
165
+ height: selectorSize,
166
+ borderRadius: selectorSize / 2,
167
+ backgroundColor: selectorColor,
168
+ }
169
+
170
+ // Dummy block for token extraction (static analysis)
171
+ if (false as boolean) {
172
+ getVariableByName('radio/idle/background/color')
173
+ getVariableByName('radio/idle/border/color')
174
+ getVariableByName('radio/selector/size')
175
+ getVariableByName('radio/width')
176
+ getVariableByName('radio/height')
177
+ getVariableByName('radio/background/color')
178
+ getVariableByName('radio/hover/background/color')
179
+ getVariableByName('radio/hover/border/color')
180
+ getVariableByName('radio/hover/boxShadow/size')
181
+ getVariableByName('radio/hover/shadow/color')
182
+ getVariableByName('radio/selected/background/color')
183
+ getVariableByName('radio/selected/border/color')
184
+ getVariableByName('radio/selected/selector/background/color')
185
+ getVariableByName('radio/hoverSelected/background/color')
186
+ getVariableByName('radio/hoverSelected/border/color')
187
+ getVariableByName('radio/hoverSelected/boxShadow/size')
188
+ getVariableByName('radio/hoverSelected/shadow/color')
189
+ getVariableByName('radio/hoverSelected/selector/background/color')
190
+ getVariableByName('radio/focus/background/color')
191
+ getVariableByName('radio/focus/border/color')
192
+ getVariableByName('radio/focus/border/size')
193
+ getVariableByName('radio/focus/boxShadow/size')
194
+ getVariableByName('radio/focus/shadow/color')
195
+ getVariableByName('radio/focusSelected/background/color')
196
+ getVariableByName('radio/focusSelected/selector/background/color')
197
+ getVariableByName('radio/focusSelected/border/size')
198
+ getVariableByName('radio/disabled/radio/disabled/border/size')
199
+ getVariableByName('radio/disabled/background/color')
200
+ getVariableByName('radio/disabled/border/color')
201
+ getVariableByName('radio/disabledSelected/selector/background/color')
202
+ getVariableByName('radio/disabledSelected/background')
203
+ getVariableByName('radio/disabledSelected/border/color')
204
+ }
205
+
206
+ return (
207
+ <Pressable
208
+ testID={testID}
209
+ disabled={disabled}
210
+ onPress={onPress}
211
+ onHoverIn={() => setHovered(true)}
212
+ onHoverOut={() => setHovered(false)}
213
+ onFocus={() => setFocused(true)}
214
+ onBlur={() => setFocused(false)}
215
+ onPressIn={() => setPressed(true)}
216
+ onPressOut={() => setPressed(false)}
217
+ style={({ pressed: isPressed }) => [
218
+ containerStyle,
219
+ style,
220
+ ]}
221
+ >
222
+ <View style={selectorStyle} />
223
+ </Pressable>
224
+ )
225
+ }
226
+
227
+ export default Radio
@@ -1,227 +1,25 @@
1
- import React, { useMemo, useState } from 'react'
2
- import {
3
- Pressable,
4
- View,
5
- StyleSheet,
6
- Platform,
7
- ViewStyle,
8
- DimensionValue,
9
- StyleProp,
10
- } from 'react-native'
11
- import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
12
- import { EMPTY_MODES } from '../../utils/react-utils'
13
-
14
- // ---------------------------------------------------------------------------
15
- // Props
16
- // ---------------------------------------------------------------------------
17
-
18
- export interface RadioButtonProps {
19
- /**
20
- * Whether the radio button is selected.
21
- */
22
- selected?: boolean
23
- /**
24
- * Whether the radio button is disabled.
25
- */
26
- disabled?: boolean
27
- /**
28
- * Function to call when the radio button is pressed.
29
- */
30
- onPress?: () => void
31
- /**
32
- * Modes object for design-token resolution.
33
- */
34
- modes?: Record<string, any>
35
- /**
36
- * Custom style for the radio button container.
37
- */
38
- style?: StyleProp<ViewStyle>
39
- /**
40
- * Test ID for testing.
41
- */
42
- testID?: string
43
- }
44
-
45
- // ---------------------------------------------------------------------------
46
- // RadioButton
47
- // ---------------------------------------------------------------------------
48
-
49
- export function RadioButton({
50
- selected = false,
51
- disabled = false,
52
- onPress,
53
- modes = EMPTY_MODES,
54
- style,
55
- testID,
56
- }: RadioButtonProps) {
57
- // ---- Refs & State ----
58
- const [hovered, setHovered] = useState(false)
59
- const [focused, setFocused] = useState(false)
60
- const [pressed, setPressed] = useState(false)
61
-
62
- // ---- Dimensions ----
63
- const widthStr = getVariableByName('radio/width', modes) || '18'
64
- const heightStr = getVariableByName('radio/height', modes) || '18'
65
- const selectorSizeStr = getVariableByName('radio/selector/size', modes) || '10'
66
-
67
- const width = parseFloat(widthStr?.toString() || '18')
68
- const height = parseFloat(heightStr?.toString() || '18')
69
- const selectorSize = parseFloat(selectorSizeStr?.toString() || '10')
70
-
71
- // ---- State Logic ----
72
- // Priority: Disabled -> Focused -> Hover/Pressed -> Idle
73
- // Note: Design treats Active (Pressed) similar to Selected for some styles,
74
- // but usually in Radio Buttons, Pressed is a transient state.
75
- // We will map:
76
- // - Disabled -> 'disabled'
77
- // - Focused -> 'focus'
78
- // - Hovered -> 'hover'
79
- // - Idle -> 'idle'
80
-
81
- // We handle `selected` as a separate dimension derived from state.
82
-
83
- let visualState = 'idle'
84
- if (disabled) {
85
- visualState = 'disabled'
86
- } else if (focused) {
87
- visualState = 'focus'
88
- } else if (hovered || pressed) {
89
- visualState = 'hover'
90
- }
91
-
92
- // Construct token paths based on state + selected
93
- let prefix = `radio/${visualState}`
94
- if (visualState === 'idle' && selected) {
95
- prefix = `radio/selected`
96
- } else if (selected) {
97
- prefix = `radio/${visualState}Selected`
98
- }
99
-
100
- // ---- Colors & Border ----
101
-
102
- const resolveColor = (path: string, fallback: string) => {
103
- return getVariableByName(path, modes) || fallback
104
- }
105
-
106
- // Background Color
107
- let bgColorVar = `${prefix}/background/color`
108
- // Fix for disabledSelected weirdness if needed
109
- if (visualState === 'disabled' && selected) {
110
- // Check specific path from dump: `radio/disabledSelected/background`
111
- if (!getVariableByName(`${prefix}/background/color`, modes)) {
112
- bgColorVar = `${prefix}/background`
113
- }
114
- }
115
-
116
- // Border Color
117
- let borderColorVar = `${prefix}/border/color`
118
-
119
- // Border Width
120
- let borderWidthVar = `${prefix}/border/size`
121
- // Fix for huge path: `radio/disabled/radio/disabled/border/size`
122
- if (visualState === 'disabled' && !selected) {
123
- if (getVariableByName('radio/disabled/radio/disabled/border/size', modes)) {
124
- borderWidthVar = 'radio/disabled/radio/disabled/border/size'
125
- }
126
- }
127
-
128
- // Selector Color
129
- let selectorBgVar = `${prefix}/selector/background/color`
130
- if (!selected) {
131
- selectorBgVar = 'transparent'
132
- }
133
-
134
- // Shadows (Glow)
135
- let shadowSizeVar = `${prefix}/boxShadow/size`
136
- let shadowColorVar = `${prefix}/shadow/color`
137
-
138
- // Resolve Values
139
- const backgroundColor = resolveColor(bgColorVar, 'transparent')
140
- const borderColor = resolveColor(borderColorVar, 'transparent')
141
- const borderWidth = parseFloat(getVariableByName(borderWidthVar, modes)?.toString() || '1')
142
- const selectorColor = resolveColor(selectorBgVar, 'transparent')
143
-
144
- const shadowSize = parseFloat(getVariableByName(shadowSizeVar, modes)?.toString() || '0')
145
- const shadowColor = resolveColor(shadowColorVar, 'transparent')
146
-
147
- // Styles
148
- const containerStyle: any = {
149
- width,
150
- height,
151
- borderRadius: width / 2, // 9999px -> circle
152
- borderWidth,
153
- borderColor,
154
- backgroundColor,
155
- justifyContent: 'center',
156
- alignItems: 'center',
157
- // Web shadow (ring)
158
- ...(Platform.OS === 'web' && shadowSize > 0 ? {
159
- boxShadow: `0px 0px 0px ${shadowSize}px ${shadowColor}`,
160
- } : {}),
161
- }
162
-
163
- const selectorStyle: ViewStyle = {
164
- width: selectorSize,
165
- height: selectorSize,
166
- borderRadius: selectorSize / 2,
167
- backgroundColor: selectorColor,
168
- }
169
-
170
- // Dummy block for token extraction (static analysis)
171
- if (false as boolean) {
172
- getVariableByName('radio/idle/background/color')
173
- getVariableByName('radio/idle/border/color')
174
- getVariableByName('radio/selector/size')
175
- getVariableByName('radio/width')
176
- getVariableByName('radio/height')
177
- getVariableByName('radio/background/color')
178
- getVariableByName('radio/hover/background/color')
179
- getVariableByName('radio/hover/border/color')
180
- getVariableByName('radio/hover/boxShadow/size')
181
- getVariableByName('radio/hover/shadow/color')
182
- getVariableByName('radio/selected/background/color')
183
- getVariableByName('radio/selected/border/color')
184
- getVariableByName('radio/selected/selector/background/color')
185
- getVariableByName('radio/hoverSelected/background/color')
186
- getVariableByName('radio/hoverSelected/border/color')
187
- getVariableByName('radio/hoverSelected/boxShadow/size')
188
- getVariableByName('radio/hoverSelected/shadow/color')
189
- getVariableByName('radio/hoverSelected/selector/background/color')
190
- getVariableByName('radio/focus/background/color')
191
- getVariableByName('radio/focus/border/color')
192
- getVariableByName('radio/focus/border/size')
193
- getVariableByName('radio/focus/boxShadow/size')
194
- getVariableByName('radio/focus/shadow/color')
195
- getVariableByName('radio/focusSelected/background/color')
196
- getVariableByName('radio/focusSelected/selector/background/color')
197
- getVariableByName('radio/focusSelected/border/size')
198
- getVariableByName('radio/disabled/radio/disabled/border/size')
199
- getVariableByName('radio/disabled/background/color')
200
- getVariableByName('radio/disabled/border/color')
201
- getVariableByName('radio/disabledSelected/selector/background/color')
202
- getVariableByName('radio/disabledSelected/background')
203
- getVariableByName('radio/disabledSelected/border/color')
204
- }
205
-
206
- return (
207
- <Pressable
208
- testID={testID}
209
- disabled={disabled}
210
- onPress={onPress}
211
- onHoverIn={() => setHovered(true)}
212
- onHoverOut={() => setHovered(false)}
213
- onFocus={() => setFocused(true)}
214
- onBlur={() => setFocused(false)}
215
- onPressIn={() => setPressed(true)}
216
- onPressOut={() => setPressed(false)}
217
- style={({ pressed: isPressed }) => [
218
- containerStyle,
219
- style,
220
- ]}
221
- >
222
- <View style={selectorStyle} />
223
- </Pressable>
224
- )
225
- }
1
+ /**
2
+ * @deprecated `RadioButton` has been renamed to `Radio`.
3
+ *
4
+ * This file is kept as a backward-compatibility shim for teams that may be
5
+ * importing `RadioButton` directly from this deep path:
6
+ *
7
+ * import RadioButton from 'jfs-components/src/components/RadioButton/RadioButton'
8
+ * import { RadioButton, RadioButtonProps } from '...'
9
+ *
10
+ * The recommended public import is now:
11
+ *
12
+ * import { Radio, type RadioProps } from 'jfs-components'
13
+ *
14
+ * Going forward, this component is called `Radio`. This shim only re-exports
15
+ * the new `Radio` component under the old `RadioButton` names; please migrate
16
+ * existing usages to `Radio` at your earliest convenience.
17
+ */
18
+
19
+ import { Radio, type RadioProps } from '../Radio/Radio'
20
+
21
+ export type RadioButtonProps = RadioProps
22
+
23
+ export const RadioButton = Radio
226
24
 
227
25
  export default RadioButton