jfs-components 0.1.55 → 0.1.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.
@@ -69,8 +69,11 @@ function cloneChildrenWithModes(children, modes, forcedModes) {
69
69
  } : modes;
70
70
  let processedChildren;
71
71
  if (hasChildren) {
72
+ // Descendants inherit this child's merged modes, not the ancestor's
73
+ // raw modes — so nested containers (e.g. ButtonGroup Neutral inside
74
+ // a CardCTA slot that injects Secondary) can cascade correctly.
72
75
  const childArray = _react.default.Children.toArray(childChildren);
73
- const processed = cloneChildrenWithModes(childArray, modes, forcedModes);
76
+ const processed = cloneChildrenWithModes(childArray, mergedModes, forcedModes);
74
77
  processedChildren = processed.length === 1 ? processed[0] : processed;
75
78
  }
76
79
  result.push(/*#__PURE__*/_react.default.cloneElement(child, {
@@ -3,21 +3,21 @@
3
3
  import React from 'react';
4
4
  import { View } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
- import { EMPTY_MODES, flattenChildren } from '../../utils/react-utils';
6
+ import { EMPTY_MODES, cloneChildrenWithModes, flattenChildren } from '../../utils/react-utils';
7
7
  import IconButton from '../IconButton/IconButton';
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
9
9
  /**
10
10
  * ButtonGroup component that aggregates multiple buttons (e.g., IconButton)
11
11
  * and handles their layout and styling/theming via design tokens.
12
12
  *
13
- * It passes the provided `modes` to all its immediate React Element children.
14
- * Non-IconButton children (e.g., Button) are automatically stretched to fill
15
- * available space. IconButton children keep their natural width.
13
+ * Group `modes` cascade to every child (and nested slot children). A child's
14
+ * own `modes` still win on conflict. Non-IconButton children (e.g. Button) are
15
+ * stretched to fill available space; IconButton children keep intrinsic width.
16
16
  *
17
17
  * @component
18
18
  * @example
19
19
  * ```jsx
20
- * <ButtonGroup modes={{"Color Mode": "Light"}}>
20
+ * <ButtonGroup modes={{"Color Mode": "Light", AppearanceBrand: "Neutral"}}>
21
21
  * <IconButton iconName="ic_qr_code" />
22
22
  * <Button label="Pay" />
23
23
  * </ButtonGroup>
@@ -28,12 +28,9 @@ function ButtonGroup({
28
28
  modes = EMPTY_MODES,
29
29
  style
30
30
  }) {
31
- // Resolve design tokens
32
31
  const gap = getVariableByName('buttonGroup/gap', modes) ?? 12;
33
32
  const paddingHorizontal = getVariableByName('buttonGroup/padding/horizontal', modes) ?? 0;
34
33
  const paddingVertical = getVariableByName('buttonGroup/padding/vertical', modes) ?? 0;
35
-
36
- // Container style
37
34
  const containerStyle = {
38
35
  flexDirection: 'row',
39
36
  alignItems: 'center',
@@ -41,27 +38,20 @@ function ButtonGroup({
41
38
  paddingHorizontal: paddingHorizontal,
42
39
  paddingVertical: paddingVertical
43
40
  };
44
-
45
- // Flatten children to handle Fragments properly
46
41
  const flatChildren = flattenChildren(children);
47
- const childrenWithModes = React.Children.map(flatChildren, child => {
48
- if (/*#__PURE__*/React.isValidElement(child)) {
49
- const element = child;
50
- const childModes = element.props.modes || {};
51
- const mergedModes = {
52
- ...modes,
53
- ...childModes
54
- };
55
- const isIconButton = element.type === IconButton;
56
- const stretchStyle = isIconButton ? undefined : {
57
- flex: 1
58
- };
59
- return /*#__PURE__*/React.cloneElement(element, {
60
- modes: mergedModes,
61
- style: [stretchStyle, element.props.style]
62
- });
42
+ const cascadedChildren = cloneChildrenWithModes(flatChildren, modes);
43
+ const childrenWithModes = React.Children.map(cascadedChildren, child => {
44
+ if (! /*#__PURE__*/React.isValidElement(child)) {
45
+ return child;
63
46
  }
64
- return child;
47
+ const element = child;
48
+ const isIconButton = element.type === IconButton;
49
+ const stretchStyle = isIconButton ? undefined : {
50
+ flex: 1
51
+ };
52
+ return /*#__PURE__*/React.cloneElement(element, {
53
+ style: [stretchStyle, element.props.style]
54
+ });
65
55
  });
66
56
  return /*#__PURE__*/_jsx(View, {
67
57
  style: [containerStyle, style],
@@ -41,6 +41,8 @@ function CardCTA({
41
41
  onPressButton,
42
42
  ratingLabel = '+28 Rating',
43
43
  showRatingActions = true,
44
+ showButton = true,
45
+ ratingMediaAlign = 'center',
44
46
  onPressLike,
45
47
  onPressDislike,
46
48
  headline = 'Headline',
@@ -127,11 +129,14 @@ function CardCTA({
127
129
  AppearanceBrand: 'Secondary',
128
130
  'Button / Size': 'S'
129
131
  };
132
+ // Rating footer IconButtons are Neutral / S / Low per Figma. Apply those
133
+ // AFTER cascaded modes so card-level AppearanceBrand (often Secondary)
134
+ // cannot override the footer chrome.
130
135
  const iconButtonModes = {
136
+ ...modes,
131
137
  'Button / Size': 'S',
132
- 'Emphasis': 'Low',
133
- 'AppearanceBrand': 'Neutral',
134
- ...modes
138
+ Emphasis: 'Low',
139
+ AppearanceBrand: 'Neutral'
135
140
  };
136
141
  const effectiveButtonLabel = buttonLabel ?? (isRating ? 'Save' : 'Button');
137
142
  const nonWrappingButtonLabel = effectiveButtonLabel.replace(/\s/g, '\u00A0');
@@ -204,7 +209,13 @@ function CardCTA({
204
209
  borderWidth: borderSize,
205
210
  borderColor,
206
211
  flexDirection: isRating || isSip ? 'column' : 'row',
207
- overflow: 'visible'
212
+ overflow: 'visible',
213
+ // Pin footer to the bottom when a parent (e.g. equal-height Carousel)
214
+ // assigns an explicit height. Do not flexGrow — that unbounded-grows
215
+ // inside horizontal ScrollViews and blows cards to infinite height.
216
+ ...(isRating ? {
217
+ justifyContent: 'space-between'
218
+ } : {})
208
219
  };
209
220
 
210
221
  // NOTE: `minWidth: 0` + explicit `flexShrink: 1` are required on native.
@@ -353,16 +364,23 @@ function CardCTA({
353
364
  paddingHorizontal: ratingContentPaddingH,
354
365
  paddingVertical: ratingContentPaddingV,
355
366
  gap: ratingContentGap,
356
- alignItems: 'flex-start'
367
+ alignItems: 'flex-start',
368
+ alignSelf: 'stretch'
369
+ };
370
+ const ratingMediaStyle = {
371
+ alignSelf: 'stretch',
372
+ width: '100%',
373
+ alignItems: ratingMediaAlign === 'center' ? 'center' : 'flex-start'
357
374
  };
358
375
  const ratingFooterStyle = {
359
376
  flexDirection: 'row',
360
377
  alignItems: 'flex-start',
361
- justifyContent: 'space-between',
378
+ justifyContent: showButton ? 'space-between' : 'flex-start',
362
379
  paddingHorizontal: ratingFooterPaddingH,
363
380
  paddingTop: ratingFooterPaddingTop,
364
381
  paddingBottom: ratingFooterPaddingBottom,
365
- overflow: 'visible'
382
+ overflow: 'visible',
383
+ alignSelf: 'stretch'
366
384
  };
367
385
  const buttonLabelStyle = {
368
386
  flexGrow: 0,
@@ -446,9 +464,12 @@ function CardCTA({
446
464
  style: [containerStyle, style],
447
465
  children: [/*#__PURE__*/_jsxs(View, {
448
466
  style: ratingContentStyle,
449
- children: [ratingBadgeSlot ? cloneChildrenWithModes(ratingBadgeSlot, modes) : /*#__PURE__*/_jsx(Badge, {
450
- label: ratingLabel,
451
- modes: modes
467
+ children: [/*#__PURE__*/_jsx(View, {
468
+ style: ratingMediaStyle,
469
+ children: ratingBadgeSlot ? cloneChildrenWithModes(ratingBadgeSlot, modes) : /*#__PURE__*/_jsx(Badge, {
470
+ label: ratingLabel,
471
+ modes: modes
472
+ })
452
473
  }), /*#__PURE__*/_jsxs(View, {
453
474
  style: textWrapStyle,
454
475
  children: [/*#__PURE__*/_jsx(Text, {
@@ -461,7 +482,7 @@ function CardCTA({
461
482
  })]
462
483
  }), /*#__PURE__*/_jsxs(View, {
463
484
  style: ratingFooterStyle,
464
- children: [/*#__PURE__*/_jsx(View, {
485
+ children: [showButton ? /*#__PURE__*/_jsx(View, {
465
486
  style: ratingButtonWrapStyle,
466
487
  children: buttonSlot ? cloneChildrenWithModes(buttonSlot, buttonModes) : /*#__PURE__*/_jsx(Button, {
467
488
  label: effectiveButtonLabel,
@@ -470,17 +491,19 @@ function CardCTA({
470
491
  style: ratingButtonStyle,
471
492
  renderContent: renderButtonContent(ratingButtonLabelStyle)
472
493
  })
473
- }), showRatingActions ? ratingActionsSlot ? cloneChildrenWithModes(ratingActionsSlot, iconButtonModes) : /*#__PURE__*/_jsxs(ButtonGroup, {
494
+ }) : null, showRatingActions ? ratingActionsSlot ? cloneChildrenWithModes(ratingActionsSlot, iconButtonModes) : /*#__PURE__*/_jsxs(ButtonGroup, {
474
495
  modes: iconButtonModes,
475
496
  children: [/*#__PURE__*/_jsx(IconButton, {
476
497
  iconName: "ic_like",
477
498
  accessibilityLabel: "Like",
499
+ modes: iconButtonModes,
478
500
  ...(onPressLike ? {
479
501
  onPress: onPressLike
480
502
  } : {})
481
503
  }), /*#__PURE__*/_jsx(IconButton, {
482
504
  iconName: "ic_dislike",
483
505
  accessibilityLabel: "Dislike",
506
+ modes: iconButtonModes,
484
507
  ...(onPressDislike ? {
485
508
  onPress: onPressDislike
486
509
  } : {})
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import React, { createContext, useContext, useRef, useState, useEffect, useCallback, useMemo } from 'react';
4
- import { View, ScrollView, Animated, Pressable } from 'react-native';
4
+ import { View, ScrollView, Animated, Pressable, StyleSheet } from 'react-native';
5
5
  import { getVariableByName } from '../../design-tokens/figma-variables-resolver';
6
6
  import { EMPTY_MODES } from '../../utils/react-utils';
7
7
  import AutoplayControl from '../AutoplayControl/AutoplayControl';
@@ -37,8 +37,12 @@ export function Carousel({
37
37
  loop = true,
38
38
  gap: gapProp,
39
39
  itemWidth: itemWidthProp,
40
+ itemInset,
41
+ bleedHorizontal,
40
42
  paddingHorizontal: paddingHorizontalProp,
41
43
  paddingVertical: paddingVerticalProp,
44
+ equalHeight = true,
45
+ maxHeight: maxHeightProp,
42
46
  type = 'Default',
43
47
  onIndexChange,
44
48
  style
@@ -50,7 +54,7 @@ export function Carousel({
50
54
  const containerPaddingH = parseFloat(getVariableByName('carousel/padding/horizontal', modes));
51
55
  const containerPaddingV = parseFloat(getVariableByName('carousel/padding/vertical', modes));
52
56
  // Outer container max height per Figma (`carousel/maxHeight`).
53
- const maxHeight = parseFloat(getVariableByName('carousel/maxHeight', modes));
57
+ const tokenMaxHeight = parseFloat(getVariableByName('carousel/maxHeight', modes));
54
58
  // Gap between AutoplayControl and NumberPagination in the Numbered overlay.
55
59
  const controlGap = parseFloat(getVariableByName('carouselControl/gap', modes));
56
60
 
@@ -79,15 +83,47 @@ export function Carousel({
79
83
  const items = useMemo(() => React.Children.toArray(children).filter(React.isValidElement), [children]);
80
84
  const totalItems = items.length;
81
85
 
82
- // Effective item width: provided prop, or full container width minus peek offsets.
86
+ // Effective item width: explicit prop, itemInset derivation, or token peek.
83
87
  // For the Numbered variant the items are full-bleed (no peek padding).
84
88
  const effectiveItemWidth = useMemo(() => {
85
89
  if (itemWidthProp != null) return itemWidthProp;
86
90
  if (containerWidth === 0) return 0;
87
91
  if (isNumbered) return containerWidth;
92
+ if (itemInset != null) {
93
+ return Math.max(0, containerWidth - itemInset * 2);
94
+ }
88
95
  // Full-width minus peekOffset on each side
89
96
  return containerWidth - containerPaddingH * 4;
90
- }, [itemWidthProp, containerWidth, containerPaddingH, isNumbered]);
97
+ }, [itemWidthProp, itemInset, containerWidth, containerPaddingH, isNumbered]);
98
+
99
+ // Equal-height: measure each slide's intrinsic height, then lock every slot
100
+ // to the tallest. Do NOT use contentContainerStyle.alignItems:'stretch' or
101
+ // height:'100%' without a bounded cross-axis — in a horizontal ScrollView
102
+ // that resolves to an unbounded/infinite height.
103
+ const slideHeightsRef = useRef({});
104
+ const [equalizedHeight, setEqualizedHeight] = useState();
105
+ const equalizedHeightRef = useRef(undefined);
106
+ equalizedHeightRef.current = equalizedHeight;
107
+ useEffect(() => {
108
+ slideHeightsRef.current = {};
109
+ equalizedHeightRef.current = undefined;
110
+ setEqualizedHeight(undefined);
111
+ }, [totalItems, effectiveItemWidth, equalHeight]);
112
+ const handleSlideLayout = useCallback(index => event => {
113
+ if (!equalHeight) return;
114
+ // Only measure while unconstrained. After lock, the slot height is forced
115
+ // and onLayout would just echo equalizedHeight.
116
+ if (equalizedHeightRef.current != null) return;
117
+ const height = Math.ceil(event.nativeEvent.layout.height);
118
+ if (height <= 0) return;
119
+ const previous = slideHeightsRef.current[index] ?? 0;
120
+ if (height <= previous) return;
121
+ slideHeightsRef.current[index] = height;
122
+ const measured = items.map((_, i) => slideHeightsRef.current[i]);
123
+ if (measured.some(value => value == null)) return;
124
+ const next = Math.max(...measured);
125
+ setEqualizedHeight(next);
126
+ }, [equalHeight, items]);
91
127
 
92
128
  // Snap interval = item width + gap
93
129
  const snapInterval = effectiveItemWidth + gap;
@@ -221,14 +257,20 @@ export function Carousel({
221
257
  }, [isPlaying, startAutoPlay, clearAutoPlay]);
222
258
 
223
259
  // ---- Render ----
224
- // Explicit padding props win verbatim; otherwise fall back to the
225
- // token-derived values (horizontal keeps its legacy ×2 "peek" multiplier).
226
- // Numbered variant is full-bleed: zero padding.
227
- const effectivePaddingH = isNumbered ? 0 : paddingHorizontalProp ?? containerPaddingH;
260
+ // Padding priority: Numbered 0; itemInset inset; explicit padding →
261
+ // verbatim; else token (legacy ×2 peek is applied via item width, not here).
262
+ const effectivePaddingH = isNumbered ? 0 : itemInset ?? paddingHorizontalProp ?? containerPaddingH;
228
263
  const effectivePaddingV = isNumbered ? 0 : paddingVerticalProp ?? containerPaddingV;
264
+
265
+ // Equal-height rows hug content — don't clip with the token maxHeight unless
266
+ // the caller opts into a numeric max (or disables equalHeight for legacy strips).
267
+ const resolvedMaxHeight = isNumbered ? undefined : maxHeightProp === false ? undefined : typeof maxHeightProp === 'number' ? maxHeightProp : equalHeight ? undefined : tokenMaxHeight;
229
268
  const outerStyle = {
230
269
  paddingVertical: effectivePaddingV,
231
- maxHeight: isNumbered ? undefined : maxHeight,
270
+ maxHeight: resolvedMaxHeight,
271
+ ...(bleedHorizontal != null ? {
272
+ marginHorizontal: -Math.abs(bleedHorizontal)
273
+ } : {}),
232
274
  // Numbered needs relative positioning for the floating controls overlay.
233
275
  ...(isNumbered ? {
234
276
  overflow: 'hidden'
@@ -237,7 +279,8 @@ export function Carousel({
237
279
  const contentContainerStyle = {
238
280
  paddingHorizontal: effectivePaddingH,
239
281
  gap,
240
- // Align items to the start so snap works correctly
282
+ // Always flex-start on the cross axis. Stretch + unbounded ScrollView
283
+ // height is what caused infinite-tall slides.
241
284
  alignItems: 'flex-start'
242
285
  };
243
286
  return /*#__PURE__*/_jsx(CarouselContext.Provider, {
@@ -260,6 +303,8 @@ export function Carousel({
260
303
  onScrollEndDrag: handleScrollEndDrag,
261
304
  onMomentumScrollEnd: finishProgrammaticScroll,
262
305
  children: items.map((child, index) => {
306
+ const hasEqualizedHeight = equalHeight && equalizedHeight != null && equalizedHeight > 0;
307
+
263
308
  // Strict slot box: width must be honored; never grow or shrink with
264
309
  // content, and clip anything that misbehaves (e.g. a child whose
265
310
  // inner flex layout would otherwise leak into the next slot on
@@ -269,7 +314,10 @@ export function Carousel({
269
314
  flexGrow: 0,
270
315
  flexShrink: 0,
271
316
  flexBasis: effectiveItemWidth > 0 ? effectiveItemWidth : 'auto',
272
- overflow: 'hidden'
317
+ overflow: 'hidden',
318
+ ...(hasEqualizedHeight ? {
319
+ height: equalizedHeight
320
+ } : {})
273
321
  };
274
322
 
275
323
  // The cloned style forces the child's outer node to also honor the
@@ -279,7 +327,11 @@ export function Carousel({
279
327
  width: effectiveItemWidth > 0 ? effectiveItemWidth : undefined,
280
328
  maxWidth: effectiveItemWidth > 0 ? effectiveItemWidth : undefined,
281
329
  flexGrow: 0,
282
- flexShrink: 0
330
+ flexShrink: 0,
331
+ ...(hasEqualizedHeight ? {
332
+ height: '100%',
333
+ alignSelf: 'stretch'
334
+ } : {})
283
335
  };
284
336
 
285
337
  // Pass modes down to children
@@ -292,7 +344,11 @@ export function Carousel({
292
344
  }) : child;
293
345
  return /*#__PURE__*/_jsx(View, {
294
346
  style: slotStyle,
295
- children: childWithModes
347
+ children: /*#__PURE__*/_jsx(View, {
348
+ style: hasEqualizedHeight ? styles.equalizedFill : undefined,
349
+ onLayout: handleSlideLayout(index),
350
+ children: childWithModes
351
+ })
296
352
  }, index);
297
353
  })
298
354
  }), !isNumbered && showPagination && totalItems > 1 && /*#__PURE__*/_jsx(Pagination, {
@@ -441,6 +497,11 @@ function AnimatedDot({
441
497
  }
442
498
  });
443
499
  }
500
+ const styles = StyleSheet.create({
501
+ equalizedFill: {
502
+ flex: 1
503
+ }
504
+ });
444
505
 
445
506
  // ---------------------------------------------------------------------------
446
507
  // Attach sub-components
@@ -198,6 +198,7 @@ export const FIGMA_MODES = {
198
198
  "NavArrow Direction": ["Left&Right", "Top&Bottom"],
199
199
  "NoteInput / Output": ["Default"],
200
200
  "Nudge / Output": ["Default"],
201
+ "Nudge Border Radius ": ["Default", "Pill"],
201
202
  "Nudge padding": ["Default", "None"],
202
203
  "number pagination": ["Default"],
203
204
  "Numpad / Output": ["Default"],
@@ -322,19 +323,19 @@ export const FIGMA_COMPONENT_MODES = {
322
323
  "AvatarGroup": ["Avatar Size", "Badge Size", "Context4"],
323
324
  "Badge": ["AppearanceBrand", "AppearanceSystem", "Badge Size", "Color Mode", "Emphasis", "Semantic Intent"],
324
325
  "Balance": ["Color Mode", "Context3"],
325
- "BenefitCard": ["AppearanceBrand", "AppearanceSystem", "Avatar Size", "Badge Size", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Context4", "Emphasis", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap", "Text Appearance", "Text Sizes", "Weight"],
326
+ "BenefitCard": ["AppearanceBrand", "AppearanceSystem", "Avatar Size", "Badge Size", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Context4", "Emphasis", "Nudge Border Radius ", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap", "Text Appearance", "Text Sizes", "Weight"],
326
327
  "BottomNav": ["Color Mode"],
327
328
  "BottomNavItem": ["BottomNavItem / State", "Color Mode"],
328
329
  "BrandChip": ["Avatar Size", "Badge Size", "Color Mode", "context 10", "Context4", "Profile Card Appearance"],
329
330
  "BubbleChart": ["Appearance / DataViz", "Color Mode", "Context", "context 10", "Emphasis / DataViz", "Profile Card Appearance", "Text Appearance"],
330
331
  "Button": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent"],
331
332
  "Card": ["AppearanceBrand", "AppearanceSystem", "Card Container", "Color Mode", "context 8", "Gap", "Page type", "Semantic Intent"],
332
- "CardAdvisory": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "circularProgressBar Size", "Color Mode", "Context", "context 10", "Emphasis", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap"],
333
+ "CardAdvisory": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "circularProgressBar Size", "Color Mode", "Context", "context 10", "Emphasis", "Nudge Border Radius ", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap"],
333
334
  "CardBankAccount": ["AppearanceBrand", "AppearanceSystem", "Avatar Size", "Badge Size", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Context4", "context5", "Emphasis", "List Item Style", "Page type", "Profile Card Appearance", "Semantic Intent", "Text Appearance", "Text Sizes", "Weight"],
334
335
  "CardCTA": ["AppearanceBrand", "AppearanceSystem", "Avatar Size", "Badge Size", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "context 8", "context 9", "Context4", "Emphasis", "Icon Capsule Size", "MediaBlock", "Page type", "Profile Card Appearance", "Semantic Intent"],
335
336
  "CardFeedback": ["AppearanceBrand", "AppearanceSystem", "Color Mode"],
336
- "CardFinancialCondition": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "circularProgressBar Size", "Color Mode", "Context", "context 10", "Emphasis", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap"],
337
- "CardInsight": ["Appearance / DataViz", "AppearanceBrand", "AppearanceSystem", "Badge Size", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "context 8", "Emphasis", "Emphasis / DataViz", "LinearProgress Size", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap", "Text Appearance"],
337
+ "CardFinancialCondition": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "circularProgressBar Size", "Color Mode", "Context", "context 10", "Emphasis", "Nudge Border Radius ", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap"],
338
+ "CardInsight": ["Appearance / DataViz", "AppearanceBrand", "AppearanceSystem", "Badge Size", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "context 8", "Emphasis", "Emphasis / DataViz", "LinearProgress Size", "Nudge Border Radius ", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap", "Text Appearance"],
338
339
  "CardProviderInfo": ["AppearanceBrand", "Avatar Size", "Badge Size", "Color Mode", "context 10", "Context4", "Profile Card Appearance"],
339
340
  "Carousel": ["peekOffset"],
340
341
  "CarouselCardAccounts": ["peekOffset"],
@@ -345,7 +346,7 @@ export const FIGMA_COMPONENT_MODES = {
345
346
  "CheckboxItem": ["Color Mode", "Context", "Slot gap"],
346
347
  "ChipSelect": ["ChipSelect State", "Color Mode"],
347
348
  "CircularProgressBar": ["AppearanceBrand", "AppearanceSystem", "circularProgressBar Size", "Color Mode", "Emphasis", "Semantic Intent"],
348
- "CircularRating": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Emphasis", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap"],
349
+ "CircularRating": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Emphasis", "Nudge Border Radius ", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap"],
349
350
  "ClusterBubble": ["Appearance / DataViz", "Color Mode", "Context", "context 10", "Emphasis / DataViz", "Profile Card Appearance", "Text Appearance"],
350
351
  "CompareTable": ["Accordion States", "AppearanceBrand", "Button / Size", "Button / State", "Color Mode", "Emphasis", "Page type", "Radius"],
351
352
  "ComparisonBar": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Emphasis", "Icon Capsule Size", "Page type", "Profile Card Appearance", "Radius", "Semantic Intent"],
@@ -373,7 +374,7 @@ export const FIGMA_COMPONENT_MODES = {
373
374
  "HeroSection": ["AppearanceBrand", "Button / Size", "Button / State", "Color Mode", "context 9", "context7", "Emphasis", "FormField States", "InputState", "Page type", "Status"],
374
375
  "HoldingsCard": ["AppearanceBrand", "Color Mode"],
375
376
  "HStack": ["Context", "Padding", "Page type", "Slot gap", "Stack Context"],
376
- "Icon": ["AppearanceBrand", "AppearanceSystem", "Badge Size", "Color Mode", "context 10", "Context4", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent"],
377
+ "Icon": ["AppearanceBrand", "Badge Size", "Color Mode", "context 10", "Context4", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent"],
377
378
  "IconButton": ["AppearanceBrand", "Button / Size", "Button / State", "Color Mode", "Emphasis", "Page type"],
378
379
  "IconCapsule": ["AppearanceBrand", "AppearanceSystem", "Color Mode", "Context", "Emphasis", "Icon Capsule Size", "Page type", "Semantic Intent"],
379
380
  "InputSearch": ["Color Mode", "FormField States", "InputState", "Status"],
@@ -388,12 +389,12 @@ export const FIGMA_COMPONENT_MODES = {
388
389
  "MediaCard": ["Contrast Context"],
389
390
  "MerchantProfile": ["Avatar Size", "Badge Size", "Color Mode", "context 10", "Context4", "Profile Card Appearance"],
390
391
  "MessageField": ["Color Mode", "FormField States"],
391
- "MetricData": ["AppearanceBrand", "AppearanceSystem", "Badge Size", "Color Mode", "context 10", "Context4", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent"],
392
+ "MetricData": ["AppearanceBrand", "Badge Size", "Color Mode", "context 10", "Context4", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent"],
392
393
  "MetricLegendItem": ["Appearance / DataViz", "Color Mode", "Emphasis / DataViz"],
393
394
  "MoneyValue": ["Color Mode", "Context3"],
394
395
  "MonthlyStatusGrid": ["Appearance / DataViz", "Calendar Glyph State", "Color Mode", "Emphasis / DataViz"],
395
396
  "NavArrow": ["Color Mode", "context 10", "Context2", "context5", "List Item Style", "NavArrow Direction", "Page type", "Profile Card Appearance"],
396
- "Nudge": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Emphasis", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap"],
397
+ "Nudge": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Emphasis", "Nudge Border Radius ", "Nudge padding", "Page type", "Profile Card Appearance", "Semantic Intent", "Slot gap"],
397
398
  "OTP": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Emphasis", "FormField States", "Input/PINSlot States", "Page type", "Profile Card Appearance", "Semantic Intent", "Status"],
398
399
  "PageHero": ["AppearanceBrand", "AppearanceSystem", "Button / Size", "Button / State", "Button Glass State", "Button type", "Color Mode", "Context", "context 10", "Emphasis", "Page type", "PageHero Size", "Profile Card Appearance", "Semantic Intent", "Video / Output"],
399
400
  "PaymentFeedback": ["AppearanceBrand", "AppearanceSystem", "Color Mode", "Context", "Emphasis", "Icon Capsule Size", "Page type", "Semantic Intent"],
@@ -439,7 +440,7 @@ export const FIGMA_COMPONENT_MODES = {
439
440
  "TransactionBubble": ["Color Mode", "context 10", "Context2", "Context3", "context5", "List Item Style", "NavArrow Direction", "Page type", "Profile Card Appearance", "Transaction Status"],
440
441
  "TransactionStatus": ["Transaction Status"],
441
442
  "UpiHandle": ["Color Mode", "context 10", "Profile Card Appearance", "UPI Handle Image"],
442
- "ValueBackMetric": ["AppearanceBrand", "AppearanceSystem", "Badge Size", "Color Mode", "Context", "context 10", "Context4", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent", "Text Appearance", "Text Sizes", "Weight"],
443
+ "ValueBackMetric": ["AppearanceBrand", "Badge Size", "Color Mode", "Context", "context 10", "Context4", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent", "Text Appearance", "Text Sizes", "Weight"],
443
444
  "VStack": ["Context", "Padding", "Page type", "Slot gap", "Stack Context"]
444
445
  };
445
446