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.
Files changed (107) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/lib/commonjs/components/AmountInput/AmountInput.js +8 -5
  3. package/lib/commonjs/components/BenefitCard/BenefitCard.js +231 -0
  4. package/lib/commonjs/components/CcCard/CcCard.js +470 -0
  5. package/lib/commonjs/components/Checkbox/Checkbox.js +4 -3
  6. package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +4 -3
  7. package/lib/commonjs/components/CompareTable/CompareTable.js +372 -0
  8. package/lib/commonjs/components/ComparisonBar/ComparisonBar.js +266 -0
  9. package/lib/commonjs/components/DropdownInput/DropdownInput.js +35 -3
  10. package/lib/commonjs/components/FormField/FormField.js +4 -3
  11. package/lib/commonjs/components/InputSearch/InputSearch.js +6 -4
  12. package/lib/commonjs/components/NoteInput/NoteInput.js +6 -5
  13. package/lib/commonjs/components/PdpCcCard/PdpCcCard.js +273 -0
  14. package/lib/commonjs/components/ProductMerchandisingCard/GlassFill.js +263 -0
  15. package/lib/commonjs/components/ProductMerchandisingCard/GlassFill.web.js +116 -0
  16. package/lib/commonjs/components/ProductMerchandisingCard/ProductMerchandisingCard.js +353 -0
  17. package/lib/commonjs/components/ProjectionMarker/ProjectionMarker.js +161 -0
  18. package/lib/commonjs/components/Radio/Radio.js +5 -5
  19. package/lib/commonjs/components/Slider/Slider.js +473 -0
  20. package/lib/commonjs/components/TextInput/TextInput.js +13 -8
  21. package/lib/commonjs/components/TextSegment/TextSegment.js +118 -0
  22. package/lib/commonjs/components/index.js +63 -0
  23. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  24. package/lib/commonjs/design-tokens/figma-modes.generated.js +38 -9
  25. package/lib/commonjs/icons/registry.js +1 -1
  26. package/lib/commonjs/utils/react-utils.js +22 -0
  27. package/lib/module/components/AmountInput/AmountInput.js +6 -4
  28. package/lib/module/components/BenefitCard/BenefitCard.js +225 -0
  29. package/lib/module/components/CcCard/CcCard.js +464 -0
  30. package/lib/module/components/Checkbox/Checkbox.js +5 -4
  31. package/lib/module/components/CheckboxItem/CheckboxItem.js +5 -4
  32. package/lib/module/components/CompareTable/CompareTable.js +367 -0
  33. package/lib/module/components/ComparisonBar/ComparisonBar.js +260 -0
  34. package/lib/module/components/DropdownInput/DropdownInput.js +36 -4
  35. package/lib/module/components/FormField/FormField.js +5 -4
  36. package/lib/module/components/InputSearch/InputSearch.js +6 -4
  37. package/lib/module/components/NoteInput/NoteInput.js +7 -6
  38. package/lib/module/components/PdpCcCard/PdpCcCard.js +267 -0
  39. package/lib/module/components/ProductMerchandisingCard/GlassFill.js +257 -0
  40. package/lib/module/components/ProductMerchandisingCard/GlassFill.web.js +111 -0
  41. package/lib/module/components/ProductMerchandisingCard/ProductMerchandisingCard.js +347 -0
  42. package/lib/module/components/ProjectionMarker/ProjectionMarker.js +156 -0
  43. package/lib/module/components/Radio/Radio.js +5 -4
  44. package/lib/module/components/Slider/Slider.js +468 -0
  45. package/lib/module/components/TextInput/TextInput.js +15 -10
  46. package/lib/module/components/TextSegment/TextSegment.js +113 -0
  47. package/lib/module/components/index.js +9 -0
  48. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  49. package/lib/module/design-tokens/figma-modes.generated.js +38 -9
  50. package/lib/module/icons/registry.js +1 -1
  51. package/lib/module/utils/react-utils.js +21 -0
  52. package/lib/typescript/src/components/AmountInput/AmountInput.d.ts +3 -2
  53. package/lib/typescript/src/components/BenefitCard/BenefitCard.d.ts +93 -0
  54. package/lib/typescript/src/components/CcCard/CcCard.d.ts +137 -0
  55. package/lib/typescript/src/components/Checkbox/Checkbox.d.ts +3 -2
  56. package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +2 -2
  57. package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +88 -0
  58. package/lib/typescript/src/components/ComparisonBar/ComparisonBar.d.ts +118 -0
  59. package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +20 -1
  60. package/lib/typescript/src/components/FormField/FormField.d.ts +2 -2
  61. package/lib/typescript/src/components/InputSearch/InputSearch.d.ts +23 -2
  62. package/lib/typescript/src/components/NoteInput/NoteInput.d.ts +19 -2
  63. package/lib/typescript/src/components/PdpCcCard/PdpCcCard.d.ts +84 -0
  64. package/lib/typescript/src/components/ProductMerchandisingCard/GlassFill.d.ts +56 -0
  65. package/lib/typescript/src/components/ProductMerchandisingCard/GlassFill.web.d.ts +27 -0
  66. package/lib/typescript/src/components/ProductMerchandisingCard/ProductMerchandisingCard.d.ts +81 -0
  67. package/lib/typescript/src/components/ProjectionMarker/ProjectionMarker.d.ts +82 -0
  68. package/lib/typescript/src/components/Radio/Radio.d.ts +3 -2
  69. package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +2 -2
  70. package/lib/typescript/src/components/Slider/Slider.d.ts +99 -0
  71. package/lib/typescript/src/components/TextInput/TextInput.d.ts +9 -29
  72. package/lib/typescript/src/components/TextSegment/TextSegment.d.ts +100 -0
  73. package/lib/typescript/src/components/index.d.ts +10 -1
  74. package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +22 -2
  75. package/lib/typescript/src/icons/registry.d.ts +1 -1
  76. package/lib/typescript/src/utils/react-utils.d.ts +10 -0
  77. package/package.json +2 -1
  78. package/src/components/AmountInput/AmountInput.tsx +7 -5
  79. package/src/components/BenefitCard/BenefitCard.tsx +309 -0
  80. package/src/components/CcCard/CcCard.tsx +598 -0
  81. package/src/components/Checkbox/Checkbox.tsx +5 -4
  82. package/src/components/CheckboxItem/CheckboxItem.tsx +5 -4
  83. package/src/components/CompareTable/CompareTable.tsx +477 -0
  84. package/src/components/ComparisonBar/ComparisonBar.tsx +356 -0
  85. package/src/components/DropdownInput/DropdownInput.tsx +55 -3
  86. package/src/components/FormField/FormField.tsx +5 -4
  87. package/src/components/InputSearch/InputSearch.tsx +8 -5
  88. package/src/components/NoteInput/NoteInput.tsx +8 -6
  89. package/src/components/PdpCcCard/PdpCcCard.tsx +356 -0
  90. package/src/components/ProductMerchandisingCard/GlassFill.tsx +276 -0
  91. package/src/components/ProductMerchandisingCard/GlassFill.web.tsx +127 -0
  92. package/src/components/ProductMerchandisingCard/ProductMerchandisingCard.tsx +423 -0
  93. package/src/components/ProjectionMarker/ProjectionMarker.tsx +277 -0
  94. package/src/components/Radio/Radio.tsx +5 -4
  95. package/src/components/Slider/Slider.tsx +628 -0
  96. package/src/components/TextInput/TextInput.tsx +15 -11
  97. package/src/components/TextSegment/TextSegment.tsx +166 -0
  98. package/src/components/index.ts +10 -1
  99. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  100. package/src/design-tokens/figma-modes.generated.ts +38 -9
  101. package/src/icons/registry.ts +1 -1
  102. package/src/utils/react-utils.ts +23 -0
  103. package/lib/typescript/scripts/extract-component-tokens.d.ts +0 -9
  104. package/lib/typescript/scripts/generate-component-docs.d.ts +0 -9
  105. package/lib/typescript/scripts/generate-icon-registry.d.ts +0 -3
  106. package/lib/typescript/scripts/generate-mode-types.d.ts +0 -2
  107. package/lib/typescript/scripts/retype-modes.d.cts +0 -2
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
4
4
  import { Dimensions, Modal, Platform, Pressable, StyleSheet, Text, View } from 'react-native';
5
5
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
6
6
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
@@ -16,6 +16,12 @@ const IS_WEB = Platform.OS === 'web';
16
16
  // Types
17
17
  // ---------------------------------------------------------------------------
18
18
 
19
+ /**
20
+ * Imperative handle exposed via `ref`. Lets the consumer drive the dropdown
21
+ * from outside — e.g. close it when an Android hardware/system button is
22
+ * pressed, or open it programmatically from a sibling control.
23
+ */
24
+
19
25
  // ---------------------------------------------------------------------------
20
26
  // Token resolution
21
27
  // ---------------------------------------------------------------------------
@@ -119,7 +125,7 @@ function collectOptionsFromChildren(children) {
119
125
  // Component
120
126
  // ---------------------------------------------------------------------------
121
127
 
122
- function DropdownInput({
128
+ const DropdownInput = /*#__PURE__*/forwardRef(function DropdownInput({
123
129
  label,
124
130
  placeholder = 'Select an option',
125
131
  items,
@@ -150,7 +156,7 @@ function DropdownInput({
150
156
  accessibilityHint,
151
157
  onFocus,
152
158
  onBlur
153
- }) {
159
+ }, ref) {
154
160
  // ---------------- Modes ----------------
155
161
  const {
156
162
  modes: globalModes
@@ -264,6 +270,32 @@ function DropdownInput({
264
270
  measure();
265
271
  }, [measure]);
266
272
 
273
+ // ---------------- Imperative handle ----------------
274
+ useImperativeHandle(ref, () => ({
275
+ open: () => {
276
+ if (isDisabled || isReadOnly) return;
277
+ measure();
278
+ setOpenState(true);
279
+ },
280
+ close: closeMenu,
281
+ toggle: () => {
282
+ if (isDisabled || isReadOnly) return;
283
+ measure();
284
+ toggleMenu();
285
+ },
286
+ focus: () => {
287
+ ;
288
+ triggerRef.current?.focus?.();
289
+ },
290
+ blur: () => {
291
+ ;
292
+ triggerRef.current?.blur?.();
293
+ },
294
+ measureInWindow: callback => {
295
+ triggerRef.current?.measureInWindow(callback);
296
+ }
297
+ }), [isDisabled, isReadOnly, measure, setOpenState, closeMenu, toggleMenu]);
298
+
267
299
  // ---------------- Popup positioning ----------------
268
300
  const [menuSize, setMenuSize] = useState(null);
269
301
  const handleMenuLayout = useCallback(e => {
@@ -558,7 +590,7 @@ function DropdownInput({
558
590
  })
559
591
  })]
560
592
  });
561
- }
593
+ });
562
594
  const webNoOutline = {
563
595
  outlineStyle: 'none',
564
596
  outlineWidth: 0,
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import React, { useCallback, useMemo, useState } from 'react';
3
+ import React, { forwardRef, useCallback, useMemo, useState } from 'react';
4
4
  import { View, Text, TextInput as RNTextInput } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { useTokens } from '../../design-tokens/JFSThemeProvider';
@@ -156,7 +156,7 @@ function firstError(error) {
156
156
  // Component
157
157
  // ---------------------------------------------------------------------------
158
158
 
159
- function FormField({
159
+ const FormField = /*#__PURE__*/forwardRef(function FormField({
160
160
  label,
161
161
  placeholder,
162
162
  value,
@@ -184,7 +184,7 @@ function FormField({
184
184
  accessibilityLabel,
185
185
  accessibilityHint,
186
186
  testID
187
- }) {
187
+ }, ref) {
188
188
  // -- Form context integration -------------------------------------------
189
189
  const formCtx = useFormContext();
190
190
  const formError = name && formCtx ? firstError(formCtx.validationErrors[name]) : undefined;
@@ -341,6 +341,7 @@ function FormField({
341
341
  importantForAccessibility: "no",
342
342
  children: processedLeading
343
343
  }), /*#__PURE__*/_jsx(RNTextInput, {
344
+ ref: ref,
344
345
  style: [inputTextStyles, inputTextStyle],
345
346
  value: value ?? '',
346
347
  onChangeText: handleChangeText,
@@ -370,5 +371,5 @@ function FormField({
370
371
  modes: modes
371
372
  })]
372
373
  });
373
- }
374
+ });
374
375
  export default FormField;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import React, { useState } from 'react';
3
+ import React, { forwardRef, useState } from 'react';
4
4
  import { View, Text, Pressable } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { EMPTY_MODES } from '../../utils/react-utils';
@@ -48,7 +48,7 @@ function SupportText({
48
48
  })]
49
49
  });
50
50
  }
51
- export default function InputSearch({
51
+ const InputSearch = /*#__PURE__*/forwardRef(function InputSearch({
52
52
  supportText = true,
53
53
  supportTextLabel = "Support Text",
54
54
  supportTextIcon = "ic_info",
@@ -63,7 +63,7 @@ export default function InputSearch({
63
63
  trailing,
64
64
  inputStyle,
65
65
  ...rest
66
- }) {
66
+ }, ref) {
67
67
  const [isFocused, setIsFocused] = useState(false);
68
68
 
69
69
  // Hardcode InputState based on the state prop, ignoring any external InputState passed in modes
@@ -118,6 +118,7 @@ export default function InputSearch({
118
118
  gap: formFieldGap
119
119
  }, containerStyle],
120
120
  children: [/*#__PURE__*/_jsx(TextInput, {
121
+ ref: ref,
121
122
  placeholder: placeholder,
122
123
  value: value || '',
123
124
  onChangeText: onChangeText || (() => {}),
@@ -137,4 +138,5 @@ export default function InputSearch({
137
138
  modes: componentModes
138
139
  })]
139
140
  });
140
- }
141
+ });
142
+ export default InputSearch;
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
 
3
- import React, { useState, useRef } from 'react';
3
+ import React, { forwardRef, useState, useRef } from 'react';
4
4
  import { View, TextInput as RNTextInput, Text, Pressable } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
- import { EMPTY_MODES } from '../../utils/react-utils';
6
+ import { EMPTY_MODES, mergeRefs } from '../../utils/react-utils';
7
7
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  /**
9
9
  * NoteInput component representing an interactive "Add note" badge style field.
10
10
  * Allows the user to click, clears the placeholder text, and shows a blinking cursor when focused.
11
11
  */
12
- export default function NoteInput({
12
+ const NoteInput = /*#__PURE__*/forwardRef(function NoteInput({
13
13
  value = '',
14
14
  placeholder = 'Add note',
15
15
  onChangeText,
@@ -20,7 +20,7 @@ export default function NoteInput({
20
20
  onFocus,
21
21
  onBlur,
22
22
  ...rest
23
- }) {
23
+ }, ref) {
24
24
  const [internalFocused, setInternalFocused] = useState(false);
25
25
  const inputRef = useRef(null);
26
26
 
@@ -92,7 +92,7 @@ export default function NoteInput({
92
92
  importantForAccessibility: "no",
93
93
  children: internalFocused ? value || ' ' : value || placeholder
94
94
  }), /*#__PURE__*/_jsx(RNTextInput, {
95
- ref: inputRef,
95
+ ref: mergeRefs(inputRef, ref),
96
96
  value: value,
97
97
  onChangeText: onChangeText,
98
98
  placeholder: internalFocused ? '' : placeholder,
@@ -112,4 +112,5 @@ export default function NoteInput({
112
112
  })]
113
113
  })
114
114
  });
115
- }
115
+ });
116
+ export default NoteInput;
@@ -0,0 +1,267 @@
1
+ "use strict";
2
+
3
+ import React, { useMemo } from 'react';
4
+ import { View, Text, Pressable, StyleSheet } from 'react-native';
5
+ import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
+ import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils';
7
+ import Title from '../Title/Title';
8
+ import Divider from '../Divider/Divider';
9
+ import Button from '../Button/Button';
10
+ import Image from '../Image/Image';
11
+ import Icon from '../Icon/Icon';
12
+
13
+ /**
14
+ * A single metric column inside the card's stats row: a small title, a bold
15
+ * value and an optional muted caption.
16
+ */
17
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
18
+ /**
19
+ * PdpCcCard — Figma node 5352:935 ("PDP cc card").
20
+ *
21
+ * A centered white product/PDP card composed from the shared design-system
22
+ * primitives so it stays in sync with the rest of the library:
23
+ *
24
+ * - **Media** — a top image slot (`Image`, rounded via `image/radius`). Pass
25
+ * `imageSource` for the default image or `media` for a full slot override.
26
+ * - **Title** — a centered headline + subtitle rendered through the shared
27
+ * {@link Title} component (`title/*`, `pageSubtitle/*` tokens).
28
+ * - **Metrics** — a row of {@link PdpCcCardMetric} columns (title / value /
29
+ * caption) separated by vertical `Divider`s (`metricdata/*` tokens).
30
+ * - **CTA** — a small tonal {@link Button} (`Button / Size: S`,
31
+ * `AppearanceBrand: Secondary`, `Emphasis: Medium`) with a leading icon.
32
+ *
33
+ * All defaults can be overridden via `modes`.
34
+ */
35
+ function PdpCcCard({
36
+ imageSource,
37
+ imageWidth = 100,
38
+ imageHeight = 60,
39
+ media,
40
+ title = 'Title',
41
+ subtitle = 'Subtitle',
42
+ metrics = DEFAULT_METRICS,
43
+ buttonLabel = 'button',
44
+ buttonIcon = 'ic_add_circle',
45
+ onButtonPress,
46
+ button,
47
+ showButton = true,
48
+ onPress,
49
+ width = 344,
50
+ modes = EMPTY_MODES,
51
+ style,
52
+ accessibilityLabel
53
+ }) {
54
+ const tokens = useMemo(() => resolveTokens(modes), [modes]);
55
+
56
+ // The CTA uses the brand "Secondary" appearance at "Medium" emphasis (lilac
57
+ // fill + purple label) and the small size — matching the design. A
58
+ // consumer-supplied `modes` value still wins via spread order.
59
+ const ctaModes = useMemo(() => ({
60
+ AppearanceBrand: 'Secondary',
61
+ Emphasis: 'Medium',
62
+ 'Button / Size': 'S',
63
+ ...modes
64
+ }), [modes]);
65
+ const buttonForeground = useMemo(() => asStr(getVariableByName('button/foreground', ctaModes), '#5d00b5'), [ctaModes]);
66
+ const mediaNode = media ? cloneChildrenWithModes(media, modes) : /*#__PURE__*/_jsx(Image, {
67
+ imageSource: imageSource,
68
+ width: imageWidth,
69
+ height: imageHeight,
70
+ borderRadius: tokens.imageRadius,
71
+ resizeMode: "cover",
72
+ accessibilityElementsHidden: true,
73
+ importantForAccessibility: "no"
74
+ });
75
+ const ctaNode = button ? cloneChildrenWithModes(button, ctaModes) : /*#__PURE__*/_jsx(Button, {
76
+ label: buttonLabel,
77
+ modes: ctaModes,
78
+ onPress: onButtonPress,
79
+ leading: buttonIcon ? /*#__PURE__*/_jsx(Icon, {
80
+ iconName: buttonIcon,
81
+ size: tokens.buttonIconSize,
82
+ color: buttonForeground
83
+ }) : undefined
84
+ });
85
+ const content = /*#__PURE__*/_jsxs(_Fragment, {
86
+ children: [/*#__PURE__*/_jsx(View, {
87
+ style: styles.mediaSlot,
88
+ children: mediaNode
89
+ }), /*#__PURE__*/_jsx(Title, {
90
+ title: title,
91
+ subtitle: subtitle,
92
+ textAlign: "Center",
93
+ modes: modes
94
+ }), metrics.length > 0 ? /*#__PURE__*/_jsx(View, {
95
+ style: styles.metricsRow,
96
+ children: metrics.map((metric, index) => /*#__PURE__*/_jsxs(React.Fragment, {
97
+ children: [index > 0 ? /*#__PURE__*/_jsx(Divider, {
98
+ direction: "vertical",
99
+ modes: modes,
100
+ style: styles.metricDivider
101
+ }) : null, /*#__PURE__*/_jsx(Metricdata, {
102
+ metric: metric,
103
+ tokens: tokens
104
+ })]
105
+ }, index))
106
+ }) : null, showButton ? ctaNode : null]
107
+ });
108
+ const containerStyle = useMemo(() => ({
109
+ ...tokens.container,
110
+ width
111
+ }), [tokens.container, width]);
112
+ if (onPress) {
113
+ return /*#__PURE__*/_jsx(Pressable, {
114
+ style: ({
115
+ pressed
116
+ }) => [containerStyle, pressed ? styles.pressed : null, style],
117
+ accessibilityRole: "button",
118
+ accessibilityLabel: accessibilityLabel ?? title,
119
+ onPress: onPress,
120
+ children: content
121
+ });
122
+ }
123
+ return /*#__PURE__*/_jsx(View, {
124
+ style: [containerStyle, style],
125
+ accessibilityLabel: accessibilityLabel,
126
+ children: content
127
+ });
128
+ }
129
+
130
+ // ---------------------------------------------------------------------------
131
+ // Metricdata — internal metric column (Figma node 5352:256)
132
+ // ---------------------------------------------------------------------------
133
+
134
+ function Metricdata({
135
+ metric,
136
+ tokens
137
+ }) {
138
+ return /*#__PURE__*/_jsxs(View, {
139
+ style: tokens.metric,
140
+ children: [metric.title != null ? /*#__PURE__*/_jsx(Text, {
141
+ style: tokens.metricTitle,
142
+ children: metric.title
143
+ }) : null, metric.value != null ? /*#__PURE__*/_jsx(Text, {
144
+ style: tokens.metricValue,
145
+ children: metric.value
146
+ }) : null, metric.caption != null ? /*#__PURE__*/_jsx(Text, {
147
+ style: tokens.metricCaption,
148
+ children: metric.caption
149
+ }) : null]
150
+ });
151
+ }
152
+
153
+ // ---------------------------------------------------------------------------
154
+ // Tokens / static styles
155
+ // ---------------------------------------------------------------------------
156
+
157
+ function asNum(raw, fallback) {
158
+ const n = typeof raw === 'number' ? raw : parseFloat(raw);
159
+ return Number.isFinite(n) ? n : fallback;
160
+ }
161
+ function asStr(raw, fallback) {
162
+ return raw != null ? String(raw) : fallback;
163
+ }
164
+ function resolveTokens(modes) {
165
+ // NOTE: token names are passed as string literals DIRECTLY to
166
+ // getVariableByName so the `extract-component-tokens` script can statically
167
+ // collect them for the generated docs. Do not refactor these into a helper
168
+ // that receives the name as a variable.
169
+ const background = asStr(getVariableByName('PDPcccard/bg/color', modes), '#ffffff');
170
+ const paddingHorizontal = asNum(getVariableByName('PDPcccard/padding/horizontal', modes), 16);
171
+ const paddingVertical = asNum(getVariableByName('PDPcccard/padding/vertical', modes), 20);
172
+ const gap = asNum(getVariableByName('PDPcccard/gap', modes), 12);
173
+ const imageRadius = asNum(getVariableByName('image/radius', modes), 8);
174
+ const buttonIconSize = asNum(getVariableByName('button/iconSize', modes), 16);
175
+ const metricGap = asNum(getVariableByName('metricdata/gap', modes), 4);
176
+ const metricPadH = asNum(getVariableByName('metricdata/padding/horizontal', modes), 10);
177
+ const metricPadV = asNum(getVariableByName('metricdata/padding/vertical', modes), 10);
178
+ const titleColor = asStr(getVariableByName('metricdata/title/color', modes), '#000000');
179
+ const titleSize = asNum(getVariableByName('metricdata/title/fontsize', modes), 12);
180
+ const titleFamily = asStr(getVariableByName('metricdata/title/fontfamily', modes), 'JioType Var');
181
+ const titleWeight = asStr(getVariableByName('metricdata/title/fontweight', modes), '400');
182
+ const valueColor = asStr(getVariableByName('metricdata/value/color', modes), '#000000');
183
+ const valueSize = asNum(getVariableByName('metricdata/value/fontsize', modes), 20);
184
+ const valueFamily = asStr(getVariableByName('metricdata/value/fontfamily', modes), 'JioType Var');
185
+ const valueWeight = asStr(getVariableByName('metricdata/value/fontweight', modes), '700');
186
+ const captionColor = asStr(getVariableByName('metricdata/caption/color', modes), '#777777');
187
+ const captionSize = asNum(getVariableByName('metricdata/caption/fontsize', modes), 12);
188
+ const captionFamily = asStr(getVariableByName('metricdata/caption/fontfamily', modes), 'JioType Var');
189
+ const captionWeight = asStr(getVariableByName('metricdata/caption/fontweight', modes), '500');
190
+ return {
191
+ container: {
192
+ backgroundColor: background,
193
+ paddingHorizontal,
194
+ paddingVertical,
195
+ gap,
196
+ flexDirection: 'column',
197
+ alignItems: 'center',
198
+ justifyContent: 'center'
199
+ },
200
+ imageRadius,
201
+ buttonIconSize,
202
+ metric: {
203
+ flex: 1,
204
+ gap: metricGap,
205
+ paddingHorizontal: metricPadH,
206
+ paddingVertical: metricPadV,
207
+ alignItems: 'center',
208
+ justifyContent: 'center'
209
+ },
210
+ metricTitle: {
211
+ color: titleColor,
212
+ fontSize: titleSize,
213
+ fontFamily: titleFamily,
214
+ fontWeight: titleWeight,
215
+ lineHeight: Math.round(titleSize * 1.2),
216
+ textAlign: 'center',
217
+ includeFontPadding: false
218
+ },
219
+ metricValue: {
220
+ color: valueColor,
221
+ fontSize: valueSize,
222
+ fontFamily: valueFamily,
223
+ fontWeight: valueWeight,
224
+ lineHeight: Math.round(valueSize * 1.2),
225
+ textAlign: 'center',
226
+ includeFontPadding: false
227
+ },
228
+ metricCaption: {
229
+ color: captionColor,
230
+ fontSize: captionSize,
231
+ fontFamily: captionFamily,
232
+ fontWeight: captionWeight,
233
+ lineHeight: Math.round(captionSize * 1.2),
234
+ textAlign: 'center',
235
+ includeFontPadding: false
236
+ }
237
+ };
238
+ }
239
+ const DEFAULT_METRICS = [{
240
+ title: 'Title',
241
+ value: 'Value',
242
+ caption: 'caption'
243
+ }, {
244
+ title: 'Title',
245
+ value: 'Value',
246
+ caption: 'caption'
247
+ }];
248
+ const styles = StyleSheet.create({
249
+ mediaSlot: {
250
+ alignSelf: 'stretch',
251
+ alignItems: 'center',
252
+ justifyContent: 'center'
253
+ },
254
+ metricsRow: {
255
+ alignSelf: 'stretch',
256
+ flexDirection: 'row',
257
+ alignItems: 'stretch'
258
+ },
259
+ metricDivider: {
260
+ alignSelf: 'center',
261
+ height: '70%'
262
+ },
263
+ pressed: {
264
+ opacity: 0.92
265
+ }
266
+ });
267
+ export default PdpCcCard;