jfs-components 0.1.25 → 0.1.30

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 (97) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/lib/commonjs/components/AutoplayControl/AutoplayControl.js +66 -0
  3. package/lib/commonjs/components/Carousel/Carousel.js +112 -19
  4. package/lib/commonjs/components/CompareTable/CompareTable.js +191 -25
  5. package/lib/commonjs/components/ContentSheet/ContentSheet.js +104 -10
  6. package/lib/commonjs/components/FormUpload/Additem.js +168 -0
  7. package/lib/commonjs/components/FormUpload/FormUpload.js +198 -0
  8. package/lib/commonjs/components/Grid/Grid.js +206 -0
  9. package/lib/commonjs/components/MoneyValue/MoneyValue.js +179 -54
  10. package/lib/commonjs/components/NumberPagination/NumberPagination.js +144 -0
  11. package/lib/commonjs/components/PdpCcCard/PdpCcCard.js +7 -1
  12. package/lib/commonjs/components/ProfileCard/ProfileCard.js +208 -0
  13. package/lib/commonjs/components/Table/Table.js +27 -7
  14. package/lib/commonjs/components/UpiHandle/UpiHandle.js +23 -11
  15. package/lib/commonjs/components/index.js +42 -0
  16. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  17. package/lib/commonjs/design-tokens/figma-modes.generated.js +21 -10
  18. package/lib/commonjs/icons/components/IconBrokenimage.js +19 -0
  19. package/lib/commonjs/icons/components/IconImage.js +19 -0
  20. package/lib/commonjs/icons/components/IconMic.js +19 -0
  21. package/lib/commonjs/icons/components/IconMicoff.js +19 -0
  22. package/lib/commonjs/icons/components/IconPause.js +19 -0
  23. package/lib/commonjs/icons/components/IconPlay.js +19 -0
  24. package/lib/commonjs/icons/components/index.js +66 -0
  25. package/lib/commonjs/icons/registry.js +2 -2
  26. package/lib/module/components/AutoplayControl/AutoplayControl.js +60 -0
  27. package/lib/module/components/Carousel/Carousel.js +111 -19
  28. package/lib/module/components/CompareTable/CompareTable.js +191 -26
  29. package/lib/module/components/ContentSheet/ContentSheet.js +108 -14
  30. package/lib/module/components/FormUpload/Additem.js +162 -0
  31. package/lib/module/components/FormUpload/FormUpload.js +192 -0
  32. package/lib/module/components/Grid/Grid.js +201 -0
  33. package/lib/module/components/MoneyValue/MoneyValue.js +182 -57
  34. package/lib/module/components/NumberPagination/NumberPagination.js +138 -0
  35. package/lib/module/components/PdpCcCard/PdpCcCard.js +7 -1
  36. package/lib/module/components/ProfileCard/ProfileCard.js +202 -0
  37. package/lib/module/components/Table/Table.js +27 -7
  38. package/lib/module/components/UpiHandle/UpiHandle.js +23 -11
  39. package/lib/module/components/index.js +7 -1
  40. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  41. package/lib/module/design-tokens/figma-modes.generated.js +21 -10
  42. package/lib/module/icons/components/IconBrokenimage.js +12 -0
  43. package/lib/module/icons/components/IconImage.js +12 -0
  44. package/lib/module/icons/components/IconMic.js +12 -0
  45. package/lib/module/icons/components/IconMicoff.js +12 -0
  46. package/lib/module/icons/components/IconPause.js +12 -0
  47. package/lib/module/icons/components/IconPlay.js +12 -0
  48. package/lib/module/icons/components/index.js +6 -0
  49. package/lib/module/icons/registry.js +2 -2
  50. package/lib/typescript/src/components/AutoplayControl/AutoplayControl.d.ts +15 -0
  51. package/lib/typescript/src/components/Carousel/Carousel.d.ts +8 -1
  52. package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +21 -1
  53. package/lib/typescript/src/components/ContentSheet/ContentSheet.d.ts +20 -1
  54. package/lib/typescript/src/components/FormUpload/Additem.d.ts +96 -0
  55. package/lib/typescript/src/components/FormUpload/FormUpload.d.ts +85 -0
  56. package/lib/typescript/src/components/Grid/Grid.d.ts +87 -0
  57. package/lib/typescript/src/components/MoneyValue/MoneyValue.d.ts +10 -1
  58. package/lib/typescript/src/components/NumberPagination/NumberPagination.d.ts +21 -0
  59. package/lib/typescript/src/components/PdpCcCard/PdpCcCard.d.ts +25 -1
  60. package/lib/typescript/src/components/ProfileCard/ProfileCard.d.ts +89 -0
  61. package/lib/typescript/src/components/Table/Table.d.ts +9 -1
  62. package/lib/typescript/src/components/UpiHandle/UpiHandle.d.ts +7 -1
  63. package/lib/typescript/src/components/index.d.ts +34 -28
  64. package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +10 -4
  65. package/lib/typescript/src/icons/components/IconBrokenimage.d.ts +3 -0
  66. package/lib/typescript/src/icons/components/IconImage.d.ts +3 -0
  67. package/lib/typescript/src/icons/components/IconMic.d.ts +3 -0
  68. package/lib/typescript/src/icons/components/IconMicoff.d.ts +3 -0
  69. package/lib/typescript/src/icons/components/IconPause.d.ts +3 -0
  70. package/lib/typescript/src/icons/components/IconPlay.d.ts +3 -0
  71. package/lib/typescript/src/icons/components/index.d.ts +6 -0
  72. package/lib/typescript/src/icons/registry.d.ts +1 -1
  73. package/package.json +1 -1
  74. package/src/components/AutoplayControl/AutoplayControl.tsx +77 -0
  75. package/src/components/Carousel/Carousel.tsx +133 -23
  76. package/src/components/CompareTable/CompareTable.tsx +224 -30
  77. package/src/components/ContentSheet/ContentSheet.tsx +138 -8
  78. package/src/components/FormUpload/Additem.tsx +262 -0
  79. package/src/components/FormUpload/FormUpload.tsx +313 -0
  80. package/src/components/Grid/Grid.tsx +368 -0
  81. package/src/components/MoneyValue/MoneyValue.tsx +216 -65
  82. package/src/components/NumberPagination/NumberPagination.tsx +170 -0
  83. package/src/components/PdpCcCard/PdpCcCard.tsx +36 -1
  84. package/src/components/ProfileCard/ProfileCard.tsx +268 -0
  85. package/src/components/Table/Table.tsx +29 -4
  86. package/src/components/UpiHandle/UpiHandle.tsx +35 -24
  87. package/src/components/index.ts +329 -182
  88. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  89. package/src/design-tokens/figma-modes.generated.ts +21 -10
  90. package/src/icons/components/IconBrokenimage.tsx +11 -0
  91. package/src/icons/components/IconImage.tsx +11 -0
  92. package/src/icons/components/IconMic.tsx +11 -0
  93. package/src/icons/components/IconMicoff.tsx +11 -0
  94. package/src/icons/components/IconPause.tsx +11 -0
  95. package/src/icons/components/IconPlay.tsx +11 -0
  96. package/src/icons/components/index.ts +6 -0
  97. package/src/icons/registry.ts +25 -1
@@ -0,0 +1,206 @@
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 _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
11
+ var _reactUtils = require("../../utils/react-utils");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ 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); }
14
+ function toNumber(value, fallback) {
15
+ if (typeof value === 'number' && Number.isFinite(value)) return value;
16
+ if (typeof value === 'string') {
17
+ const parsed = parseFloat(value);
18
+ if (Number.isFinite(parsed)) return parsed;
19
+ }
20
+ return fallback;
21
+ }
22
+ function resolveGridTokens(modes) {
23
+ const gapFallback = toNumber((0, _figmaVariablesResolver.getVariableByName)('Grid/gap', modes), 8);
24
+ const columnGap = toNumber((0, _figmaVariablesResolver.getVariableByName)('Grid/column/gap', modes), gapFallback);
25
+ const rowGap = toNumber((0, _figmaVariablesResolver.getVariableByName)('Grid/row/gap', modes), gapFallback);
26
+ const paddingHorizontal = toNumber((0, _figmaVariablesResolver.getVariableByName)('Grid/padding/horizontal', modes), 8);
27
+ const paddingVertical = toNumber((0, _figmaVariablesResolver.getVariableByName)('Grid/padding/vertical', modes), 8);
28
+ const paddingTop = toNumber((0, _figmaVariablesResolver.getVariableByName)('Grid/padding/top', modes), paddingVertical);
29
+ const paddingBottom = toNumber((0, _figmaVariablesResolver.getVariableByName)('Grid/padding/bottom', modes), paddingVertical);
30
+ const paddingLeft = toNumber((0, _figmaVariablesResolver.getVariableByName)('Grid/padding/left', modes), paddingHorizontal);
31
+ const paddingRight = toNumber((0, _figmaVariablesResolver.getVariableByName)('Grid/padding/right', modes), paddingHorizontal);
32
+ const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('Grid/background/color', modes) ?? 'transparent';
33
+ return {
34
+ backgroundColor,
35
+ columnGap,
36
+ rowGap,
37
+ paddingTop,
38
+ paddingBottom,
39
+ paddingLeft,
40
+ paddingRight
41
+ };
42
+ }
43
+ function normalizeFrs(frs, count) {
44
+ if (!frs || frs.length === 0) {
45
+ return Array.from({
46
+ length: count
47
+ }, () => 1);
48
+ }
49
+ return Array.from({
50
+ length: count
51
+ }, (_, index) => {
52
+ const value = frs[index] ?? frs[frs.length - 1] ?? 1;
53
+ return value > 0 ? value : 1;
54
+ });
55
+ }
56
+ function resolveAlignSelf(alignItems) {
57
+ if (alignItems === 'center') return 'center';
58
+ if (alignItems === 'start') return 'flex-start';
59
+ return 'stretch';
60
+ }
61
+ function resolveRowJustifyContent(justifyContent) {
62
+ if (justifyContent === 'space-between') return 'space-between';
63
+ if (justifyContent === 'start') return 'flex-start';
64
+ return 'flex-start';
65
+ }
66
+ function buildCellStyle(columnFr, justifyContent, alignItems) {
67
+ const alignSelf = resolveAlignSelf(alignItems);
68
+ if (justifyContent === 'space-between' || justifyContent === 'start') {
69
+ return {
70
+ flexGrow: 0,
71
+ flexShrink: 1,
72
+ flexBasis: 'auto',
73
+ minWidth: 0,
74
+ alignSelf
75
+ };
76
+ }
77
+ return {
78
+ flex: columnFr,
79
+ minWidth: 0,
80
+ alignSelf
81
+ };
82
+ }
83
+
84
+ /**
85
+ * `Grid` — a token-driven layout grid for React Native.
86
+ *
87
+ * Mirrors the Figma "Grid" component: a padded container with configurable
88
+ * columns, rows, fractional column tracks (`columnFrs`), and gap tokens.
89
+ * Each slot child maps to one cell — no separate `GridItem` wrapper is needed.
90
+ *
91
+ * @component
92
+ */
93
+ function Grid({
94
+ columns = 1,
95
+ rows,
96
+ columnFrs,
97
+ rowFrs,
98
+ columnGap: columnGapProp,
99
+ rowGap: rowGapProp,
100
+ gap: gapProp,
101
+ padding: paddingProp,
102
+ paddingHorizontal: paddingHorizontalProp,
103
+ paddingVertical: paddingVerticalProp,
104
+ paddingTop: paddingTopProp,
105
+ paddingBottom: paddingBottomProp,
106
+ paddingLeft: paddingLeftProp,
107
+ paddingRight: paddingRightProp,
108
+ justifyContent = 'stretch',
109
+ alignItems = 'stretch',
110
+ children,
111
+ modes: propModes = _reactUtils.EMPTY_MODES,
112
+ style,
113
+ contentStyle,
114
+ cellStyle,
115
+ accessibilityLabel,
116
+ testID
117
+ }) {
118
+ const {
119
+ modes: globalModes
120
+ } = (0, _JFSThemeProvider.useTokens)();
121
+ const modes = (0, _react.useMemo)(() => globalModes === _reactUtils.EMPTY_MODES && propModes === _reactUtils.EMPTY_MODES ? _reactUtils.EMPTY_MODES : {
122
+ ...globalModes,
123
+ ...propModes
124
+ }, [globalModes, propModes]);
125
+ const tokens = (0, _react.useMemo)(() => resolveGridTokens(modes), [modes]);
126
+ const resolvedColumnGap = columnGapProp ?? gapProp ?? tokens.columnGap;
127
+ const resolvedRowGap = rowGapProp ?? gapProp ?? tokens.rowGap;
128
+ const resolvedPadding = (0, _react.useMemo)(() => ({
129
+ paddingTop: paddingTopProp ?? paddingVerticalProp ?? paddingProp ?? tokens.paddingTop,
130
+ paddingBottom: paddingBottomProp ?? paddingVerticalProp ?? paddingProp ?? tokens.paddingBottom,
131
+ paddingLeft: paddingLeftProp ?? paddingHorizontalProp ?? paddingProp ?? tokens.paddingLeft,
132
+ paddingRight: paddingRightProp ?? paddingHorizontalProp ?? paddingProp ?? tokens.paddingRight
133
+ }), [paddingTopProp, paddingBottomProp, paddingLeftProp, paddingRightProp, paddingHorizontalProp, paddingVerticalProp, paddingProp, tokens]);
134
+ const safeColumns = Math.max(1, Math.floor(columns));
135
+ const processedChildren = (0, _react.useMemo)(() => (0, _reactUtils.cloneChildrenWithModes)((0, _reactUtils.flattenChildren)(children), modes), [children, modes]);
136
+ const cellNodes = (0, _react.useMemo)(() => {
137
+ const nodes = [...processedChildren];
138
+ if (rows != null) {
139
+ const targetCount = safeColumns * Math.max(1, Math.floor(rows));
140
+ while (nodes.length < targetCount) {
141
+ nodes.push(null);
142
+ }
143
+ if (nodes.length > targetCount) {
144
+ nodes.length = targetCount;
145
+ }
146
+ }
147
+ return nodes;
148
+ }, [processedChildren, rows, safeColumns]);
149
+ const gridRows = (0, _react.useMemo)(() => {
150
+ const result = [];
151
+ for (let index = 0; index < cellNodes.length; index += safeColumns) {
152
+ result.push(cellNodes.slice(index, index + safeColumns));
153
+ }
154
+ return result;
155
+ }, [cellNodes, safeColumns]);
156
+ const normalizedColumnFrs = (0, _react.useMemo)(() => normalizeFrs(columnFrs, safeColumns), [columnFrs, safeColumns]);
157
+ const normalizedRowFrs = (0, _react.useMemo)(() => rowFrs ? normalizeFrs(rowFrs, gridRows.length) : null, [rowFrs, gridRows.length]);
158
+ const containerStyle = (0, _react.useMemo)(() => ({
159
+ backgroundColor: tokens.backgroundColor,
160
+ ...resolvedPadding,
161
+ width: '100%'
162
+ }), [tokens.backgroundColor, resolvedPadding]);
163
+ const rowsContainerStyle = (0, _react.useMemo)(() => ({
164
+ gap: resolvedRowGap,
165
+ width: '100%'
166
+ }), [resolvedRowGap]);
167
+ const rowStyle = (0, _react.useMemo)(() => ({
168
+ flexDirection: 'row',
169
+ columnGap: resolvedColumnGap,
170
+ justifyContent: resolveRowJustifyContent(justifyContent),
171
+ alignItems: alignItems === 'stretch' ? 'stretch' : alignItems === 'center' ? 'center' : 'flex-start',
172
+ width: '100%'
173
+ }), [resolvedColumnGap, justifyContent, alignItems]);
174
+ const defaultAccessibilityLabel = accessibilityLabel ?? `Grid, ${safeColumns} column${safeColumns === 1 ? '' : 's'}, ${gridRows.length} row${gridRows.length === 1 ? '' : 's'}`;
175
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
176
+ style: [containerStyle, style],
177
+ accessibilityRole: "none",
178
+ accessibilityLabel: defaultAccessibilityLabel,
179
+ testID: testID,
180
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
181
+ style: [rowsContainerStyle, contentStyle],
182
+ children: gridRows.map((row, rowIndex) => {
183
+ const rowFr = normalizedRowFrs?.[rowIndex];
184
+ const spacersNeeded = justifyContent === 'space-between' && row.length < safeColumns ? safeColumns - row.length : 0;
185
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
186
+ style: rowFr != null ? [rowStyle, {
187
+ flexGrow: rowFr
188
+ }] : rowStyle,
189
+ children: [row.map((cell, columnIndex) => {
190
+ const absoluteIndex = rowIndex * safeColumns + columnIndex;
191
+ const cellFlexStyle = buildCellStyle(normalizedColumnFrs[columnIndex] ?? 1, justifyContent, alignItems);
192
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
193
+ style: [cellFlexStyle, cellStyle],
194
+ children: cell
195
+ }, `grid-cell-${absoluteIndex}`);
196
+ }), spacersNeeded > 0 && Array.from({
197
+ length: spacersNeeded
198
+ }, (_, spacerIndex) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
199
+ style: buildCellStyle(normalizedColumnFrs[row.length + spacerIndex] ?? 1, justifyContent, alignItems)
200
+ }, `grid-spacer-${rowIndex}-${spacerIndex}`))]
201
+ }, `grid-row-${rowIndex}`);
202
+ })
203
+ })
204
+ });
205
+ }
206
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(Grid);
@@ -61,6 +61,8 @@ function MoneyValue({
61
61
  negative,
62
62
  focused = false,
63
63
  hidden = false,
64
+ editable = false,
65
+ onValueChange,
64
66
  modes = _reactUtils.EMPTY_MODES,
65
67
  style,
66
68
  valueStyle,
@@ -72,24 +74,51 @@ function MoneyValue({
72
74
  ...rest
73
75
  }) {
74
76
  // Auto-detect negative from value and compute display value
75
- const {
76
- isNegative,
77
- displayValue
78
- } = (0, _react.useMemo)(() => {
79
- const stringValue = String(value);
80
- const trimmed = stringValue.trim();
81
- const valueIsNegative = trimmed.startsWith('-') || typeof value === 'number' && value < 0;
77
+ const stringValue = String(value);
78
+ const trimmed = stringValue.trim();
79
+ const valueIsNegative = trimmed.startsWith('-') || typeof value === 'number' && value < 0;
82
80
 
83
- // Strip leading minus sign for display (we show it separately)
84
- const absoluteValue = trimmed.startsWith('-') ? trimmed.slice(1) : trimmed;
81
+ // Strip leading minus sign for display (we show it separately)
82
+ const absoluteValue = trimmed.startsWith('-') ? trimmed.slice(1) : trimmed;
85
83
 
86
- // Use explicit negative prop if provided, otherwise use auto-detected
87
- const showNegative = negative !== undefined ? negative : valueIsNegative;
88
- return {
89
- isNegative: hidden ? false : showNegative,
90
- displayValue: hidden ? '•••' : absoluteValue
91
- };
92
- }, [value, negative, hidden]);
84
+ // Use explicit negative prop if provided, otherwise use auto-detected
85
+ const showNegative = negative !== undefined ? negative : valueIsNegative;
86
+ const isNegative = hidden ? false : showNegative;
87
+ const displayValue = hidden ? '•••' : absoluteValue;
88
+
89
+ // Inline editing state
90
+ const [isEditing, setIsEditing] = (0, _react.useState)(false);
91
+ const [editBuffer, setEditBuffer] = (0, _react.useState)('');
92
+ const inputRef = (0, _react.useRef)(null);
93
+ // Always-current snapshot of the display value for callbacks to reference.
94
+ const displayValueRef = (0, _react.useRef)(displayValue);
95
+ displayValueRef.current = displayValue;
96
+ const enterEditMode = (0, _react.useCallback)(() => {
97
+ setIsEditing(true);
98
+ setEditBuffer(displayValueRef.current);
99
+ // Focus the input on next frame so the keyboard opens
100
+ setTimeout(() => inputRef.current?.focus(), 0);
101
+ }, []);
102
+ const commitEdit = (0, _react.useCallback)(() => {
103
+ setIsEditing(false);
104
+ const resolved = editBuffer || '0';
105
+ if (resolved !== displayValueRef.current) {
106
+ onValueChange?.(resolved);
107
+ }
108
+ }, [editBuffer, onValueChange]);
109
+ const handleChangeText = (0, _react.useCallback)(text => {
110
+ // Allow only digits and at most one decimal point
111
+ const filtered = text.replace(/[^0-9.]/g, '');
112
+ const parts = filtered.split('.');
113
+ const clean = parts.length > 2 ? parts[0] + '.' + parts.slice(1).join('') : filtered;
114
+ setEditBuffer(clean);
115
+ }, []);
116
+ const handlePress = (0, _react.useCallback)(event => {
117
+ if (editable) {
118
+ enterEditMode();
119
+ }
120
+ onPress?.(event);
121
+ }, [editable, enterEditMode, onPress]);
93
122
 
94
123
  // Resolve typography and layout tokens from Figma
95
124
  const textColor = (0, _figmaVariablesResolver.getVariableByName)('moneyValue/text/color', modes);
@@ -150,44 +179,140 @@ function MoneyValue({
150
179
  cursorOpacity.setValue(0);
151
180
  }
152
181
  }, [focused, cursorOpacity]);
153
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
154
- style: [containerStyle, style],
155
- accessibilityRole: "text",
156
- accessibilityLabel: undefined,
157
- accessibilityHint: accessibilityHint,
158
- onPress: onPress,
159
- disabled: !onPress,
160
- ...rest,
161
- children: [isNegative && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
162
- style: [currencyTextStyle, negativeSignStyle],
163
- accessibilityElementsHidden: true,
164
- importantForAccessibility: "no",
165
- children: "-"
166
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
167
- style: [currencyTextStyle, currencyStyle],
168
- accessibilityElementsHidden: true,
169
- importantForAccessibility: "no",
170
- children: resolvedCurrency
171
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
172
- style: {
173
- flexDirection: 'row',
174
- alignItems: 'center'
175
- },
176
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
177
- style: [valueTextStyle, valueStyle],
178
- accessibilityElementsHidden: true,
179
- importantForAccessibility: "no",
180
- children: displayValue
181
- }), focused && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
182
- style: {
183
- opacity: cursorOpacity,
184
- width: 2,
185
- height: valueFontSize * 1.1,
186
- backgroundColor: textColor,
187
- marginLeft: 2
188
- }
189
- })]
190
- })]
182
+
183
+ // Keyboard avoidance — lift the component when the keyboard would cover it.
184
+ // Follows the same pattern as ActionFooter (uses Keyboard.addListener).
185
+ // Resets when editing ends or the keyboard hides.
186
+ const rootRef = (0, _react.useRef)(null);
187
+ const keyboardLift = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
188
+ const rootWindowYRef = (0, _react.useRef)(0);
189
+ const rootMeasuredHeightRef = (0, _react.useRef)(0);
190
+ const measureRoot = (0, _react.useCallback)(() => {
191
+ rootRef.current?.measureInWindow((_x, y, _w, h) => {
192
+ rootWindowYRef.current = y;
193
+ rootMeasuredHeightRef.current = h;
194
+ });
195
+ }, []);
196
+ const handleRootLayout = (0, _react.useCallback)(_e => {
197
+ // measureInWindow gives the component's position relative to the window,
198
+ // which is what we need for keyboard overlap calculation. onLayout fires
199
+ // after the component mounts and whenever its size changes.
200
+ measureRoot();
201
+ }, [measureRoot]);
202
+ (0, _react.useEffect)(() => {
203
+ if (!editable) return;
204
+ const showSub = _reactNative.Keyboard.addListener('keyboardDidShow', e => {
205
+ measureRoot();
206
+ if (!isEditing) return;
207
+ const kbHeight = e.endCoordinates.height;
208
+ const {
209
+ height: screenH
210
+ } = require('react-native').Dimensions.get('window');
211
+ const componentBottom = rootWindowYRef.current + rootMeasuredHeightRef.current;
212
+ const visibleBottom = screenH - kbHeight;
213
+ const overlap = componentBottom - visibleBottom + 12;
214
+ if (overlap > 0) {
215
+ _reactNative.Animated.timing(keyboardLift, {
216
+ toValue: -overlap,
217
+ duration: e.duration ?? 250,
218
+ useNativeDriver: true
219
+ }).start();
220
+ }
221
+ });
222
+ const hideSub = _reactNative.Keyboard.addListener('keyboardDidHide', () => {
223
+ _reactNative.Animated.timing(keyboardLift, {
224
+ toValue: 0,
225
+ duration: 150,
226
+ useNativeDriver: true
227
+ }).start();
228
+ });
229
+ return () => {
230
+ showSub.remove();
231
+ hideSub.remove();
232
+ };
233
+ }, [editable, isEditing, keyboardLift, measureRoot]);
234
+
235
+ // Reset lift when editing ends
236
+ (0, _react.useEffect)(() => {
237
+ if (!isEditing) {
238
+ keyboardLift.setValue(0);
239
+ }
240
+ }, [isEditing, keyboardLift]);
241
+ const handleBlur = (0, _react.useCallback)(() => {
242
+ commitEdit();
243
+ }, [commitEdit]);
244
+ const handleSubmitEditing = (0, _react.useCallback)(() => {
245
+ commitEdit();
246
+ }, [commitEdit]);
247
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
248
+ style: {
249
+ transform: [{
250
+ translateY: keyboardLift
251
+ }]
252
+ },
253
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
254
+ ref: rootRef,
255
+ onLayout: handleRootLayout,
256
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
257
+ style: [containerStyle, style],
258
+ accessibilityRole: "text",
259
+ accessibilityLabel: undefined,
260
+ accessibilityHint: accessibilityHint,
261
+ onPress: handlePress,
262
+ disabled: !onPress && !editable,
263
+ ...rest,
264
+ children: [isNegative && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
265
+ style: [currencyTextStyle, negativeSignStyle],
266
+ accessibilityElementsHidden: true,
267
+ importantForAccessibility: "no",
268
+ children: "-"
269
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
270
+ style: [currencyTextStyle, currencyStyle],
271
+ accessibilityElementsHidden: true,
272
+ importantForAccessibility: "no",
273
+ children: resolvedCurrency
274
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
275
+ style: {
276
+ flexDirection: 'row',
277
+ alignItems: 'center'
278
+ },
279
+ children: isEditing ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
280
+ ref: inputRef,
281
+ value: editBuffer,
282
+ onChangeText: handleChangeText,
283
+ onBlur: handleBlur,
284
+ onSubmitEditing: handleSubmitEditing,
285
+ keyboardType: "decimal-pad",
286
+ returnKeyType: "done",
287
+ selectTextOnFocus: true,
288
+ style: [valueTextStyle, valueStyle, {
289
+ padding: 0,
290
+ margin: 0,
291
+ // On web a thin border helps the cursor appear precisely
292
+ ...(_reactNative.Platform.OS === 'web' ? {
293
+ outlineStyle: 'none'
294
+ } : {})
295
+ }],
296
+ accessibilityLabel: accessibilityLabel || 'Edit value'
297
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
298
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
299
+ style: [valueTextStyle, valueStyle],
300
+ accessibilityElementsHidden: true,
301
+ importantForAccessibility: "no",
302
+ children: displayValue
303
+ }), focused && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
304
+ style: {
305
+ opacity: cursorOpacity,
306
+ width: 2,
307
+ height: valueFontSize * 1.1,
308
+ backgroundColor: textColor,
309
+ marginLeft: 2
310
+ }
311
+ })]
312
+ })
313
+ })]
314
+ })
315
+ })
191
316
  });
192
317
  }
193
318
  var _default = exports.default = MoneyValue;
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = NumberPagination;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _GlassFill = _interopRequireDefault(require("../../utils/GlassFill/GlassFill"));
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ 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); }
14
+ function resolveNumberPaginationTokens(modes) {
15
+ const horizontalPadding = (0, _figmaVariablesResolver.getVariableByName)('numberPagination/padding/horizontal', modes) ?? 4;
16
+ const verticalPadding = (0, _figmaVariablesResolver.getVariableByName)('numberPagination/padding/vertical', modes) ?? 4;
17
+ const radiusRaw = (0, _figmaVariablesResolver.getVariableByName)('numberPagination/radius', modes) ?? 9999;
18
+ const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('numberPagination/background/color', modes) ?? 'rgba(141, 141, 141, 0.4)';
19
+ const borderColor = (0, _figmaVariablesResolver.getVariableByName)('numberPagination/border/color', modes) ?? 'rgba(255, 255, 255, 0.15)';
20
+
21
+ // control number variables
22
+ const itemWidth = (0, _figmaVariablesResolver.getVariableByName)('controlNumber/width', modes) ?? 32;
23
+ const itemHeight = (0, _figmaVariablesResolver.getVariableByName)('controlNumber/height', modes) ?? 32;
24
+ const itemRadiusRaw = (0, _figmaVariablesResolver.getVariableByName)('controlNumber/radius', modes) ?? 9999;
25
+ const activeBgColor = (0, _figmaVariablesResolver.getVariableByName)('control/active/background/color', modes) ?? '#ffffff';
26
+ const activeTextColor = (0, _figmaVariablesResolver.getVariableByName)('control/active/text/color', modes) ?? '#000000';
27
+ const inactiveTextColor = (0, _figmaVariablesResolver.getVariableByName)('control/text/default', modes) ?? '#ffffff';
28
+
29
+ // typography variables
30
+ const fontFamily = (0, _figmaVariablesResolver.getVariableByName)('numberPagination/fontFamily', modes) ?? 'JioType';
31
+ const fontSize = (0, _figmaVariablesResolver.getVariableByName)('numberPagination/fontSize', modes) ?? 16;
32
+ const fontWeight = String((0, _figmaVariablesResolver.getVariableByName)('numberPagination/fontWeight', modes) ?? '500');
33
+ const lineHeight = (0, _figmaVariablesResolver.getVariableByName)('numberPagination/lineHeight', modes) ?? 18;
34
+ const blurMinimal = (0, _figmaVariablesResolver.getVariableByName)('blur/minimal', modes) ?? 29;
35
+ const blurIntensity = Math.max(0, Math.min(100, Math.round(Number(blurMinimal))));
36
+ const borderRadius = radiusRaw === 9999 ? 39 / 2 : radiusRaw;
37
+ const itemRadius = itemRadiusRaw === 9999 ? itemWidth / 2 : itemRadiusRaw;
38
+ return {
39
+ containerStyle: {
40
+ height: 39,
41
+ borderRadius,
42
+ borderWidth: 1,
43
+ borderColor,
44
+ backgroundColor: 'transparent',
45
+ overflow: 'hidden',
46
+ flexDirection: 'row',
47
+ alignItems: 'center',
48
+ paddingHorizontal: horizontalPadding,
49
+ paddingVertical: verticalPadding
50
+ },
51
+ activeItemStyle: {
52
+ width: itemWidth,
53
+ height: itemHeight,
54
+ borderRadius: itemRadius,
55
+ backgroundColor: activeBgColor,
56
+ alignItems: 'center',
57
+ justifyContent: 'center'
58
+ },
59
+ inactiveItemStyle: {
60
+ width: itemWidth,
61
+ height: itemHeight,
62
+ borderRadius: itemRadius,
63
+ backgroundColor: 'transparent',
64
+ alignItems: 'center',
65
+ justifyContent: 'center'
66
+ },
67
+ activeTextStyle: {
68
+ fontFamily,
69
+ fontSize,
70
+ fontWeight,
71
+ lineHeight,
72
+ color: activeTextColor,
73
+ textAlign: 'center'
74
+ },
75
+ inactiveTextStyle: {
76
+ fontFamily,
77
+ fontSize,
78
+ fontWeight,
79
+ lineHeight,
80
+ color: inactiveTextColor,
81
+ textAlign: 'center'
82
+ },
83
+ blurIntensity,
84
+ backgroundColor
85
+ };
86
+ }
87
+
88
+ /**
89
+ * NumberPagination component displays a horizontal list of page numbers on a frosted glass surface.
90
+ * All styling is driven by Figma design tokens with support for custom children slot.
91
+ */
92
+ function NumberPagination({
93
+ activePage = 1,
94
+ totalPages = 1,
95
+ onPageChange,
96
+ children,
97
+ modes,
98
+ style
99
+ }) {
100
+ const tokens = (0, _react.useMemo)(() => resolveNumberPaginationTokens(modes ?? {}), [modes]);
101
+ const renderPages = () => {
102
+ if (children) {
103
+ return children;
104
+ }
105
+ const pages = [];
106
+ for (let i = 1; i <= totalPages; i++) {
107
+ const active = i === activePage;
108
+ pages.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
109
+ onPress: () => onPageChange?.(i),
110
+ style: ({
111
+ pressed
112
+ }) => [active ? tokens.activeItemStyle : tokens.inactiveItemStyle, pressed && {
113
+ opacity: 0.7
114
+ }],
115
+ accessibilityRole: "button",
116
+ accessibilityState: {
117
+ selected: active
118
+ },
119
+ accessibilityLabel: `Page ${i}`,
120
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
121
+ style: active ? tokens.activeTextStyle : tokens.inactiveTextStyle,
122
+ children: i
123
+ })
124
+ }, i));
125
+ }
126
+ return pages;
127
+ };
128
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
129
+ style: [tokens.containerStyle, style],
130
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_GlassFill.default, {
131
+ tint: "light",
132
+ intensity: tokens.blurIntensity,
133
+ overlayColor: tokens.backgroundColor,
134
+ androidTintWash: false
135
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
136
+ style: {
137
+ flexDirection: 'row',
138
+ alignItems: 'center',
139
+ height: '100%'
140
+ },
141
+ children: renderPages()
142
+ })]
143
+ });
144
+ }
@@ -45,6 +45,9 @@ function PdpCcCard({
45
45
  media,
46
46
  title = 'Title',
47
47
  subtitle = 'Subtitle',
48
+ numberOfLines,
49
+ disableTruncation,
50
+ singleLine,
48
51
  metrics = DEFAULT_METRICS,
49
52
  buttonLabel = 'button',
50
53
  buttonIcon = 'ic_add_circle',
@@ -96,7 +99,10 @@ function PdpCcCard({
96
99
  title: title,
97
100
  subtitle: subtitle,
98
101
  textAlign: "Center",
99
- modes: modes
102
+ modes: modes,
103
+ numberOfLines: numberOfLines,
104
+ disableTruncation: disableTruncation,
105
+ singleLine: singleLine
100
106
  }), metrics.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
101
107
  style: styles.metricsRow,
102
108
  children: metrics.map((metric, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.default.Fragment, {