jfs-components 0.1.2 → 0.1.8
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 +29 -0
- package/lib/commonjs/components/AmountInput/AmountInput.js +8 -5
- package/lib/commonjs/components/BenefitCard/BenefitCard.js +231 -0
- package/lib/commonjs/components/CcCard/CcCard.js +470 -0
- package/lib/commonjs/components/Checkbox/Checkbox.js +4 -3
- package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +4 -3
- package/lib/commonjs/components/CompareTable/CompareTable.js +372 -0
- package/lib/commonjs/components/ComparisonBar/ComparisonBar.js +266 -0
- package/lib/commonjs/components/DropdownInput/DropdownInput.js +35 -3
- package/lib/commonjs/components/FormField/FormField.js +4 -3
- package/lib/commonjs/components/InputSearch/InputSearch.js +6 -4
- package/lib/commonjs/components/NoteInput/NoteInput.js +6 -5
- package/lib/commonjs/components/PdpCcCard/PdpCcCard.js +273 -0
- package/lib/commonjs/components/ProductMerchandisingCard/GlassFill.js +263 -0
- package/lib/commonjs/components/ProductMerchandisingCard/GlassFill.web.js +116 -0
- package/lib/commonjs/components/ProductMerchandisingCard/ProductMerchandisingCard.js +353 -0
- package/lib/commonjs/components/ProjectionMarker/ProjectionMarker.js +161 -0
- package/lib/commonjs/components/Radio/Radio.js +5 -5
- package/lib/commonjs/components/Slider/Slider.js +473 -0
- package/lib/commonjs/components/TextInput/TextInput.js +13 -8
- package/lib/commonjs/components/TextSegment/TextSegment.js +118 -0
- package/lib/commonjs/components/index.js +63 -0
- package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/commonjs/design-tokens/figma-modes.generated.js +38 -9
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/commonjs/utils/react-utils.js +22 -0
- package/lib/module/components/AmountInput/AmountInput.js +6 -4
- package/lib/module/components/BenefitCard/BenefitCard.js +225 -0
- package/lib/module/components/CcCard/CcCard.js +464 -0
- package/lib/module/components/Checkbox/Checkbox.js +5 -4
- package/lib/module/components/CheckboxItem/CheckboxItem.js +5 -4
- package/lib/module/components/CompareTable/CompareTable.js +367 -0
- package/lib/module/components/ComparisonBar/ComparisonBar.js +260 -0
- package/lib/module/components/DropdownInput/DropdownInput.js +36 -4
- package/lib/module/components/FormField/FormField.js +5 -4
- package/lib/module/components/InputSearch/InputSearch.js +6 -4
- package/lib/module/components/NoteInput/NoteInput.js +7 -6
- package/lib/module/components/PdpCcCard/PdpCcCard.js +267 -0
- package/lib/module/components/ProductMerchandisingCard/GlassFill.js +257 -0
- package/lib/module/components/ProductMerchandisingCard/GlassFill.web.js +111 -0
- package/lib/module/components/ProductMerchandisingCard/ProductMerchandisingCard.js +347 -0
- package/lib/module/components/ProjectionMarker/ProjectionMarker.js +156 -0
- package/lib/module/components/Radio/Radio.js +5 -4
- package/lib/module/components/Slider/Slider.js +468 -0
- package/lib/module/components/TextInput/TextInput.js +15 -10
- package/lib/module/components/TextSegment/TextSegment.js +113 -0
- package/lib/module/components/index.js +9 -0
- package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/module/design-tokens/figma-modes.generated.js +38 -9
- package/lib/module/icons/registry.js +1 -1
- package/lib/module/utils/react-utils.js +21 -0
- package/lib/typescript/src/components/AmountInput/AmountInput.d.ts +3 -2
- package/lib/typescript/src/components/BenefitCard/BenefitCard.d.ts +93 -0
- package/lib/typescript/src/components/CcCard/CcCard.d.ts +137 -0
- package/lib/typescript/src/components/Checkbox/Checkbox.d.ts +3 -2
- package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +2 -2
- package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +88 -0
- package/lib/typescript/src/components/ComparisonBar/ComparisonBar.d.ts +118 -0
- package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +20 -1
- package/lib/typescript/src/components/FormField/FormField.d.ts +2 -2
- package/lib/typescript/src/components/InputSearch/InputSearch.d.ts +23 -2
- package/lib/typescript/src/components/NoteInput/NoteInput.d.ts +19 -2
- package/lib/typescript/src/components/PdpCcCard/PdpCcCard.d.ts +84 -0
- package/lib/typescript/src/components/ProductMerchandisingCard/GlassFill.d.ts +56 -0
- package/lib/typescript/src/components/ProductMerchandisingCard/GlassFill.web.d.ts +27 -0
- package/lib/typescript/src/components/ProductMerchandisingCard/ProductMerchandisingCard.d.ts +81 -0
- package/lib/typescript/src/components/ProjectionMarker/ProjectionMarker.d.ts +82 -0
- package/lib/typescript/src/components/Radio/Radio.d.ts +3 -2
- package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +2 -2
- package/lib/typescript/src/components/Slider/Slider.d.ts +99 -0
- package/lib/typescript/src/components/TextInput/TextInput.d.ts +9 -29
- package/lib/typescript/src/components/TextSegment/TextSegment.d.ts +100 -0
- package/lib/typescript/src/components/index.d.ts +10 -1
- package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +22 -2
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/lib/typescript/src/utils/react-utils.d.ts +10 -0
- package/package.json +2 -1
- package/src/components/AmountInput/AmountInput.tsx +7 -5
- package/src/components/BenefitCard/BenefitCard.tsx +309 -0
- package/src/components/CcCard/CcCard.tsx +598 -0
- package/src/components/Checkbox/Checkbox.tsx +5 -4
- package/src/components/CheckboxItem/CheckboxItem.tsx +5 -4
- package/src/components/CompareTable/CompareTable.tsx +477 -0
- package/src/components/ComparisonBar/ComparisonBar.tsx +356 -0
- package/src/components/DropdownInput/DropdownInput.tsx +55 -3
- package/src/components/FormField/FormField.tsx +5 -4
- package/src/components/InputSearch/InputSearch.tsx +8 -5
- package/src/components/NoteInput/NoteInput.tsx +8 -6
- package/src/components/PdpCcCard/PdpCcCard.tsx +356 -0
- package/src/components/ProductMerchandisingCard/GlassFill.tsx +276 -0
- package/src/components/ProductMerchandisingCard/GlassFill.web.tsx +127 -0
- package/src/components/ProductMerchandisingCard/ProductMerchandisingCard.tsx +423 -0
- package/src/components/ProjectionMarker/ProjectionMarker.tsx +277 -0
- package/src/components/Radio/Radio.tsx +5 -4
- package/src/components/Slider/Slider.tsx +628 -0
- package/src/components/TextInput/TextInput.tsx +15 -11
- package/src/components/TextSegment/TextSegment.tsx +166 -0
- package/src/components/index.ts +10 -1
- package/src/design-tokens/Coin Variables-variables-full.json +1 -1
- package/src/design-tokens/figma-modes.generated.ts +38 -9
- package/src/icons/registry.ts +1 -1
- package/src/utils/react-utils.ts +23 -0
- package/lib/typescript/scripts/extract-component-tokens.d.ts +0 -9
- package/lib/typescript/scripts/generate-component-docs.d.ts +0 -9
- package/lib/typescript/scripts/generate-icon-registry.d.ts +0 -3
- package/lib/typescript/scripts/generate-mode-types.d.ts +0 -2
- package/lib/typescript/scripts/retype-modes.d.cts +0 -2
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
Text,
|
|
5
|
+
type StyleProp,
|
|
6
|
+
type ViewStyle,
|
|
7
|
+
type TextStyle,
|
|
8
|
+
} from 'react-native'
|
|
9
|
+
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
10
|
+
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
11
|
+
import type { Modes } from '../../design-tokens'
|
|
12
|
+
import Divider from '../Divider/Divider'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A value rendered at either end of the marker. A `string`/`number` is rendered
|
|
16
|
+
* with the built-in title typography; any other `ReactNode` (e.g. a
|
|
17
|
+
* `MoneyValue`) is rendered as-is so consumers can fully control presentation.
|
|
18
|
+
*/
|
|
19
|
+
type ProjectionMarkerEndValue = React.ReactNode
|
|
20
|
+
|
|
21
|
+
export type ProjectionMarkerProps = {
|
|
22
|
+
/**
|
|
23
|
+
* Value shown on the leading (left) end of the marker — typically the
|
|
24
|
+
* invested/starting amount. Accepts a string for the default styling or any
|
|
25
|
+
* `ReactNode` (e.g. `MoneyValue`) for custom rendering.
|
|
26
|
+
*/
|
|
27
|
+
startValue?: ProjectionMarkerEndValue
|
|
28
|
+
/**
|
|
29
|
+
* Value shown on the trailing (right) end of the marker — typically the
|
|
30
|
+
* projected/ending amount.
|
|
31
|
+
*/
|
|
32
|
+
endValue?: ProjectionMarkerEndValue
|
|
33
|
+
/**
|
|
34
|
+
* Primary line inside the center badge — typically the duration
|
|
35
|
+
* (e.g. `"1Y 10M"`).
|
|
36
|
+
*/
|
|
37
|
+
duration?: React.ReactNode
|
|
38
|
+
/**
|
|
39
|
+
* Secondary line inside the center badge — typically the rate
|
|
40
|
+
* (e.g. `"@ 8.25 %"`).
|
|
41
|
+
*/
|
|
42
|
+
rate?: React.ReactNode
|
|
43
|
+
/**
|
|
44
|
+
* Whether to render the connector lines between the end values and the
|
|
45
|
+
* center badge. Defaults to `true`.
|
|
46
|
+
*/
|
|
47
|
+
showConnectors?: boolean
|
|
48
|
+
/** Design token modes for theming. */
|
|
49
|
+
modes?: Modes
|
|
50
|
+
/** Override the root container styles. */
|
|
51
|
+
style?: StyleProp<ViewStyle>
|
|
52
|
+
/** Override the leading value text styles (only applies to string values). */
|
|
53
|
+
startValueStyle?: StyleProp<TextStyle>
|
|
54
|
+
/** Override the trailing value text styles (only applies to string values). */
|
|
55
|
+
endValueStyle?: StyleProp<TextStyle>
|
|
56
|
+
/** Override the center badge container styles. */
|
|
57
|
+
badgeStyle?: StyleProp<ViewStyle>
|
|
58
|
+
/** Override the duration text styles. */
|
|
59
|
+
durationStyle?: StyleProp<TextStyle>
|
|
60
|
+
/** Override the rate text styles. */
|
|
61
|
+
rateStyle?: StyleProp<TextStyle>
|
|
62
|
+
/** Accessibility label for the whole marker. */
|
|
63
|
+
accessibilityLabel?: string
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const isTextValue = (value: React.ReactNode): value is string | number =>
|
|
67
|
+
typeof value === 'string' || typeof value === 'number'
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* ProjectionMarker renders a start value and an end value connected to a
|
|
71
|
+
* centered badge that summarizes the projection (e.g. a tenure and interest
|
|
72
|
+
* rate). It mirrors the Figma `projectionMarker` component and is commonly used
|
|
73
|
+
* inside "Potential returns" style cards.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```tsx
|
|
77
|
+
* <ProjectionMarker
|
|
78
|
+
* startValue="₹1,00,000"
|
|
79
|
+
* endValue="₹1,25,101"
|
|
80
|
+
* duration="1Y 10M"
|
|
81
|
+
* rate="@ 8.25 %"
|
|
82
|
+
* />
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @example Custom end values via MoneyValue
|
|
86
|
+
* ```tsx
|
|
87
|
+
* <ProjectionMarker
|
|
88
|
+
* startValue={<MoneyValue value="1,00,000" />}
|
|
89
|
+
* endValue={<MoneyValue value="1,25,101" />}
|
|
90
|
+
* duration="1Y 10M"
|
|
91
|
+
* rate="@ 8.25 %"
|
|
92
|
+
* />
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
function ProjectionMarker({
|
|
96
|
+
startValue = '₹1,00,000',
|
|
97
|
+
endValue = '₹1,25,101',
|
|
98
|
+
duration = '1Y 10M',
|
|
99
|
+
rate = '@ 8.25 %',
|
|
100
|
+
showConnectors = true,
|
|
101
|
+
modes = EMPTY_MODES,
|
|
102
|
+
style,
|
|
103
|
+
startValueStyle,
|
|
104
|
+
endValueStyle,
|
|
105
|
+
badgeStyle,
|
|
106
|
+
durationStyle,
|
|
107
|
+
rateStyle,
|
|
108
|
+
accessibilityLabel,
|
|
109
|
+
}: ProjectionMarkerProps) {
|
|
110
|
+
const titleColor =
|
|
111
|
+
(getVariableByName('projectionMarker/title/color', modes) as string | null) ?? '#000000'
|
|
112
|
+
const titleFontFamily =
|
|
113
|
+
(getVariableByName('projectionMarker/title/fontfamily', modes) as string | null) ??
|
|
114
|
+
'JioType Var'
|
|
115
|
+
const titleFontSize =
|
|
116
|
+
(getVariableByName('projectionMarker/title/fontsize', modes) as number | null) ?? 14
|
|
117
|
+
const titleFontWeight = String(
|
|
118
|
+
getVariableByName('projectionMarker/title/fontweight', modes) ?? 600
|
|
119
|
+
) as TextStyle['fontWeight']
|
|
120
|
+
|
|
121
|
+
const durationColor =
|
|
122
|
+
(getVariableByName('projectionMarker/duration/color', modes) as string | null) ?? '#000000'
|
|
123
|
+
const durationFontFamily =
|
|
124
|
+
(getVariableByName('projectionMarker/duration/fontfamily', modes) as string | null) ??
|
|
125
|
+
'JioType Var'
|
|
126
|
+
const durationFontSize =
|
|
127
|
+
(getVariableByName('projectionMarker/duration/fontsize', modes) as number | null) ?? 12
|
|
128
|
+
const durationFontWeight = String(
|
|
129
|
+
getVariableByName('projectionMarker/duration/fontweight', modes) ?? 500
|
|
130
|
+
) as TextStyle['fontWeight']
|
|
131
|
+
|
|
132
|
+
const rateColor =
|
|
133
|
+
(getVariableByName('projectionMarker/rate/color', modes) as string | null) ?? '#6b6b6b'
|
|
134
|
+
const rateFontFamily =
|
|
135
|
+
(getVariableByName('metricdata/rate/fontfamily', modes) as string | null) ?? 'JioType Var'
|
|
136
|
+
const rateFontSize =
|
|
137
|
+
(getVariableByName('metricdata/rate/fontsize', modes) as number | null) ?? 11
|
|
138
|
+
const rateFontWeight = String(
|
|
139
|
+
getVariableByName('metricdata/rate/fontweight', modes) ?? 400
|
|
140
|
+
) as TextStyle['fontWeight']
|
|
141
|
+
|
|
142
|
+
const badgeBg =
|
|
143
|
+
(getVariableByName('projectionMarker/durationWrap/bg/color', modes) as string | null) ??
|
|
144
|
+
'#f5f5f5'
|
|
145
|
+
const badgeBorderColor =
|
|
146
|
+
(getVariableByName('projectionMarker/durationWrap/border/color', modes) as string | null) ??
|
|
147
|
+
'#ebebed'
|
|
148
|
+
const badgeBorderWidth =
|
|
149
|
+
(getVariableByName('metricdata/durationWrap/stroke', modes) as number | null) ?? 1
|
|
150
|
+
const badgeRadius =
|
|
151
|
+
(getVariableByName('metricdata/durationWrap/radius', modes) as number | null) ?? 8
|
|
152
|
+
const badgePaddingHorizontal =
|
|
153
|
+
(getVariableByName('metricdata/durationWrap/padding/horizontal', modes) as number | null) ?? 16
|
|
154
|
+
const badgePaddingVertical =
|
|
155
|
+
(getVariableByName('metricdata/durationWrap/padding/vertical', modes) as number | null) ?? 8
|
|
156
|
+
|
|
157
|
+
const titleTextStyle: TextStyle = {
|
|
158
|
+
color: titleColor,
|
|
159
|
+
fontFamily: titleFontFamily,
|
|
160
|
+
fontSize: titleFontSize,
|
|
161
|
+
fontWeight: titleFontWeight,
|
|
162
|
+
lineHeight: titleFontSize * 1.3,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const renderEndValue = (
|
|
166
|
+
value: React.ReactNode,
|
|
167
|
+
overrideStyle: StyleProp<TextStyle>
|
|
168
|
+
): React.ReactNode => {
|
|
169
|
+
if (value === null || value === undefined) return null
|
|
170
|
+
if (isTextValue(value)) {
|
|
171
|
+
return (
|
|
172
|
+
<Text style={[titleTextStyle, overrideStyle]} numberOfLines={1}>
|
|
173
|
+
{value}
|
|
174
|
+
</Text>
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
return cloneChildrenWithModes(value, modes)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<View
|
|
182
|
+
style={[styles.container, style]}
|
|
183
|
+
accessibilityRole="summary"
|
|
184
|
+
accessibilityLabel={accessibilityLabel}
|
|
185
|
+
>
|
|
186
|
+
{renderEndValue(startValue, startValueStyle)}
|
|
187
|
+
|
|
188
|
+
{showConnectors && (
|
|
189
|
+
<Divider direction="horizontal" modes={modes} style={styles.connector} />
|
|
190
|
+
)}
|
|
191
|
+
|
|
192
|
+
<View
|
|
193
|
+
style={[
|
|
194
|
+
styles.badge,
|
|
195
|
+
{
|
|
196
|
+
backgroundColor: badgeBg,
|
|
197
|
+
borderColor: badgeBorderColor,
|
|
198
|
+
borderWidth: badgeBorderWidth,
|
|
199
|
+
borderRadius: badgeRadius,
|
|
200
|
+
paddingHorizontal: badgePaddingHorizontal,
|
|
201
|
+
paddingVertical: badgePaddingVertical,
|
|
202
|
+
},
|
|
203
|
+
badgeStyle,
|
|
204
|
+
]}
|
|
205
|
+
>
|
|
206
|
+
{duration !== null && duration !== undefined
|
|
207
|
+
? isTextValue(duration)
|
|
208
|
+
? (
|
|
209
|
+
<Text
|
|
210
|
+
style={[
|
|
211
|
+
{
|
|
212
|
+
color: durationColor,
|
|
213
|
+
fontFamily: durationFontFamily,
|
|
214
|
+
fontSize: durationFontSize,
|
|
215
|
+
fontWeight: durationFontWeight,
|
|
216
|
+
lineHeight: durationFontSize * 1.2,
|
|
217
|
+
textAlign: 'center',
|
|
218
|
+
},
|
|
219
|
+
durationStyle,
|
|
220
|
+
]}
|
|
221
|
+
>
|
|
222
|
+
{duration}
|
|
223
|
+
</Text>
|
|
224
|
+
)
|
|
225
|
+
: cloneChildrenWithModes(duration, modes)
|
|
226
|
+
: null}
|
|
227
|
+
{rate !== null && rate !== undefined
|
|
228
|
+
? isTextValue(rate)
|
|
229
|
+
? (
|
|
230
|
+
<Text
|
|
231
|
+
style={[
|
|
232
|
+
{
|
|
233
|
+
color: rateColor,
|
|
234
|
+
fontFamily: rateFontFamily,
|
|
235
|
+
fontSize: rateFontSize,
|
|
236
|
+
fontWeight: rateFontWeight,
|
|
237
|
+
lineHeight: rateFontSize * 1.3,
|
|
238
|
+
textAlign: 'center',
|
|
239
|
+
},
|
|
240
|
+
rateStyle,
|
|
241
|
+
]}
|
|
242
|
+
>
|
|
243
|
+
{rate}
|
|
244
|
+
</Text>
|
|
245
|
+
)
|
|
246
|
+
: cloneChildrenWithModes(rate, modes)
|
|
247
|
+
: null}
|
|
248
|
+
</View>
|
|
249
|
+
|
|
250
|
+
{showConnectors && (
|
|
251
|
+
<Divider direction="horizontal" modes={modes} style={styles.connector} />
|
|
252
|
+
)}
|
|
253
|
+
|
|
254
|
+
{renderEndValue(endValue, endValueStyle)}
|
|
255
|
+
</View>
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const styles = {
|
|
260
|
+
container: {
|
|
261
|
+
flexDirection: 'row',
|
|
262
|
+
alignItems: 'center',
|
|
263
|
+
width: '100%',
|
|
264
|
+
} as ViewStyle,
|
|
265
|
+
connector: {
|
|
266
|
+
flex: 1,
|
|
267
|
+
alignSelf: 'center',
|
|
268
|
+
marginHorizontal: 16,
|
|
269
|
+
} as ViewStyle,
|
|
270
|
+
badge: {
|
|
271
|
+
flexDirection: 'column',
|
|
272
|
+
alignItems: 'center',
|
|
273
|
+
justifyContent: 'center',
|
|
274
|
+
} as ViewStyle,
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export default ProjectionMarker
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { forwardRef, useState } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
Pressable,
|
|
4
4
|
View,
|
|
@@ -47,14 +47,14 @@ export interface RadioProps {
|
|
|
47
47
|
// Radio
|
|
48
48
|
// ---------------------------------------------------------------------------
|
|
49
49
|
|
|
50
|
-
export function Radio({
|
|
50
|
+
export const Radio = forwardRef<View, RadioProps>(function Radio({
|
|
51
51
|
selected = false,
|
|
52
52
|
disabled = false,
|
|
53
53
|
onPress,
|
|
54
54
|
modes = EMPTY_MODES,
|
|
55
55
|
style,
|
|
56
56
|
testID,
|
|
57
|
-
}: RadioProps) {
|
|
57
|
+
}: RadioProps, ref: React.Ref<View>) {
|
|
58
58
|
// ---- Refs & State ----
|
|
59
59
|
const [hovered, setHovered] = useState(false)
|
|
60
60
|
const [focused, setFocused] = useState(false)
|
|
@@ -206,6 +206,7 @@ export function Radio({
|
|
|
206
206
|
|
|
207
207
|
return (
|
|
208
208
|
<Pressable
|
|
209
|
+
ref={ref}
|
|
209
210
|
testID={testID}
|
|
210
211
|
disabled={disabled}
|
|
211
212
|
onPress={onPress}
|
|
@@ -223,6 +224,6 @@ export function Radio({
|
|
|
223
224
|
<View style={selectorStyle} />
|
|
224
225
|
</Pressable>
|
|
225
226
|
)
|
|
226
|
-
}
|
|
227
|
+
})
|
|
227
228
|
|
|
228
229
|
export default Radio
|