jfs-components 0.0.55 → 0.0.57

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 (48) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +2 -34
  2. package/lib/commonjs/components/AppBar/AppBar.js +4 -36
  3. package/lib/commonjs/components/FilterBar/FilterBar.js +2 -34
  4. package/lib/commonjs/components/LazyList/LazyList.js +2 -34
  5. package/lib/commonjs/components/MoneyValue/MoneyValue.js +1 -1
  6. package/lib/commonjs/components/NavArrow/NavArrow.js +45 -44
  7. package/lib/commonjs/components/Numpad/Numpad.js +6 -5
  8. package/lib/commonjs/components/Section/Section.js +7 -8
  9. package/lib/commonjs/components/TextInput/TextInput.js +4 -38
  10. package/lib/commonjs/components/TransactionBubble/TransactionBubble.js +149 -0
  11. package/lib/commonjs/components/index.js +7 -0
  12. package/lib/commonjs/design-tokens/JFSThemeProvider.js +38 -3
  13. package/lib/commonjs/icons/registry.js +1 -1
  14. package/lib/commonjs/utils/react-utils.js +18 -13
  15. package/lib/module/components/Accordion/Accordion.js +1 -33
  16. package/lib/module/components/AppBar/AppBar.js +1 -34
  17. package/lib/module/components/FilterBar/FilterBar.js +1 -35
  18. package/lib/module/components/LazyList/LazyList.js +1 -35
  19. package/lib/module/components/MoneyValue/MoneyValue.js +1 -1
  20. package/lib/module/components/NavArrow/NavArrow.js +44 -44
  21. package/lib/module/components/Numpad/Numpad.js +5 -5
  22. package/lib/module/components/Section/Section.js +8 -9
  23. package/lib/module/components/TextInput/TextInput.js +2 -36
  24. package/lib/module/components/TransactionBubble/TransactionBubble.js +144 -0
  25. package/lib/module/components/index.js +1 -0
  26. package/lib/module/design-tokens/JFSThemeProvider.js +35 -3
  27. package/lib/module/icons/registry.js +1 -1
  28. package/lib/module/utils/react-utils.js +18 -13
  29. package/lib/typescript/src/components/NavArrow/NavArrow.d.ts +6 -11
  30. package/lib/typescript/src/components/TransactionBubble/TransactionBubble.d.ts +39 -0
  31. package/lib/typescript/src/components/index.d.ts +1 -0
  32. package/lib/typescript/src/design-tokens/JFSThemeProvider.d.ts +15 -0
  33. package/lib/typescript/src/icons/registry.d.ts +1 -1
  34. package/package.json +1 -1
  35. package/src/components/Accordion/Accordion.tsx +1 -44
  36. package/src/components/AppBar/AppBar.tsx +1 -44
  37. package/src/components/FilterBar/FilterBar.tsx +1 -44
  38. package/src/components/LazyList/LazyList.tsx +1 -41
  39. package/src/components/MoneyValue/MoneyValue.tsx +1 -1
  40. package/src/components/NavArrow/NavArrow.tsx +46 -43
  41. package/src/components/Numpad/Numpad.tsx +5 -5
  42. package/src/components/Section/Section.tsx +8 -8
  43. package/src/components/TextInput/TextInput.tsx +1 -44
  44. package/src/components/TransactionBubble/TransactionBubble.tsx +155 -0
  45. package/src/components/index.ts +1 -0
  46. package/src/design-tokens/JFSThemeProvider.tsx +37 -2
  47. package/src/icons/registry.ts +1 -1
  48. package/src/utils/react-utils.ts +29 -21
@@ -9,6 +9,7 @@ var _reactNative = require("react-native");
9
9
  var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
10
  var _Icon = _interopRequireDefault(require("../../icons/Icon"));
11
11
  var _webPlatformUtils = require("../../utils/web-platform-utils");
12
+ var _reactUtils = require("../../utils/react-utils");
12
13
  var _jsxRuntime = require("react/jsx-runtime");
13
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
15
  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); }
@@ -16,39 +17,6 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
16
17
  if (_reactNative.Platform.OS === 'android' && _reactNative.UIManager.setLayoutAnimationEnabledExperimental) {
17
18
  _reactNative.UIManager.setLayoutAnimationEnabledExperimental(true);
18
19
  }
19
-
20
- /**
21
- * Helper function to recursively clone children and pass modes prop to components that accept it.
22
- * This ensures that all child components in slots receive the modes prop from the parent.
23
- */
24
- function cloneChildrenWithModes(children, modes) {
25
- const result = _react.default.Children.map(children, child => {
26
- if (! /*#__PURE__*/_react.default.isValidElement(child)) {
27
- return child;
28
- }
29
-
30
- // Get existing children
31
- const childChildren = child.props?.children;
32
- const hasChildren = childChildren !== undefined && childChildren !== null;
33
-
34
- // Merge modes: parent modes first, then child's explicit modes override them
35
- const existingModes = child.props?.modes;
36
- const mergedModes = existingModes ? {
37
- ...modes,
38
- ...existingModes
39
- } : modes;
40
-
41
- // Recursively process children if they exist
42
- const processedChildren = hasChildren ? cloneChildrenWithModes(_react.default.Children.toArray(childChildren), modes) : undefined;
43
-
44
- // Clone element with modes and processed children
45
- return /*#__PURE__*/_react.default.cloneElement(child, {
46
- ...child.props,
47
- modes: mergedModes
48
- }, processedChildren);
49
- });
50
- return result || [];
51
- }
52
20
  /**
53
21
  * Accordion component that mirrors the Figma "Accordion" component.
54
22
  *
@@ -173,7 +141,7 @@ function Accordion({
173
141
  });
174
142
 
175
143
  // Process children to pass modes
176
- const processedChildren = children ? cloneChildrenWithModes(_react.default.Children.toArray(children), modes) : null;
144
+ const processedChildren = children ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(children), modes) : null;
177
145
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
178
146
  style: [containerStyle, style],
179
147
  ...rest,
@@ -9,41 +9,9 @@ var _reactNative = require("react-native");
9
9
  var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
10
  var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
11
11
  var _NavArrow = _interopRequireDefault(require("../NavArrow/NavArrow"));
12
+ var _reactUtils = require("../../utils/react-utils");
12
13
  var _jsxRuntime = require("react/jsx-runtime");
13
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- // We might need to import Image or Svg if we had the assets locally, but for now we'll use placeholders or standard icons for defaults.
15
- // The user prompt mentioned "Use getVariableByName... strict camelCase".
16
-
17
- /**
18
- * Helper function to recursively clone children and pass modes prop to components that accept it.
19
- */function cloneChildrenWithModes(children, modes) {
20
- return _react.default.Children.map(children, child => {
21
- if (! /*#__PURE__*/_react.default.isValidElement(child)) {
22
- return child;
23
- }
24
-
25
- // Get existing children
26
- const childChildren = child.props?.children;
27
- const hasChildren = childChildren !== undefined && childChildren !== null;
28
-
29
- // Clone the child with modes prop if it doesn't already have one
30
- // or merge with existing modes if it does
31
- const existingModes = child.props?.modes;
32
- const mergedModes = existingModes ? {
33
- ...modes,
34
- ...existingModes
35
- } : modes;
36
-
37
- // Recursively process children if they exist
38
- const processedChildren = hasChildren ? cloneChildrenWithModes(_react.default.Children.toArray(childChildren), modes) : undefined;
39
-
40
- // Clone element with modes and processed children
41
- return /*#__PURE__*/_react.default.cloneElement(child, {
42
- ...child.props,
43
- modes: mergedModes
44
- }, processedChildren);
45
- })?.filter(child => child !== null && child !== undefined) ?? [];
46
- }
47
15
  function AppBar({
48
16
  type = 'MainPage',
49
17
  leadingSlot,
@@ -133,8 +101,8 @@ function AppBar({
133
101
  }
134
102
 
135
103
  // --- Process Slots ---
136
- const processedLeading = leadingSlot ? cloneChildrenWithModes([leadingSlot], modes)[0] : defaultLeading;
137
- const processedMiddle = middleSlot ? cloneChildrenWithModes(_react.default.Children.toArray(middleSlot), modes) : null;
104
+ const processedLeading = leadingSlot ? (0, _reactUtils.cloneChildrenWithModes)([leadingSlot], modes)[0] : defaultLeading;
105
+ const processedMiddle = middleSlot ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(middleSlot), modes) : null;
138
106
 
139
107
  // Actions Gap wrapper
140
108
  // The Figma has "Actions" slot with a gap.
@@ -145,7 +113,7 @@ function AppBar({
145
113
  };
146
114
  const processedActions = actionsSlot ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
147
115
  style: actionsStyle,
148
- children: cloneChildrenWithModes(_react.default.Children.toArray(actionsSlot), modes)
116
+ children: (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(actionsSlot), modes)
149
117
  }) : null;
150
118
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
151
119
  style: [containerStyle, style],
@@ -8,42 +8,10 @@ var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
10
  var _TextInput = _interopRequireDefault(require("../TextInput/TextInput"));
11
+ var _reactUtils = require("../../utils/react-utils");
11
12
  var _jsxRuntime = require("react/jsx-runtime");
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
14
  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
- /**
15
- * Helper function to recursively clone children and pass modes prop to components that accept it.
16
- * This ensures that all child components in slots receive the modes prop from the parent.
17
- */function cloneChildrenWithModes(children, modes) {
18
- const result = _react.default.Children.map(children, child => {
19
- if (! /*#__PURE__*/_react.default.isValidElement(child)) {
20
- return child;
21
- }
22
-
23
- // Get existing children
24
- const childChildren = child.props?.children;
25
- const hasChildren = childChildren !== undefined && childChildren !== null;
26
-
27
- // Clone the child with modes prop if it doesn't already have one
28
- // or merge with existing modes if it does
29
- // Merge order: parent modes first, then child's explicit modes override them
30
- const existingModes = child.props?.modes;
31
- const mergedModes = existingModes ? {
32
- ...modes,
33
- ...existingModes
34
- } : modes;
35
-
36
- // Recursively process children if they exist
37
- const processedChildren = hasChildren ? cloneChildrenWithModes(_react.default.Children.toArray(childChildren), modes) : undefined;
38
-
39
- // Clone element with modes and processed children
40
- return /*#__PURE__*/_react.default.cloneElement(child, {
41
- ...child.props,
42
- modes: mergedModes
43
- }, processedChildren);
44
- });
45
- return result || [];
46
- }
47
15
  /**
48
16
  * FilterBar component that mirrors the Figma "filterBar" component.
49
17
  *
@@ -125,7 +93,7 @@ function FilterBar({
125
93
  });
126
94
  } else if (children) {
127
95
  // Clone custom children and inject onFocus/onBlur where possible.
128
- const cloned = cloneChildrenWithModes(_react.default.Children.toArray(children), modes);
96
+ const cloned = (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(children), modes);
129
97
  processedChildren = _react.default.Children.map(cloned, child => {
130
98
  if (! /*#__PURE__*/_react.default.isValidElement(child)) return child;
131
99
  const existingOnFocus = child.props?.onFocus;
@@ -7,41 +7,9 @@ exports.default = void 0;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _reactUtils = require("../../utils/react-utils");
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
- /**
13
- * Helper function to recursively clone children and pass modes prop to components that accept it.
14
- * This ensures that all child components in slots receive the modes prop from the parent.
15
- */function cloneChildrenWithModes(children, modes) {
16
- return _react.default.Children.map(children, child => {
17
- if (! /*#__PURE__*/_react.default.isValidElement(child)) {
18
- return child;
19
- }
20
-
21
- // Get existing children
22
- const childProps = child.props;
23
- const childChildren = childProps?.children;
24
- const hasChildren = childChildren !== undefined && childChildren !== null;
25
-
26
- // Clone the child with modes prop if it doesn't already have one
27
- // or merge with existing modes if it does
28
- // Merge order: parent modes first, then child's explicit modes override them
29
- const existingModes = childProps?.modes;
30
- const mergedModes = existingModes ? {
31
- ...modes,
32
- ...existingModes
33
- } : modes;
34
-
35
- // Recursively process children if they exist
36
- const processedChildren = hasChildren ? cloneChildrenWithModes(_react.default.Children.toArray(childChildren), modes) : undefined;
37
-
38
- // Clone element with modes and processed children
39
- return /*#__PURE__*/_react.default.cloneElement(child, {
40
- ...childProps,
41
- modes: mergedModes
42
- }, processedChildren);
43
- });
44
- }
45
13
  /**
46
14
  * LazyList component that mirrors the Figma "LazyList" component.
47
15
  *
@@ -85,7 +53,7 @@ function LazyList({
85
53
  };
86
54
 
87
55
  // Clone listGroupsSlot children and pass modes to all children that accept it
88
- const processedSlot = listGroupsSlot ? cloneChildrenWithModes(_react.default.Children.toArray(listGroupsSlot), modes) : null;
56
+ const processedSlot = listGroupsSlot ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(listGroupsSlot), modes) : null;
89
57
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
90
58
  style: [containerStyle, style],
91
59
  accessibilityRole: "list",
@@ -99,7 +99,7 @@ function MoneyValue({
99
99
  const fontWeightValue = (0, _figmaVariablesResolver.getVariableByName)('moneyValue/fontWeight', modes) || 500;
100
100
  const fontWeight = typeof fontWeightValue === 'number' ? fontWeightValue.toString() : fontWeightValue;
101
101
  const fontFamily = (0, _figmaVariablesResolver.getVariableByName)('moneyValue/fontFamily', modes) || 'System';
102
- const gap = (0, _figmaVariablesResolver.getVariableByName)('moneyValue/gap', modes) || 4;
102
+ const gap = (0, _figmaVariablesResolver.getVariableByName)('moneyValue/gap', modes) ?? 4;
103
103
 
104
104
  // Resolve currency to a symbol, supporting both symbols and ISO codes
105
105
  const resolvedCurrency = (0, _react.useMemo)(() => {
@@ -6,28 +6,24 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = NavArrow;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _reactNative = require("react-native");
9
+ var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
9
10
  var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
- var _Icon = _interopRequireDefault(require("../../icons/Icon"));
11
11
  var _jsxRuntime = require("react/jsx-runtime");
12
+ 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); }
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
14
  /**
14
- * NavArrow component that displays a small chevron arrow for navigation.
15
+ * NavArrow component that displays a chevron arrow for navigation.
15
16
  *
16
- * This component uses design tokens for all visual properties:
17
+ * Renders a stroked SVG chevron whose dimensions and thickness are
18
+ * fully driven by design tokens:
17
19
  * - navArrow/icon/color - chevron stroke color
18
- * - navArrow/icon/width - icon width
19
- * - navArrow/icon/height - icon height
20
- * - navArrow/icon/strokeWeight - stroke width
20
+ * - navArrow/icon/width - chevron arm width (horizontal spread)
21
+ * - navArrow/icon/height - chevron arm height (vertical spread)
22
+ * - navArrow/icon/strokeWeight - stroke thickness
21
23
  * - navArrow/width - container width
22
24
  * - navArrow/height - container height
23
25
  * - navArrow/radius - border radius
24
26
  * - navArrow/background - background color
25
- *
26
- * @component
27
- * @param {Object} props
28
- * @param {'Back'|'Forward'|'Down'} [props.direction='Back'] - Arrow direction
29
- * @param {Object} [props.modes={}] - Modes for design token resolution
30
- * @param {Object} [props.style] - Additional container styles
31
27
  */
32
28
  function NavArrow({
33
29
  direction = 'Back',
@@ -36,22 +32,20 @@ function NavArrow({
36
32
  accessibilityLabel,
37
33
  ...rest
38
34
  }) {
39
- // Resolve design tokens
40
35
  const iconColor = (0, _figmaVariablesResolver.getVariableByName)('navArrow/icon/color', modes) || '#24262b';
41
-
42
- // Dimensions from tokens
43
36
  const widthToken = Number((0, _figmaVariablesResolver.getVariableByName)('navArrow/width', modes)) || 6;
44
37
  const heightToken = Number((0, _figmaVariablesResolver.getVariableByName)('navArrow/height', modes)) || 10;
45
38
  const borderRadius = Number((0, _figmaVariablesResolver.getVariableByName)('navArrow/radius', modes)) || 0;
46
39
  const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('navArrow/background', modes) || 'transparent';
47
-
48
- // Swap dimensions if direction is Down
40
+ const iconWidth = Number((0, _figmaVariablesResolver.getVariableByName)('navArrow/icon/width', modes)) || 4;
41
+ const iconHeight = Number((0, _figmaVariablesResolver.getVariableByName)('navArrow/icon/height', modes)) || 8;
42
+ const strokeWeight = Number((0, _figmaVariablesResolver.getVariableByName)('navArrow/icon/strokeWeight', modes)) || 2;
49
43
  const isDown = direction === 'Down';
50
- const width = isDown ? heightToken : widthToken;
51
- const height = isDown ? widthToken : heightToken;
44
+ const containerWidth = isDown ? heightToken : widthToken;
45
+ const containerHeight = isDown ? widthToken : heightToken;
52
46
  const containerStyle = {
53
- width,
54
- height,
47
+ width: containerWidth,
48
+ height: containerHeight,
55
49
  borderRadius,
56
50
  backgroundColor,
57
51
  alignItems: 'center',
@@ -59,34 +53,41 @@ function NavArrow({
59
53
  ...(style || {})
60
54
  };
61
55
  const defaultAccessibilityLabel = accessibilityLabel || (direction === 'Back' ? 'Go back' : direction === 'Forward' ? 'Go forward' : 'Go down');
62
-
63
- // Map direction to icon name
64
- let iconName = 'ic_chevron_left'; // Default for Back
65
- if (direction === 'Forward') {
66
- iconName = 'ic_chevron_right';
67
- } else if (direction === 'Down') {
68
- iconName = 'ic_chevron_down';
56
+ const chevronW = isDown ? iconHeight : iconWidth;
57
+ const chevronH = isDown ? iconWidth : iconHeight;
58
+ const pad = strokeWeight / 2;
59
+ const svgWidth = chevronW + pad * 2;
60
+ const svgHeight = chevronH + pad * 2;
61
+ let points;
62
+ switch (direction) {
63
+ case 'Forward':
64
+ points = `${pad},${pad} ${chevronW + pad},${chevronH / 2 + pad} ${pad},${chevronH + pad}`;
65
+ break;
66
+ case 'Down':
67
+ points = `${pad},${pad} ${chevronW / 2 + pad},${chevronH + pad} ${chevronW + pad},${pad}`;
68
+ break;
69
+ case 'Back':
70
+ default:
71
+ points = `${chevronW + pad},${pad} ${pad},${chevronH / 2 + pad} ${chevronW + pad},${chevronH + pad}`;
72
+ break;
69
73
  }
70
74
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
71
75
  style: containerStyle,
72
76
  accessibilityRole: "image",
73
- accessibilityLabel: undefined,
77
+ accessibilityLabel: defaultAccessibilityLabel,
74
78
  ...rest,
75
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
76
- name: iconName,
77
- size: 24 // Internal icon size is fixed/clipped by container in design but Icon requires a size
78
- ,
79
- color: iconColor,
80
- style: {
81
- // Center the larger icon within the small container if needed,
82
- // though flex center on container handles this.
83
- // If the container is 6x10 and icon is 24, we might want to ensure it doesn't affect layout
84
- // but Flexbox 'center' centers the content.
85
- // However, if the icon component has its own frame, it might overflow.
86
- // React Native View has overflow: 'hidden' by default if borderRadius is set? No.
87
- // We might want overflow: 'hidden' if strictly following design clip.
88
- // Figma design had "overflow-clip" class.
89
- }
79
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.default, {
80
+ width: svgWidth,
81
+ height: svgHeight,
82
+ viewBox: `0 0 ${svgWidth} ${svgHeight}`,
83
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Polyline, {
84
+ points: points,
85
+ stroke: iconColor,
86
+ strokeWidth: strokeWeight,
87
+ strokeLinecap: "round",
88
+ strokeLinejoin: "round",
89
+ fill: "none"
90
+ })
90
91
  })
91
92
  });
92
93
  }
@@ -7,8 +7,9 @@ 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");
10
- var _IconDeletebackspace = require("../../icons/components/IconDeletebackspace");
10
+ var _Icon = _interopRequireDefault(require("../../icons/Icon"));
11
11
  var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
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); }
13
14
  function shuffleArray(arr) {
14
15
  const shuffled = [...arr];
@@ -92,10 +93,10 @@ function Numpad({
92
93
  onPress: () => handlePress(key),
93
94
  accessibilityRole: "button",
94
95
  accessibilityLabel: isBackspace ? 'Backspace' : key,
95
- children: isBackspace ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconDeletebackspace.IconDeletebackspace, {
96
- width: fontSize,
97
- height: fontSize,
98
- fill: foreground
96
+ children: isBackspace ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
97
+ name: "ic_delete_backspace",
98
+ size: fontSize,
99
+ color: foreground
99
100
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
100
101
  style: [textStyle, keyTextStyle],
101
102
  children: key
@@ -66,7 +66,8 @@ function Section({
66
66
  } : {};
67
67
  // Resolve section container tokens
68
68
  const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('section/background/color', modes) || '#ffffff';
69
- const gap = (0, _figmaVariablesResolver.getVariableByName)('slot/gap', modes) || 12;
69
+ const sectionGap = (0, _figmaVariablesResolver.getVariableByName)('section/gap', modes) || 12;
70
+ const slotGap = (0, _figmaVariablesResolver.getVariableByName)('slot/gap', modes) || 12;
70
71
  const paddingHorizontal = (0, _figmaVariablesResolver.getVariableByName)('section/padding/horizontal', modes) || 12;
71
72
  const paddingVertical = (0, _figmaVariablesResolver.getVariableByName)('section/padding/vertical', modes) || 16;
72
73
  const radius = (0, _figmaVariablesResolver.getVariableByName)('section/radius', modes) || 12;
@@ -96,7 +97,7 @@ function Section({
96
97
  paddingHorizontal,
97
98
  paddingVertical,
98
99
  borderRadius: radius,
99
- gap
100
+ gap: sectionGap
100
101
  };
101
102
  const headerStyle = {
102
103
  paddingHorizontal: headerPaddingHorizontal,
@@ -204,9 +205,9 @@ function Section({
204
205
  }), slot && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
205
206
  style: {
206
207
  flexDirection: slotDirection,
207
- gap
208
+ gap: slotGap
208
209
  },
209
- children: (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(slot), modes)
210
+ children: (0, _reactUtils.cloneChildrenWithModes)((0, _reactUtils.flattenChildren)(slot), modes)
210
211
  })]
211
212
  });
212
213
  }
@@ -254,10 +255,8 @@ function SectionBento({
254
255
  borderRadius: radius,
255
256
  gap
256
257
  };
257
-
258
- // Process slots to pass modes to children
259
- const processedNavSlot = navSlot ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(navSlot), modes) : null;
260
- const processedUpiSlot = upiSlot ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(upiSlot), modes) : null;
258
+ const processedNavSlot = navSlot ? (0, _reactUtils.cloneChildrenWithModes)((0, _reactUtils.flattenChildren)(navSlot), modes) : null;
259
+ const processedUpiSlot = upiSlot ? (0, _reactUtils.cloneChildrenWithModes)((0, _reactUtils.flattenChildren)(upiSlot), modes) : null;
261
260
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
262
261
  style: [containerStyle, style],
263
262
  ...(_reactNative.Platform.OS === 'web' ? {
@@ -8,43 +8,10 @@ var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
10
  var _Icon = _interopRequireDefault(require("../../icons/Icon"));
11
+ var _reactUtils = require("../../utils/react-utils");
11
12
  var _jsxRuntime = require("react/jsx-runtime");
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
14
  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
- /**
15
- * Helper function to recursively clone children and pass modes prop to components that accept it.
16
- * This ensures that all child components in slots receive the modes prop from the parent.
17
- */function cloneChildrenWithModes(children, modes) {
18
- const result = _react.default.Children.map(children, child => {
19
- if (! /*#__PURE__*/_react.default.isValidElement(child)) {
20
- return child;
21
- }
22
-
23
- // Get existing children
24
- const childChildren = child.props?.children;
25
- const hasChildren = childChildren !== undefined && childChildren !== null;
26
-
27
- // Clone the child with modes prop if it doesn't already have one
28
- // or merge with existing modes if it does
29
- // Merge order: parent modes first, then child's explicit modes override them
30
- const existingModes = child.props?.modes;
31
- const mergedModes = existingModes ? {
32
- ...modes,
33
- ...existingModes
34
- } : modes;
35
-
36
- // Recursively process children if they exist
37
- const processedChildren = hasChildren ? cloneChildrenWithModes(_react.default.Children.toArray(childChildren), modes) : undefined;
38
-
39
- // Clone element with modes and processed children
40
- return /*#__PURE__*/_react.default.cloneElement(child, {
41
- ...child.props,
42
- modes: mergedModes
43
- }, processedChildren);
44
- });
45
- return result || [];
46
- }
47
-
48
15
  /**
49
16
  * TextInput component that mirrors the Figma "textInput" component.
50
17
  *
@@ -76,8 +43,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
76
43
  /**
77
44
  * Helper function to convert a color to a more transparent version for placeholder text.
78
45
  * Takes a color string (hex, rgb, rgba) and returns it with reduced opacity.
79
- */
80
- function makePlaceholderColor(color, opacity = 0.5) {
46
+ */function makePlaceholderColor(color, opacity = 0.5) {
81
47
  if (!color || typeof color !== 'string') {
82
48
  return color || '';
83
49
  }
@@ -220,8 +186,8 @@ function TextInput({
220
186
  });
221
187
 
222
188
  // Clone leading and trailing slots and pass modes to all children that accept it
223
- const processedLeading = leadingElement ? cloneChildrenWithModes(_react.default.Children.toArray(leadingElement), modes) : null;
224
- const processedTrailing = trailing ? cloneChildrenWithModes(_react.default.Children.toArray(trailing), modes) : null;
189
+ const processedLeading = leadingElement ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(leadingElement), modes) : null;
190
+ const processedTrailing = trailing ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(trailing), modes) : null;
225
191
 
226
192
  // Handle focus events
227
193
  const handleFocus = e => {
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _MoneyValue = _interopRequireDefault(require("../MoneyValue/MoneyValue"));
11
+ var _TransactionStatus = _interopRequireDefault(require("../TransactionStatus/TransactionStatus"));
12
+ var _NavArrow = _interopRequireDefault(require("../NavArrow/NavArrow"));
13
+ var _reactUtils = require("../../utils/react-utils");
14
+ var _webPlatformUtils = require("../../utils/web-platform-utils");
15
+ var _jsxRuntime = require("react/jsx-runtime");
16
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
+ /**
18
+ * TransactionBubble — Figma node 1517:1155.
19
+ *
20
+ * Layout (vertical stack inside a rounded bordered pill):
21
+ *
22
+ * ┌──────────────────────────────────────────────┐
23
+ * │ Description │
24
+ * │ ₹56 │
25
+ * │ [slot / children content] │
26
+ * │ ⚠ Expired · 20 Mar 2025 › │
27
+ * └──────────────────────────────────────────────┘
28
+ *
29
+ * moneyValueWrap: description + MoneyValue, vertical with `transactionBubble/wrap/gap`.
30
+ * slotWrap: children (optional), rendered between moneyValueWrap and statusWrap.
31
+ * statusWrap: TransactionStatus + NavArrow, horizontal row with `transactionBubble/statusWrap/gap`.
32
+ * Container gap between sections: `transactionBubble/gap`.
33
+ */
34
+ function TransactionBubble({
35
+ description = 'Payment to Uber India',
36
+ value = '56',
37
+ currency = '₹',
38
+ status = 'Expired',
39
+ date = '20 Mar 2025',
40
+ statusSlot,
41
+ children,
42
+ modes = {},
43
+ onPress,
44
+ style,
45
+ accessibilityLabel,
46
+ accessibilityHint,
47
+ webAccessibilityProps,
48
+ ...rest
49
+ }) {
50
+ const resolvedModes = {
51
+ ...modes,
52
+ 'Context3': 'Transaction Bubble'
53
+ };
54
+ const padding = Number((0, _figmaVariablesResolver.getVariableByName)('transactionBubble/padding', resolvedModes)) || 16;
55
+ const radius = Number((0, _figmaVariablesResolver.getVariableByName)('transactionBubble/radius', resolvedModes)) || 23;
56
+ const borderSize = Number((0, _figmaVariablesResolver.getVariableByName)('transactionBubble/border/size', resolvedModes)) || 1;
57
+ const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('transactionBubble/background', resolvedModes) || '#ffffff';
58
+ const borderColor = (0, _figmaVariablesResolver.getVariableByName)('transactionBubble/border/color', resolvedModes) || '#e5e5e5';
59
+ const bubbleGap = Number((0, _figmaVariablesResolver.getVariableByName)('transactionBubble/gap', resolvedModes)) || 8;
60
+ const moneyValueWrapGap = Number((0, _figmaVariablesResolver.getVariableByName)('transactionBubble/wrap/gap', resolvedModes)) || 8;
61
+ const descriptionColor = (0, _figmaVariablesResolver.getVariableByName)('transactionBubble/description/color', resolvedModes) || '#24262b';
62
+ const descriptionFontSize = Number((0, _figmaVariablesResolver.getVariableByName)('transactionBubble/description/fontSize', resolvedModes)) || 14;
63
+ const descriptionLineHeight = Number((0, _figmaVariablesResolver.getVariableByName)('transactionBubble/description/lineHeight', resolvedModes)) || 17;
64
+ const descriptionFontFamily = (0, _figmaVariablesResolver.getVariableByName)('transactionBubble/description/fontFamily', resolvedModes) || 'JioType Var';
65
+ const statusWrapGap = Number((0, _figmaVariablesResolver.getVariableByName)('transactionBubble/statusWrap/gap', resolvedModes)) || 4;
66
+ const statusWrapHeight = Number((0, _figmaVariablesResolver.getVariableByName)('transactionBubble/statusWrap/height', resolvedModes)) || 18;
67
+ const containerStyle = {
68
+ padding,
69
+ borderRadius: radius,
70
+ borderWidth: borderSize,
71
+ borderColor,
72
+ backgroundColor
73
+ };
74
+ const descriptionStyle = {
75
+ color: descriptionColor,
76
+ fontSize: descriptionFontSize,
77
+ lineHeight: descriptionLineHeight,
78
+ fontFamily: descriptionFontFamily
79
+ };
80
+ const processedChildren = children ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(children), resolvedModes) : null;
81
+ const processedStatusSlot = statusSlot ? (0, _reactUtils.cloneChildrenWithModes)(_react.default.Children.toArray(statusSlot), resolvedModes) : null;
82
+ const defaultAccessibilityLabel = accessibilityLabel || `${description} • ${status}`;
83
+ const webProps = (0, _webPlatformUtils.usePressableWebSupport)({
84
+ restProps: rest,
85
+ onPress,
86
+ disabled: false,
87
+ accessibilityLabel: defaultAccessibilityLabel,
88
+ webAccessibilityProps
89
+ });
90
+ const statusRow = processedStatusSlot || /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
91
+ style: {
92
+ flexDirection: 'row',
93
+ alignItems: 'center',
94
+ justifyContent: 'space-between',
95
+ gap: statusWrapGap,
96
+ height: statusWrapHeight
97
+ },
98
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_TransactionStatus.default, {
99
+ status: status,
100
+ date: date,
101
+ modes: resolvedModes
102
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_NavArrow.default, {
103
+ direction: "Forward",
104
+ modes: resolvedModes
105
+ })]
106
+ });
107
+ const mainContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
108
+ style: {
109
+ gap: bubbleGap
110
+ },
111
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
112
+ style: {
113
+ gap: moneyValueWrapGap
114
+ },
115
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
116
+ style: descriptionStyle,
117
+ numberOfLines: 1,
118
+ children: description
119
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_MoneyValue.default, {
120
+ value: value,
121
+ currency: currency,
122
+ modes: resolvedModes
123
+ })]
124
+ }), processedChildren, statusRow]
125
+ });
126
+ if (onPress) {
127
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
128
+ onPress: onPress,
129
+ style: ({
130
+ pressed
131
+ }) => [containerStyle, style, pressed && {
132
+ opacity: 0.85
133
+ }],
134
+ accessibilityRole: "button",
135
+ accessibilityLabel: defaultAccessibilityLabel,
136
+ accessibilityHint: accessibilityHint,
137
+ ...webProps,
138
+ ...rest,
139
+ children: mainContent
140
+ });
141
+ }
142
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
143
+ style: [containerStyle, style],
144
+ accessibilityLabel: defaultAccessibilityLabel,
145
+ accessibilityHint: accessibilityHint,
146
+ children: mainContent
147
+ });
148
+ }
149
+ var _default = exports.default = TransactionBubble;