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