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.
- package/CHANGELOG.md +10 -0
- package/lib/commonjs/components/ButtonGroup/ButtonGroup.js +16 -26
- package/lib/commonjs/components/CardCTA/CardCTA.js +35 -12
- package/lib/commonjs/components/Carousel/Carousel.js +73 -12
- package/lib/commonjs/design-tokens/figma-modes.generated.js +10 -9
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/commonjs/utils/react-utils.js +4 -1
- package/lib/module/components/ButtonGroup/ButtonGroup.js +17 -27
- package/lib/module/components/CardCTA/CardCTA.js +35 -12
- package/lib/module/components/Carousel/Carousel.js +74 -13
- package/lib/module/design-tokens/figma-modes.generated.js +10 -9
- package/lib/module/icons/registry.js +1 -1
- package/lib/module/utils/react-utils.js +4 -1
- package/lib/typescript/src/components/ButtonGroup/ButtonGroup.d.ts +5 -5
- package/lib/typescript/src/components/CardCTA/CardCTA.d.ts +14 -1
- package/lib/typescript/src/components/Carousel/Carousel.d.ts +30 -2
- package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +1 -0
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/ButtonGroup/ButtonGroup.tsx +22 -24
- package/src/components/CardCTA/CardCTA.tsx +65 -20
- package/src/components/Carousel/Carousel.tsx +125 -11
- package/src/design-tokens/figma-modes.generated.ts +10 -9
- package/src/icons/registry.ts +1 -1
- package/src/utils/react-utils.ts +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to this project are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
6
|
|
|
7
|
+
## [0.1.57] - 2026-07-27
|
|
8
|
+
|
|
9
|
+
- `Carousel` — fix infinite-tall slides: equal-height no longer uses unbounded `alignItems:'stretch'` / `height:'100%'` in a horizontal ScrollView; it measures intrinsic slide heights then locks slots to the tallest.
|
|
10
|
+
- `CardCTA` (rating) — pin the footer when given an explicit height without `flexGrow` (which also caused infinite height in horizontal carousels).
|
|
11
|
+
|
|
12
|
+
## [0.1.56] - 2026-07-27
|
|
13
|
+
|
|
14
|
+
- `Carousel` — `equalHeight` defaults to `true` (hug tallest slide; no token `maxHeight` clip). New `itemInset`, `bleedHorizontal`, and `maxHeight` (`number | false`) props for edge-aligned cards without consumer math. Opt out with `equalHeight={false}` to keep the legacy clipped strip. Storybook docs refreshed for the new API.
|
|
15
|
+
- `CardCTA` (rating) — media/badge slot centers by default (`ratingMediaAlign`); `showButton={false}` for actions-only start-aligned footers; rating footer IconButtons keep Neutral / S / Low even when the card is Secondary; rating cards stretch and pin the footer in equal-height carousels.
|
|
16
|
+
|
|
7
17
|
## [0.1.55] - 2026-07-27
|
|
8
18
|
|
|
9
19
|
- D2C playbooks (`.cursor/commands/D2C.md`, `.cursor/D2C-FLOW.md`, `.cursor/D2C-SCREEN.md`) — on unresolved mode pairs, notify the user then continue with resolved modes (no longer stop execution).
|
|
@@ -15,14 +15,14 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
15
15
|
* ButtonGroup component that aggregates multiple buttons (e.g., IconButton)
|
|
16
16
|
* and handles their layout and styling/theming via design tokens.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* Non-IconButton children (e.g
|
|
20
|
-
* available space
|
|
18
|
+
* Group `modes` cascade to every child (and nested slot children). A child's
|
|
19
|
+
* own `modes` still win on conflict. Non-IconButton children (e.g. Button) are
|
|
20
|
+
* stretched to fill available space; IconButton children keep intrinsic width.
|
|
21
21
|
*
|
|
22
22
|
* @component
|
|
23
23
|
* @example
|
|
24
24
|
* ```jsx
|
|
25
|
-
* <ButtonGroup modes={{"Color Mode": "Light"}}>
|
|
25
|
+
* <ButtonGroup modes={{"Color Mode": "Light", AppearanceBrand: "Neutral"}}>
|
|
26
26
|
* <IconButton iconName="ic_qr_code" />
|
|
27
27
|
* <Button label="Pay" />
|
|
28
28
|
* </ButtonGroup>
|
|
@@ -33,12 +33,9 @@ function ButtonGroup({
|
|
|
33
33
|
modes = _reactUtils.EMPTY_MODES,
|
|
34
34
|
style
|
|
35
35
|
}) {
|
|
36
|
-
// Resolve design tokens
|
|
37
36
|
const gap = (0, _figmaVariablesResolver.getVariableByName)('buttonGroup/gap', modes) ?? 12;
|
|
38
37
|
const paddingHorizontal = (0, _figmaVariablesResolver.getVariableByName)('buttonGroup/padding/horizontal', modes) ?? 0;
|
|
39
38
|
const paddingVertical = (0, _figmaVariablesResolver.getVariableByName)('buttonGroup/padding/vertical', modes) ?? 0;
|
|
40
|
-
|
|
41
|
-
// Container style
|
|
42
39
|
const containerStyle = {
|
|
43
40
|
flexDirection: 'row',
|
|
44
41
|
alignItems: 'center',
|
|
@@ -46,27 +43,20 @@ function ButtonGroup({
|
|
|
46
43
|
paddingHorizontal: paddingHorizontal,
|
|
47
44
|
paddingVertical: paddingVertical
|
|
48
45
|
};
|
|
49
|
-
|
|
50
|
-
// Flatten children to handle Fragments properly
|
|
51
46
|
const flatChildren = (0, _reactUtils.flattenChildren)(children);
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const mergedModes = {
|
|
57
|
-
...modes,
|
|
58
|
-
...childModes
|
|
59
|
-
};
|
|
60
|
-
const isIconButton = element.type === _IconButton.default;
|
|
61
|
-
const stretchStyle = isIconButton ? undefined : {
|
|
62
|
-
flex: 1
|
|
63
|
-
};
|
|
64
|
-
return /*#__PURE__*/_react.default.cloneElement(element, {
|
|
65
|
-
modes: mergedModes,
|
|
66
|
-
style: [stretchStyle, element.props.style]
|
|
67
|
-
});
|
|
47
|
+
const cascadedChildren = (0, _reactUtils.cloneChildrenWithModes)(flatChildren, modes);
|
|
48
|
+
const childrenWithModes = _react.default.Children.map(cascadedChildren, child => {
|
|
49
|
+
if (! /*#__PURE__*/_react.default.isValidElement(child)) {
|
|
50
|
+
return child;
|
|
68
51
|
}
|
|
69
|
-
|
|
52
|
+
const element = child;
|
|
53
|
+
const isIconButton = element.type === _IconButton.default;
|
|
54
|
+
const stretchStyle = isIconButton ? undefined : {
|
|
55
|
+
flex: 1
|
|
56
|
+
};
|
|
57
|
+
return /*#__PURE__*/_react.default.cloneElement(element, {
|
|
58
|
+
style: [stretchStyle, element.props.style]
|
|
59
|
+
});
|
|
70
60
|
});
|
|
71
61
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
72
62
|
style: [containerStyle, style],
|
|
@@ -46,6 +46,8 @@ function CardCTA({
|
|
|
46
46
|
onPressButton,
|
|
47
47
|
ratingLabel = '+28 Rating',
|
|
48
48
|
showRatingActions = true,
|
|
49
|
+
showButton = true,
|
|
50
|
+
ratingMediaAlign = 'center',
|
|
49
51
|
onPressLike,
|
|
50
52
|
onPressDislike,
|
|
51
53
|
headline = 'Headline',
|
|
@@ -132,11 +134,14 @@ function CardCTA({
|
|
|
132
134
|
AppearanceBrand: 'Secondary',
|
|
133
135
|
'Button / Size': 'S'
|
|
134
136
|
};
|
|
137
|
+
// Rating footer IconButtons are Neutral / S / Low per Figma. Apply those
|
|
138
|
+
// AFTER cascaded modes so card-level AppearanceBrand (often Secondary)
|
|
139
|
+
// cannot override the footer chrome.
|
|
135
140
|
const iconButtonModes = {
|
|
141
|
+
...modes,
|
|
136
142
|
'Button / Size': 'S',
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
...modes
|
|
143
|
+
Emphasis: 'Low',
|
|
144
|
+
AppearanceBrand: 'Neutral'
|
|
140
145
|
};
|
|
141
146
|
const effectiveButtonLabel = buttonLabel ?? (isRating ? 'Save' : 'Button');
|
|
142
147
|
const nonWrappingButtonLabel = effectiveButtonLabel.replace(/\s/g, '\u00A0');
|
|
@@ -209,7 +214,13 @@ function CardCTA({
|
|
|
209
214
|
borderWidth: borderSize,
|
|
210
215
|
borderColor,
|
|
211
216
|
flexDirection: isRating || isSip ? 'column' : 'row',
|
|
212
|
-
overflow: 'visible'
|
|
217
|
+
overflow: 'visible',
|
|
218
|
+
// Pin footer to the bottom when a parent (e.g. equal-height Carousel)
|
|
219
|
+
// assigns an explicit height. Do not flexGrow — that unbounded-grows
|
|
220
|
+
// inside horizontal ScrollViews and blows cards to infinite height.
|
|
221
|
+
...(isRating ? {
|
|
222
|
+
justifyContent: 'space-between'
|
|
223
|
+
} : {})
|
|
213
224
|
};
|
|
214
225
|
|
|
215
226
|
// NOTE: `minWidth: 0` + explicit `flexShrink: 1` are required on native.
|
|
@@ -358,16 +369,23 @@ function CardCTA({
|
|
|
358
369
|
paddingHorizontal: ratingContentPaddingH,
|
|
359
370
|
paddingVertical: ratingContentPaddingV,
|
|
360
371
|
gap: ratingContentGap,
|
|
361
|
-
alignItems: 'flex-start'
|
|
372
|
+
alignItems: 'flex-start',
|
|
373
|
+
alignSelf: 'stretch'
|
|
374
|
+
};
|
|
375
|
+
const ratingMediaStyle = {
|
|
376
|
+
alignSelf: 'stretch',
|
|
377
|
+
width: '100%',
|
|
378
|
+
alignItems: ratingMediaAlign === 'center' ? 'center' : 'flex-start'
|
|
362
379
|
};
|
|
363
380
|
const ratingFooterStyle = {
|
|
364
381
|
flexDirection: 'row',
|
|
365
382
|
alignItems: 'flex-start',
|
|
366
|
-
justifyContent: 'space-between',
|
|
383
|
+
justifyContent: showButton ? 'space-between' : 'flex-start',
|
|
367
384
|
paddingHorizontal: ratingFooterPaddingH,
|
|
368
385
|
paddingTop: ratingFooterPaddingTop,
|
|
369
386
|
paddingBottom: ratingFooterPaddingBottom,
|
|
370
|
-
overflow: 'visible'
|
|
387
|
+
overflow: 'visible',
|
|
388
|
+
alignSelf: 'stretch'
|
|
371
389
|
};
|
|
372
390
|
const buttonLabelStyle = {
|
|
373
391
|
flexGrow: 0,
|
|
@@ -451,9 +469,12 @@ function CardCTA({
|
|
|
451
469
|
style: [containerStyle, style],
|
|
452
470
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
453
471
|
style: ratingContentStyle,
|
|
454
|
-
children: [
|
|
455
|
-
|
|
456
|
-
modes:
|
|
472
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
473
|
+
style: ratingMediaStyle,
|
|
474
|
+
children: ratingBadgeSlot ? (0, _reactUtils.cloneChildrenWithModes)(ratingBadgeSlot, modes) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Badge.default, {
|
|
475
|
+
label: ratingLabel,
|
|
476
|
+
modes: modes
|
|
477
|
+
})
|
|
457
478
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
458
479
|
style: textWrapStyle,
|
|
459
480
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
@@ -466,7 +487,7 @@ function CardCTA({
|
|
|
466
487
|
})]
|
|
467
488
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
468
489
|
style: ratingFooterStyle,
|
|
469
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
490
|
+
children: [showButton ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
470
491
|
style: ratingButtonWrapStyle,
|
|
471
492
|
children: buttonSlot ? (0, _reactUtils.cloneChildrenWithModes)(buttonSlot, buttonModes) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
|
|
472
493
|
label: effectiveButtonLabel,
|
|
@@ -475,17 +496,19 @@ function CardCTA({
|
|
|
475
496
|
style: ratingButtonStyle,
|
|
476
497
|
renderContent: renderButtonContent(ratingButtonLabelStyle)
|
|
477
498
|
})
|
|
478
|
-
}), showRatingActions ? ratingActionsSlot ? (0, _reactUtils.cloneChildrenWithModes)(ratingActionsSlot, iconButtonModes) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ButtonGroup.default, {
|
|
499
|
+
}) : null, showRatingActions ? ratingActionsSlot ? (0, _reactUtils.cloneChildrenWithModes)(ratingActionsSlot, iconButtonModes) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ButtonGroup.default, {
|
|
479
500
|
modes: iconButtonModes,
|
|
480
501
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
|
|
481
502
|
iconName: "ic_like",
|
|
482
503
|
accessibilityLabel: "Like",
|
|
504
|
+
modes: iconButtonModes,
|
|
483
505
|
...(onPressLike ? {
|
|
484
506
|
onPress: onPressLike
|
|
485
507
|
} : {})
|
|
486
508
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
|
|
487
509
|
iconName: "ic_dislike",
|
|
488
510
|
accessibilityLabel: "Dislike",
|
|
511
|
+
modes: iconButtonModes,
|
|
489
512
|
...(onPressDislike ? {
|
|
490
513
|
onPress: onPressDislike
|
|
491
514
|
} : {})
|
|
@@ -46,8 +46,12 @@ function Carousel({
|
|
|
46
46
|
loop = true,
|
|
47
47
|
gap: gapProp,
|
|
48
48
|
itemWidth: itemWidthProp,
|
|
49
|
+
itemInset,
|
|
50
|
+
bleedHorizontal,
|
|
49
51
|
paddingHorizontal: paddingHorizontalProp,
|
|
50
52
|
paddingVertical: paddingVerticalProp,
|
|
53
|
+
equalHeight = true,
|
|
54
|
+
maxHeight: maxHeightProp,
|
|
51
55
|
type = 'Default',
|
|
52
56
|
onIndexChange,
|
|
53
57
|
style
|
|
@@ -59,7 +63,7 @@ function Carousel({
|
|
|
59
63
|
const containerPaddingH = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/padding/horizontal', modes));
|
|
60
64
|
const containerPaddingV = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/padding/vertical', modes));
|
|
61
65
|
// Outer container max height per Figma (`carousel/maxHeight`).
|
|
62
|
-
const
|
|
66
|
+
const tokenMaxHeight = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carousel/maxHeight', modes));
|
|
63
67
|
// Gap between AutoplayControl and NumberPagination in the Numbered overlay.
|
|
64
68
|
const controlGap = parseFloat((0, _figmaVariablesResolver.getVariableByName)('carouselControl/gap', modes));
|
|
65
69
|
|
|
@@ -88,15 +92,47 @@ function Carousel({
|
|
|
88
92
|
const items = (0, _react.useMemo)(() => _react.default.Children.toArray(children).filter(_react.default.isValidElement), [children]);
|
|
89
93
|
const totalItems = items.length;
|
|
90
94
|
|
|
91
|
-
// Effective item width:
|
|
95
|
+
// Effective item width: explicit prop, itemInset derivation, or token peek.
|
|
92
96
|
// For the Numbered variant the items are full-bleed (no peek padding).
|
|
93
97
|
const effectiveItemWidth = (0, _react.useMemo)(() => {
|
|
94
98
|
if (itemWidthProp != null) return itemWidthProp;
|
|
95
99
|
if (containerWidth === 0) return 0;
|
|
96
100
|
if (isNumbered) return containerWidth;
|
|
101
|
+
if (itemInset != null) {
|
|
102
|
+
return Math.max(0, containerWidth - itemInset * 2);
|
|
103
|
+
}
|
|
97
104
|
// Full-width minus peekOffset on each side
|
|
98
105
|
return containerWidth - containerPaddingH * 4;
|
|
99
|
-
}, [itemWidthProp, containerWidth, containerPaddingH, isNumbered]);
|
|
106
|
+
}, [itemWidthProp, itemInset, containerWidth, containerPaddingH, isNumbered]);
|
|
107
|
+
|
|
108
|
+
// Equal-height: measure each slide's intrinsic height, then lock every slot
|
|
109
|
+
// to the tallest. Do NOT use contentContainerStyle.alignItems:'stretch' or
|
|
110
|
+
// height:'100%' without a bounded cross-axis — in a horizontal ScrollView
|
|
111
|
+
// that resolves to an unbounded/infinite height.
|
|
112
|
+
const slideHeightsRef = (0, _react.useRef)({});
|
|
113
|
+
const [equalizedHeight, setEqualizedHeight] = (0, _react.useState)();
|
|
114
|
+
const equalizedHeightRef = (0, _react.useRef)(undefined);
|
|
115
|
+
equalizedHeightRef.current = equalizedHeight;
|
|
116
|
+
(0, _react.useEffect)(() => {
|
|
117
|
+
slideHeightsRef.current = {};
|
|
118
|
+
equalizedHeightRef.current = undefined;
|
|
119
|
+
setEqualizedHeight(undefined);
|
|
120
|
+
}, [totalItems, effectiveItemWidth, equalHeight]);
|
|
121
|
+
const handleSlideLayout = (0, _react.useCallback)(index => event => {
|
|
122
|
+
if (!equalHeight) return;
|
|
123
|
+
// Only measure while unconstrained. After lock, the slot height is forced
|
|
124
|
+
// and onLayout would just echo equalizedHeight.
|
|
125
|
+
if (equalizedHeightRef.current != null) return;
|
|
126
|
+
const height = Math.ceil(event.nativeEvent.layout.height);
|
|
127
|
+
if (height <= 0) return;
|
|
128
|
+
const previous = slideHeightsRef.current[index] ?? 0;
|
|
129
|
+
if (height <= previous) return;
|
|
130
|
+
slideHeightsRef.current[index] = height;
|
|
131
|
+
const measured = items.map((_, i) => slideHeightsRef.current[i]);
|
|
132
|
+
if (measured.some(value => value == null)) return;
|
|
133
|
+
const next = Math.max(...measured);
|
|
134
|
+
setEqualizedHeight(next);
|
|
135
|
+
}, [equalHeight, items]);
|
|
100
136
|
|
|
101
137
|
// Snap interval = item width + gap
|
|
102
138
|
const snapInterval = effectiveItemWidth + gap;
|
|
@@ -230,14 +266,20 @@ function Carousel({
|
|
|
230
266
|
}, [isPlaying, startAutoPlay, clearAutoPlay]);
|
|
231
267
|
|
|
232
268
|
// ---- Render ----
|
|
233
|
-
//
|
|
234
|
-
// token
|
|
235
|
-
|
|
236
|
-
const effectivePaddingH = isNumbered ? 0 : paddingHorizontalProp ?? containerPaddingH;
|
|
269
|
+
// Padding priority: Numbered → 0; itemInset → inset; explicit padding →
|
|
270
|
+
// verbatim; else token (legacy ×2 peek is applied via item width, not here).
|
|
271
|
+
const effectivePaddingH = isNumbered ? 0 : itemInset ?? paddingHorizontalProp ?? containerPaddingH;
|
|
237
272
|
const effectivePaddingV = isNumbered ? 0 : paddingVerticalProp ?? containerPaddingV;
|
|
273
|
+
|
|
274
|
+
// Equal-height rows hug content — don't clip with the token maxHeight unless
|
|
275
|
+
// the caller opts into a numeric max (or disables equalHeight for legacy strips).
|
|
276
|
+
const resolvedMaxHeight = isNumbered ? undefined : maxHeightProp === false ? undefined : typeof maxHeightProp === 'number' ? maxHeightProp : equalHeight ? undefined : tokenMaxHeight;
|
|
238
277
|
const outerStyle = {
|
|
239
278
|
paddingVertical: effectivePaddingV,
|
|
240
|
-
maxHeight:
|
|
279
|
+
maxHeight: resolvedMaxHeight,
|
|
280
|
+
...(bleedHorizontal != null ? {
|
|
281
|
+
marginHorizontal: -Math.abs(bleedHorizontal)
|
|
282
|
+
} : {}),
|
|
241
283
|
// Numbered needs relative positioning for the floating controls overlay.
|
|
242
284
|
...(isNumbered ? {
|
|
243
285
|
overflow: 'hidden'
|
|
@@ -246,7 +288,8 @@ function Carousel({
|
|
|
246
288
|
const contentContainerStyle = {
|
|
247
289
|
paddingHorizontal: effectivePaddingH,
|
|
248
290
|
gap,
|
|
249
|
-
//
|
|
291
|
+
// Always flex-start on the cross axis. Stretch + unbounded ScrollView
|
|
292
|
+
// height is what caused infinite-tall slides.
|
|
250
293
|
alignItems: 'flex-start'
|
|
251
294
|
};
|
|
252
295
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(CarouselContext.Provider, {
|
|
@@ -269,6 +312,8 @@ function Carousel({
|
|
|
269
312
|
onScrollEndDrag: handleScrollEndDrag,
|
|
270
313
|
onMomentumScrollEnd: finishProgrammaticScroll,
|
|
271
314
|
children: items.map((child, index) => {
|
|
315
|
+
const hasEqualizedHeight = equalHeight && equalizedHeight != null && equalizedHeight > 0;
|
|
316
|
+
|
|
272
317
|
// Strict slot box: width must be honored; never grow or shrink with
|
|
273
318
|
// content, and clip anything that misbehaves (e.g. a child whose
|
|
274
319
|
// inner flex layout would otherwise leak into the next slot on
|
|
@@ -278,7 +323,10 @@ function Carousel({
|
|
|
278
323
|
flexGrow: 0,
|
|
279
324
|
flexShrink: 0,
|
|
280
325
|
flexBasis: effectiveItemWidth > 0 ? effectiveItemWidth : 'auto',
|
|
281
|
-
overflow: 'hidden'
|
|
326
|
+
overflow: 'hidden',
|
|
327
|
+
...(hasEqualizedHeight ? {
|
|
328
|
+
height: equalizedHeight
|
|
329
|
+
} : {})
|
|
282
330
|
};
|
|
283
331
|
|
|
284
332
|
// The cloned style forces the child's outer node to also honor the
|
|
@@ -288,7 +336,11 @@ function Carousel({
|
|
|
288
336
|
width: effectiveItemWidth > 0 ? effectiveItemWidth : undefined,
|
|
289
337
|
maxWidth: effectiveItemWidth > 0 ? effectiveItemWidth : undefined,
|
|
290
338
|
flexGrow: 0,
|
|
291
|
-
flexShrink: 0
|
|
339
|
+
flexShrink: 0,
|
|
340
|
+
...(hasEqualizedHeight ? {
|
|
341
|
+
height: '100%',
|
|
342
|
+
alignSelf: 'stretch'
|
|
343
|
+
} : {})
|
|
292
344
|
};
|
|
293
345
|
|
|
294
346
|
// Pass modes down to children
|
|
@@ -301,7 +353,11 @@ function Carousel({
|
|
|
301
353
|
}) : child;
|
|
302
354
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
303
355
|
style: slotStyle,
|
|
304
|
-
children:
|
|
356
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
357
|
+
style: hasEqualizedHeight ? styles.equalizedFill : undefined,
|
|
358
|
+
onLayout: handleSlideLayout(index),
|
|
359
|
+
children: childWithModes
|
|
360
|
+
})
|
|
305
361
|
}, index);
|
|
306
362
|
})
|
|
307
363
|
}), !isNumbered && showPagination && totalItems > 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(Pagination, {
|
|
@@ -450,6 +506,11 @@ function AnimatedDot({
|
|
|
450
506
|
}
|
|
451
507
|
});
|
|
452
508
|
}
|
|
509
|
+
const styles = _reactNative.StyleSheet.create({
|
|
510
|
+
equalizedFill: {
|
|
511
|
+
flex: 1
|
|
512
|
+
}
|
|
513
|
+
});
|
|
453
514
|
|
|
454
515
|
// ---------------------------------------------------------------------------
|
|
455
516
|
// Attach sub-components
|
|
@@ -202,6 +202,7 @@ const FIGMA_MODES = exports.FIGMA_MODES = {
|
|
|
202
202
|
"NavArrow Direction": ["Left&Right", "Top&Bottom"],
|
|
203
203
|
"NoteInput / Output": ["Default"],
|
|
204
204
|
"Nudge / Output": ["Default"],
|
|
205
|
+
"Nudge Border Radius ": ["Default", "Pill"],
|
|
205
206
|
"Nudge padding": ["Default", "None"],
|
|
206
207
|
"number pagination": ["Default"],
|
|
207
208
|
"Numpad / Output": ["Default"],
|
|
@@ -326,19 +327,19 @@ const FIGMA_COMPONENT_MODES = exports.FIGMA_COMPONENT_MODES = {
|
|
|
326
327
|
"AvatarGroup": ["Avatar Size", "Badge Size", "Context4"],
|
|
327
328
|
"Badge": ["AppearanceBrand", "AppearanceSystem", "Badge Size", "Color Mode", "Emphasis", "Semantic Intent"],
|
|
328
329
|
"Balance": ["Color Mode", "Context3"],
|
|
329
|
-
"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"],
|
|
330
|
+
"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"],
|
|
330
331
|
"BottomNav": ["Color Mode"],
|
|
331
332
|
"BottomNavItem": ["BottomNavItem / State", "Color Mode"],
|
|
332
333
|
"BrandChip": ["Avatar Size", "Badge Size", "Color Mode", "context 10", "Context4", "Profile Card Appearance"],
|
|
333
334
|
"BubbleChart": ["Appearance / DataViz", "Color Mode", "Context", "context 10", "Emphasis / DataViz", "Profile Card Appearance", "Text Appearance"],
|
|
334
335
|
"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"],
|
|
335
336
|
"Card": ["AppearanceBrand", "AppearanceSystem", "Card Container", "Color Mode", "context 8", "Gap", "Page type", "Semantic Intent"],
|
|
336
|
-
"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"],
|
|
337
|
+
"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"],
|
|
337
338
|
"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"],
|
|
338
339
|
"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"],
|
|
339
340
|
"CardFeedback": ["AppearanceBrand", "AppearanceSystem", "Color Mode"],
|
|
340
|
-
"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"],
|
|
341
|
-
"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"],
|
|
341
|
+
"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"],
|
|
342
|
+
"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"],
|
|
342
343
|
"CardProviderInfo": ["AppearanceBrand", "Avatar Size", "Badge Size", "Color Mode", "context 10", "Context4", "Profile Card Appearance"],
|
|
343
344
|
"Carousel": ["peekOffset"],
|
|
344
345
|
"CarouselCardAccounts": ["peekOffset"],
|
|
@@ -349,7 +350,7 @@ const FIGMA_COMPONENT_MODES = exports.FIGMA_COMPONENT_MODES = {
|
|
|
349
350
|
"CheckboxItem": ["Color Mode", "Context", "Slot gap"],
|
|
350
351
|
"ChipSelect": ["ChipSelect State", "Color Mode"],
|
|
351
352
|
"CircularProgressBar": ["AppearanceBrand", "AppearanceSystem", "circularProgressBar Size", "Color Mode", "Emphasis", "Semantic Intent"],
|
|
352
|
-
"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"],
|
|
353
|
+
"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"],
|
|
353
354
|
"ClusterBubble": ["Appearance / DataViz", "Color Mode", "Context", "context 10", "Emphasis / DataViz", "Profile Card Appearance", "Text Appearance"],
|
|
354
355
|
"CompareTable": ["Accordion States", "AppearanceBrand", "Button / Size", "Button / State", "Color Mode", "Emphasis", "Page type", "Radius"],
|
|
355
356
|
"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"],
|
|
@@ -377,7 +378,7 @@ const FIGMA_COMPONENT_MODES = exports.FIGMA_COMPONENT_MODES = {
|
|
|
377
378
|
"HeroSection": ["AppearanceBrand", "Button / Size", "Button / State", "Color Mode", "context 9", "context7", "Emphasis", "FormField States", "InputState", "Page type", "Status"],
|
|
378
379
|
"HoldingsCard": ["AppearanceBrand", "Color Mode"],
|
|
379
380
|
"HStack": ["Context", "Padding", "Page type", "Slot gap", "Stack Context"],
|
|
380
|
-
"Icon": ["AppearanceBrand", "
|
|
381
|
+
"Icon": ["AppearanceBrand", "Badge Size", "Color Mode", "context 10", "Context4", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent"],
|
|
381
382
|
"IconButton": ["AppearanceBrand", "Button / Size", "Button / State", "Color Mode", "Emphasis", "Page type"],
|
|
382
383
|
"IconCapsule": ["AppearanceBrand", "AppearanceSystem", "Color Mode", "Context", "Emphasis", "Icon Capsule Size", "Page type", "Semantic Intent"],
|
|
383
384
|
"InputSearch": ["Color Mode", "FormField States", "InputState", "Status"],
|
|
@@ -392,12 +393,12 @@ const FIGMA_COMPONENT_MODES = exports.FIGMA_COMPONENT_MODES = {
|
|
|
392
393
|
"MediaCard": ["Contrast Context"],
|
|
393
394
|
"MerchantProfile": ["Avatar Size", "Badge Size", "Color Mode", "context 10", "Context4", "Profile Card Appearance"],
|
|
394
395
|
"MessageField": ["Color Mode", "FormField States"],
|
|
395
|
-
"MetricData": ["AppearanceBrand", "
|
|
396
|
+
"MetricData": ["AppearanceBrand", "Badge Size", "Color Mode", "context 10", "Context4", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent"],
|
|
396
397
|
"MetricLegendItem": ["Appearance / DataViz", "Color Mode", "Emphasis / DataViz"],
|
|
397
398
|
"MoneyValue": ["Color Mode", "Context3"],
|
|
398
399
|
"MonthlyStatusGrid": ["Appearance / DataViz", "Calendar Glyph State", "Color Mode", "Emphasis / DataViz"],
|
|
399
400
|
"NavArrow": ["Color Mode", "context 10", "Context2", "context5", "List Item Style", "NavArrow Direction", "Page type", "Profile Card Appearance"],
|
|
400
|
-
"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"],
|
|
401
|
+
"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"],
|
|
401
402
|
"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"],
|
|
402
403
|
"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"],
|
|
403
404
|
"PaymentFeedback": ["AppearanceBrand", "AppearanceSystem", "Color Mode", "Context", "Emphasis", "Icon Capsule Size", "Page type", "Semantic Intent"],
|
|
@@ -443,7 +444,7 @@ const FIGMA_COMPONENT_MODES = exports.FIGMA_COMPONENT_MODES = {
|
|
|
443
444
|
"TransactionBubble": ["Color Mode", "context 10", "Context2", "Context3", "context5", "List Item Style", "NavArrow Direction", "Page type", "Profile Card Appearance", "Transaction Status"],
|
|
444
445
|
"TransactionStatus": ["Transaction Status"],
|
|
445
446
|
"UpiHandle": ["Color Mode", "context 10", "Profile Card Appearance", "UPI Handle Image"],
|
|
446
|
-
"ValueBackMetric": ["AppearanceBrand", "
|
|
447
|
+
"ValueBackMetric": ["AppearanceBrand", "Badge Size", "Color Mode", "Context", "context 10", "Context4", "Emphasis", "Page type", "Profile Card Appearance", "Semantic Intent", "Text Appearance", "Text Sizes", "Weight"],
|
|
447
448
|
"VStack": ["Context", "Padding", "Page type", "Slot gap", "Stack Context"]
|
|
448
449
|
};
|
|
449
450
|
|