jfs-components 0.1.19 → 0.1.25

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 (55) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/lib/commonjs/components/CardCTA/CardCTA.js +32 -25
  3. package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +31 -8
  4. package/lib/commonjs/components/ChipSelect/ChipSelect.js +2 -1
  5. package/lib/commonjs/components/ContentSheet/ContentSheet.js +131 -0
  6. package/lib/commonjs/components/HeroSection/HeroSection.js +165 -0
  7. package/lib/commonjs/components/Image/Image.js +33 -7
  8. package/lib/commonjs/components/Link/Link.js +115 -0
  9. package/lib/commonjs/components/ListItem/ListItem.js +27 -5
  10. package/lib/commonjs/components/MetricData/MetricData.js +132 -0
  11. package/lib/commonjs/components/Rating/Rating.js +137 -0
  12. package/lib/commonjs/components/index.js +21 -0
  13. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  14. package/lib/commonjs/design-tokens/figma-modes.generated.js +55 -43
  15. package/lib/commonjs/icons/registry.js +1 -1
  16. package/lib/module/components/CardCTA/CardCTA.js +32 -25
  17. package/lib/module/components/CheckboxItem/CheckboxItem.js +31 -8
  18. package/lib/module/components/ChipSelect/ChipSelect.js +2 -1
  19. package/lib/module/components/ContentSheet/ContentSheet.js +126 -0
  20. package/lib/module/components/HeroSection/HeroSection.js +159 -0
  21. package/lib/module/components/Image/Image.js +34 -7
  22. package/lib/module/components/Link/Link.js +110 -0
  23. package/lib/module/components/ListItem/ListItem.js +27 -5
  24. package/lib/module/components/MetricData/MetricData.js +127 -0
  25. package/lib/module/components/Rating/Rating.js +132 -0
  26. package/lib/module/components/index.js +3 -0
  27. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  28. package/lib/module/design-tokens/figma-modes.generated.js +55 -43
  29. package/lib/module/icons/registry.js +1 -1
  30. package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +26 -3
  31. package/lib/typescript/src/components/ChipSelect/ChipSelect.d.ts +6 -1
  32. package/lib/typescript/src/components/ContentSheet/ContentSheet.d.ts +71 -0
  33. package/lib/typescript/src/components/HeroSection/HeroSection.d.ts +80 -0
  34. package/lib/typescript/src/components/Image/Image.d.ts +27 -2
  35. package/lib/typescript/src/components/Link/Link.d.ts +73 -0
  36. package/lib/typescript/src/components/MetricData/MetricData.d.ts +53 -0
  37. package/lib/typescript/src/components/Rating/Rating.d.ts +30 -0
  38. package/lib/typescript/src/components/index.d.ts +3 -0
  39. package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +8 -0
  40. package/lib/typescript/src/icons/registry.d.ts +1 -1
  41. package/package.json +1 -1
  42. package/src/components/CardCTA/CardCTA.tsx +30 -15
  43. package/src/components/CheckboxItem/CheckboxItem.tsx +59 -14
  44. package/src/components/ChipSelect/ChipSelect.tsx +7 -1
  45. package/src/components/ContentSheet/ContentSheet.tsx +217 -0
  46. package/src/components/HeroSection/HeroSection.tsx +231 -0
  47. package/src/components/Image/Image.tsx +55 -3
  48. package/src/components/Link/Link.tsx +159 -0
  49. package/src/components/ListItem/ListItem.tsx +26 -4
  50. package/src/components/MetricData/MetricData.tsx +185 -0
  51. package/src/components/Rating/Rating.tsx +174 -0
  52. package/src/components/index.ts +3 -0
  53. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  54. package/src/design-tokens/figma-modes.generated.ts +55 -43
  55. package/src/icons/registry.ts +1 -1
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
10
+ var _reactUtils = require("../../utils/react-utils");
11
+ var _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); }
13
+ const TEXT_ALIGN_MAP = {
14
+ Left: 'left',
15
+ Center: 'center'
16
+ };
17
+ const DISABLED_OPACITY = 0.4;
18
+
19
+ /**
20
+ * Link — an underlined, pressable text primitive.
21
+ *
22
+ * It renders a single React Native `<Text>` (not a `Pressable`), so it flows
23
+ * inline and can be nested inside {@link TextSegment} exactly like a `Text`
24
+ * run — the React Native equivalent of an `<a>` inside a `<p>`. Font family,
25
+ * size, weight, line-height and letter-spacing come from the dedicated `link/*`
26
+ * tokens, while the colour resolves from `text/foreground` (so a link sits on
27
+ * the same colour as the surrounding copy). The label is always underlined.
28
+ *
29
+ * @example Standalone
30
+ * ```tsx
31
+ * <Link text="Forgot PIN?" onPress={() => navigation.navigate('ResetPin')} />
32
+ * ```
33
+ *
34
+ * @example Inline inside TextSegment
35
+ * ```tsx
36
+ * <TextSegment>
37
+ * <Text>By continuing you agree to our </Text>
38
+ * <Link onPress={openTerms}>Terms</Link>
39
+ * <Text>.</Text>
40
+ * </TextSegment>
41
+ * ```
42
+ */
43
+ function Link({
44
+ text,
45
+ children,
46
+ onPress,
47
+ disabled = false,
48
+ autolayout = 'Fill',
49
+ textAlign = 'Left',
50
+ modes = _reactUtils.EMPTY_MODES,
51
+ style,
52
+ numberOfLines,
53
+ disableTruncation,
54
+ singleLine,
55
+ accessibilityLabel,
56
+ accessibilityHint
57
+ }) {
58
+ // Bindings mirror the Figma `Link` node exactly: colour from `text/foreground`
59
+ // (so the link matches the surrounding copy), everything else from the
60
+ // dedicated `link/*` tokens.
61
+ const foreground = (0, _figmaVariablesResolver.getVariableByName)('text/foreground', modes) ?? '#000000';
62
+ const fontFamily = (0, _figmaVariablesResolver.getVariableByName)('link/fontFamily', modes) ?? 'JioType Var';
63
+ const fontSize = (0, _figmaVariablesResolver.getVariableByName)('link/fontSize', modes) ?? 12;
64
+ const fontWeight = (0, _figmaVariablesResolver.getVariableByName)('link/fontWeight', modes) ?? 400;
65
+ const lineHeight = (0, _figmaVariablesResolver.getVariableByName)('link/lineHeight', modes) ?? 16;
66
+ const letterSpacing = (0, _figmaVariablesResolver.getVariableByName)('link/letterSpacing', modes) ?? -0.5;
67
+ const linkStyle = {
68
+ color: foreground,
69
+ fontFamily: fontFamily,
70
+ fontSize: fontSize,
71
+ fontWeight: String(fontWeight),
72
+ lineHeight: lineHeight,
73
+ letterSpacing: letterSpacing,
74
+ textAlign: TEXT_ALIGN_MAP[textAlign],
75
+ textDecorationLine: 'underline',
76
+ alignSelf: autolayout === 'Fill' ? 'stretch' : 'flex-start',
77
+ ...(disabled ? {
78
+ opacity: DISABLED_OPACITY
79
+ } : null)
80
+ };
81
+ const content = children !== undefined && children !== null && children !== false ? children : text !== undefined ? text : 'Link';
82
+ const handlePress = (0, _react.useCallback)(event => {
83
+ if (disabled) return;
84
+ onPress?.(event);
85
+ }, [disabled, onPress]);
86
+ const {
87
+ style: layoutStyle,
88
+ ...truncation
89
+ } = (0, _reactUtils.resolveTextLayout)({
90
+ disableTruncation,
91
+ singleLine,
92
+ numberOfLines
93
+ });
94
+ const resolvedLabel = accessibilityLabel ?? (typeof content === 'string' ? content : undefined);
95
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
96
+ accessibilityRole: "link",
97
+ accessibilityState: {
98
+ disabled
99
+ },
100
+ ...(resolvedLabel !== undefined ? {
101
+ accessibilityLabel: resolvedLabel
102
+ } : null),
103
+ ...(accessibilityHint !== undefined ? {
104
+ accessibilityHint
105
+ } : null),
106
+ ...(onPress !== undefined ? {
107
+ onPress: handlePress
108
+ } : null),
109
+ disabled: disabled,
110
+ style: [linkStyle, style, layoutStyle],
111
+ ...truncation,
112
+ children: content
113
+ });
114
+ }
115
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(Link);
@@ -63,6 +63,17 @@ function resolveListItemTokens(modes) {
63
63
  const paddingLeft = (0, _figmaVariablesResolver.getVariableByName)('listItem/padding/left', resolvedModes) ?? 0;
64
64
  const paddingRight = (0, _figmaVariablesResolver.getVariableByName)('listItem/padding/right', resolvedModes) ?? 0;
65
65
  const textWrapGap = (0, _figmaVariablesResolver.getVariableByName)('listItem/text wrap', resolvedModes) ?? 0;
66
+
67
+ // Container surface — driven by the `List Item Style` collection
68
+ // (Default | Boxed | Minimal) plus `ListItem State`, `Selectable`,
69
+ // `Page type` and `Color Mode`. In the default style these all resolve to a
70
+ // transparent background / no border / 0 radius, so existing usages are
71
+ // visually unchanged; the "Boxed" style paints a filled, rounded, bordered
72
+ // surface.
73
+ const backgroundColor = (0, _figmaVariablesResolver.getVariableByName)('listItem/background/color', resolvedModes);
74
+ const borderColor = (0, _figmaVariablesResolver.getVariableByName)('listItem/border/color', resolvedModes);
75
+ const borderWidth = (0, _figmaVariablesResolver.getVariableByName)('listItem/borderWidth', resolvedModes) ?? 0;
76
+ const borderRadius = (0, _figmaVariablesResolver.getVariableByName)('listItem/radius', resolvedModes) ?? 0;
66
77
  const titleColor = (0, _figmaVariablesResolver.getVariableByName)('listItem/title/color', textModes);
67
78
  const titleFontSize = (0, _figmaVariablesResolver.getVariableByName)('listItem/title/fontSize', textModes);
68
79
  const titleLineHeight = (0, _figmaVariablesResolver.getVariableByName)('listItem/title/lineHeight', textModes);
@@ -80,7 +91,11 @@ function resolveListItemTokens(modes) {
80
91
  paddingTop: paddingTop,
81
92
  paddingBottom: paddingBottom,
82
93
  paddingLeft: paddingLeft,
83
- paddingRight: paddingRight
94
+ paddingRight: paddingRight,
95
+ backgroundColor: backgroundColor,
96
+ borderColor: borderColor,
97
+ borderWidth,
98
+ borderRadius
84
99
  },
85
100
  horizontalLayoutStyle: {
86
101
  flexDirection: 'row',
@@ -240,13 +255,20 @@ function ListItemImpl({
240
255
  const renderSupportContent = () => {
241
256
  if (processedSupportSlot) return processedSupportSlot;
242
257
 
243
- // Default support text:
244
- // - vertical layout: main text (line-broken on spaces)
245
- // - horizontal layout: secondary line (clamped to 2 lines)
258
+ // Default support text — ONE `<Text>` hard-clamped to 2 lines via
259
+ // `numberOfLines={2}`, the only mechanism React Native actually enforces
260
+ // on iOS/Android (native has no `white-space: nowrap` equivalent, so any
261
+ // style-based trick cannot stop a too-wide word from wrapping).
262
+ //
263
+ // - vertical layout: line-broken on spaces so each word gets its own line
264
+ // ("Split Payments" → "Split" / "Payments"). If a word is still wider
265
+ // than the cell (or there are 3+ words), RN cuts it off at line 2 with
266
+ // a trailing ellipsis instead of ever spilling onto a third line.
267
+ // - horizontal layout: natural wrapping, same 2-line clamp.
246
268
  const displayText = layout === 'Vertical' ? supportText.replace(/ /g, '\n') : supportText;
247
269
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
248
270
  style: layout === 'Vertical' ? [tokens.supportTextStyle, verticalSupportTextOverride] : tokens.supportTextStyle,
249
- ...(0, _reactUtils.resolveTruncation)(disableTruncation, layout === 'Horizontal' ? 2 : undefined),
271
+ ...(0, _reactUtils.resolveTruncation)(disableTruncation, 2, 'tail'),
250
272
  children: displayText
251
273
  });
252
274
  };
@@ -0,0 +1,132 @@
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 _reactUtils = require("../../utils/react-utils");
11
+ var _Icon = _interopRequireDefault(require("../Icon/Icon"));
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ const LINE_HEIGHT_RATIO = 1.2;
15
+ const ICON_SIZE = 18;
16
+ // Figma renders the value-row icon with no surrounding padding; the shared Icon
17
+ // component pulls padding from `icon/padding/*` tokens, so we zero it here.
18
+ const ICON_PADDING_RESET = {
19
+ paddingLeft: 0,
20
+ paddingRight: 0,
21
+ paddingTop: 0,
22
+ paddingBottom: 0
23
+ };
24
+ /**
25
+ * MetricData — a compact, centered metric block.
26
+ *
27
+ * Stacks a small `title`, a prominent `value` (with an optional leading
28
+ * `icon`), and a muted `caption`. Typography, colours, gaps and padding all
29
+ * resolve from the `metricdata/*` design tokens. `title`, `caption` and `icon`
30
+ * are optional; only `value` is shown by default.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * <MetricData title="Balance" value="₹1,20,000" caption="as of today" />
35
+ * <MetricData title="Cards" value="12" icon="ic_card" caption="active" />
36
+ * ```
37
+ */
38
+ function MetricData({
39
+ title,
40
+ value,
41
+ caption,
42
+ icon,
43
+ modes = _reactUtils.EMPTY_MODES,
44
+ style,
45
+ titleStyle,
46
+ valueStyle,
47
+ captionStyle,
48
+ accessibilityLabel
49
+ }) {
50
+ const titleColor = (0, _figmaVariablesResolver.getVariableByName)('metricdata/title/color', modes) ?? '#000000';
51
+ const titleFontFamily = (0, _figmaVariablesResolver.getVariableByName)('metricdata/title/fontfamily', modes) ?? 'JioType Var';
52
+ const titleFontSize = (0, _figmaVariablesResolver.getVariableByName)('metricdata/title/fontsize', modes) ?? 12;
53
+ const titleFontWeight = String((0, _figmaVariablesResolver.getVariableByName)('metricdata/title/fontweight', modes) ?? 400);
54
+ const valueColor = (0, _figmaVariablesResolver.getVariableByName)('metricdata/value/color', modes) ?? '#000000';
55
+ const valueFontFamily = (0, _figmaVariablesResolver.getVariableByName)('metricdata/value/fontfamily', modes) ?? 'JioType Var';
56
+ const valueFontSize = (0, _figmaVariablesResolver.getVariableByName)('metricdata/value/fontsize', modes) ?? 20;
57
+ const valueFontWeight = String((0, _figmaVariablesResolver.getVariableByName)('metricdata/value/fontweight', modes) ?? 700);
58
+ const captionColor = (0, _figmaVariablesResolver.getVariableByName)('metricdata/caption/color', modes) ?? '#777777';
59
+ const captionFontFamily = (0, _figmaVariablesResolver.getVariableByName)('metricdata/caption/fontfamily', modes) ?? 'JioType Var';
60
+ const captionFontSize = (0, _figmaVariablesResolver.getVariableByName)('metricdata/caption/fontsize', modes) ?? 12;
61
+ const captionFontWeight = String((0, _figmaVariablesResolver.getVariableByName)('metricdata/caption/fontweight', modes) ?? 500);
62
+ const gap = (0, _figmaVariablesResolver.getVariableByName)('metricdata/gap', modes) ?? 4;
63
+ const valueWrapGap = (0, _figmaVariablesResolver.getVariableByName)('metricdata/valueWrap/gap', modes) ?? 4;
64
+ const paddingHorizontal = (0, _figmaVariablesResolver.getVariableByName)('metricdata/padding/horizontal', modes) ?? 10;
65
+ const paddingVertical = (0, _figmaVariablesResolver.getVariableByName)('metricdata/padding/vertical', modes) ?? 10;
66
+ const containerStyle = {
67
+ flexDirection: 'column',
68
+ alignItems: 'center',
69
+ justifyContent: 'center',
70
+ gap,
71
+ paddingHorizontal,
72
+ paddingVertical
73
+ };
74
+ const titleTextStyle = {
75
+ color: titleColor,
76
+ fontFamily: titleFontFamily,
77
+ fontSize: titleFontSize,
78
+ fontWeight: titleFontWeight,
79
+ lineHeight: titleFontSize * LINE_HEIGHT_RATIO,
80
+ textAlign: 'center'
81
+ };
82
+ const valueTextStyle = {
83
+ color: valueColor,
84
+ fontFamily: valueFontFamily,
85
+ fontSize: valueFontSize,
86
+ fontWeight: valueFontWeight,
87
+ lineHeight: valueFontSize * LINE_HEIGHT_RATIO,
88
+ textAlign: 'center'
89
+ };
90
+ const captionTextStyle = {
91
+ color: captionColor,
92
+ fontFamily: captionFontFamily,
93
+ fontSize: captionFontSize,
94
+ fontWeight: captionFontWeight,
95
+ lineHeight: captionFontSize * LINE_HEIGHT_RATIO,
96
+ textAlign: 'center'
97
+ };
98
+ const iconNode = icon == null ? null : typeof icon === 'string' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
99
+ iconName: icon,
100
+ size: ICON_SIZE,
101
+ color: valueColor,
102
+ modes: modes,
103
+ style: ICON_PADDING_RESET
104
+ }) : icon;
105
+ const resolvedLabel = accessibilityLabel ?? ([title, typeof value === 'string' ? value : undefined, caption].filter(Boolean).join(', ') || undefined);
106
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
107
+ style: [containerStyle, style],
108
+ accessible: true,
109
+ ...(resolvedLabel !== undefined ? {
110
+ accessibilityLabel: resolvedLabel
111
+ } : null),
112
+ children: [title !== undefined && title !== '' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
113
+ style: [titleTextStyle, titleStyle],
114
+ children: title
115
+ }) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
116
+ style: {
117
+ flexDirection: 'row',
118
+ alignItems: 'center',
119
+ justifyContent: 'center',
120
+ gap: valueWrapGap
121
+ },
122
+ children: [iconNode, typeof value === 'string' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
123
+ style: [valueTextStyle, valueStyle],
124
+ children: value
125
+ }) : value]
126
+ }), caption !== undefined && caption !== '' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
127
+ style: [captionTextStyle, captionStyle],
128
+ children: caption
129
+ }) : null]
130
+ });
131
+ }
132
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(MetricData);
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
10
+ var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
11
+ var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
12
+ var _reactUtils = require("../../utils/react-utils");
13
+ var _jsxRuntime = require("react/jsx-runtime");
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); }
15
+ /**
16
+ * Star glyph taken directly from the Figma `Rating` component. Filled and empty
17
+ * stars share this shape and differ only by fill color, so a single path keeps
18
+ * the row perfectly aligned.
19
+ */
20
+ const STAR_PATH = 'M40.7187 15.3334C40.4728 14.6159 40.0426 13.9805 39.4688 13.4885C38.8951 12.9965 38.1985 12.689 37.4403 12.566L28.3018 11.1721L24.2038 2.35741C23.8759 1.66044 23.3432 1.06596 22.6875 0.635476C22.0318 0.225491 21.2737 0 20.4951 0C19.7165 0 18.9583 0.225491 18.3027 0.635476C17.647 1.04546 17.1142 1.63994 16.7864 2.35741L12.6884 11.1721L3.4679 12.566C2.73026 12.689 2.01311 12.9965 1.43939 13.4885C0.865675 13.9805 0.435385 14.6159 0.189505 15.3334C-0.0358854 16.0304 -0.0563753 16.7889 0.107545 17.5063C0.271465 18.2238 0.640285 18.9003 1.15254 19.4333L7.89374 26.362L6.29552 36.1811C6.17258 36.9396 6.27503 37.7186 6.56189 38.4156C6.84875 39.1125 7.34051 39.7275 7.9757 40.1785C8.65187 40.691 9.49196 40.978 10.3525 40.9985C11.0697 40.9985 11.7664 40.8345 12.4015 40.486L20.5771 35.9761L28.7526 40.486C29.3673 40.8345 30.0844 41.019 30.8016 40.9985C31.6621 40.9985 32.4817 40.732 33.1784 40.24C33.7931 39.789 34.2849 39.1945 34.5922 38.4771C34.8791 37.7801 34.9815 37.0011 34.8586 36.2426L33.2604 26.4235L40.0016 19.4948C40.4933 18.9413 40.8007 18.2443 40.9441 17.5063C41.0671 16.7684 40.9851 16.0099 40.7187 15.3334Z';
21
+ const STAR_VIEWBOX = '0 0 41 41';
22
+
23
+ // Fallbacks mirror the Figma `Rating Star / Output` + `Rating Star State` tokens.
24
+ const DEFAULT_STAR_SIZE = 41;
25
+ const DEFAULT_GAP = 12;
26
+ const SELECTED_FALLBACK = '#5D00B5';
27
+ const IDLE_FALLBACK = '#F6F3FF';
28
+
29
+ /**
30
+ * `ratingStar/background` is state-driven: the same token resolves to the filled
31
+ * color when `Rating Star State = selected` and to the empty color when `idle`.
32
+ */
33
+ const RATING_STATE_COLLECTION = 'Rating Star State';
34
+ const toNumber = (value, fallback) => {
35
+ const n = typeof value === 'string' ? Number(value) : value;
36
+ return typeof n === 'number' && Number.isFinite(n) ? n : fallback;
37
+ };
38
+ function Star({
39
+ width,
40
+ height,
41
+ color
42
+ }) {
43
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.default, {
44
+ width: width,
45
+ height: height,
46
+ viewBox: STAR_VIEWBOX,
47
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
48
+ d: STAR_PATH,
49
+ fill: color
50
+ })
51
+ });
52
+ }
53
+ function Rating({
54
+ value = 0,
55
+ max = 5,
56
+ onChange,
57
+ readOnly = false,
58
+ starSize,
59
+ gap,
60
+ modes: propModes = _reactUtils.EMPTY_MODES,
61
+ style,
62
+ accessibilityLabel,
63
+ ...rest
64
+ }) {
65
+ const {
66
+ modes: globalModes
67
+ } = (0, _JFSThemeProvider.useTokens)();
68
+ const modes = (0, _react.useMemo)(() => globalModes === _reactUtils.EMPTY_MODES && propModes === _reactUtils.EMPTY_MODES ? _reactUtils.EMPTY_MODES : {
69
+ ...globalModes,
70
+ ...propModes
71
+ }, [globalModes, propModes]);
72
+ const {
73
+ selectedColor,
74
+ idleColor,
75
+ starWidth,
76
+ starHeight,
77
+ resolvedGap
78
+ } = (0, _react.useMemo)(() => {
79
+ const selected = (0, _figmaVariablesResolver.getVariableByName)('ratingStar/background', {
80
+ ...modes,
81
+ [RATING_STATE_COLLECTION]: 'selected'
82
+ });
83
+ const idle = (0, _figmaVariablesResolver.getVariableByName)('ratingStar/background', {
84
+ ...modes,
85
+ [RATING_STATE_COLLECTION]: 'idle'
86
+ });
87
+ return {
88
+ selectedColor: selected ?? SELECTED_FALLBACK,
89
+ idleColor: idle ?? IDLE_FALLBACK,
90
+ starWidth: starSize ?? toNumber((0, _figmaVariablesResolver.getVariableByName)('ratingStar/width', modes), DEFAULT_STAR_SIZE),
91
+ starHeight: starSize ?? toNumber((0, _figmaVariablesResolver.getVariableByName)('ratingStar/height', modes), DEFAULT_STAR_SIZE),
92
+ resolvedGap: gap ?? toNumber((0, _figmaVariablesResolver.getVariableByName)('rating/gap', modes), DEFAULT_GAP)
93
+ };
94
+ }, [modes, starSize, gap]);
95
+ const total = Math.max(0, Math.round(max));
96
+ const filledCount = Math.max(0, Math.min(total, Math.round(value)));
97
+ const interactive = !readOnly && typeof onChange === 'function';
98
+ const label = accessibilityLabel ?? `${filledCount} of ${total} stars`;
99
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
100
+ ...rest,
101
+ style: [{
102
+ flexDirection: 'row',
103
+ alignItems: 'center',
104
+ gap: resolvedGap
105
+ }, style],
106
+ accessibilityRole: interactive ? 'adjustable' : 'image',
107
+ accessibilityLabel: label,
108
+ accessibilityValue: interactive ? {
109
+ min: 0,
110
+ max: total,
111
+ now: filledCount
112
+ } : undefined,
113
+ children: Array.from({
114
+ length: total
115
+ }, (_, index) => {
116
+ const color = index < filledCount ? selectedColor : idleColor;
117
+ const star = /*#__PURE__*/(0, _jsxRuntime.jsx)(Star, {
118
+ width: starWidth,
119
+ height: starHeight,
120
+ color: color
121
+ });
122
+ if (!interactive) {
123
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.default.Fragment, {
124
+ children: star
125
+ }, index);
126
+ }
127
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
128
+ onPress: () => onChange?.(index + 1),
129
+ accessibilityRole: "button",
130
+ accessibilityLabel: `Rate ${index + 1} of ${total} stars`,
131
+ hitSlop: 8,
132
+ children: star
133
+ }, index);
134
+ })
135
+ });
136
+ }
137
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(Rating);
@@ -267,6 +267,12 @@ Object.defineProperty(exports, "ComparisonBar", {
267
267
  return _ComparisonBar.default;
268
268
  }
269
269
  });
270
+ Object.defineProperty(exports, "ContentSheet", {
271
+ enumerable: true,
272
+ get: function () {
273
+ return _ContentSheet.default;
274
+ }
275
+ });
270
276
  Object.defineProperty(exports, "CoverageBarComparison", {
271
277
  enumerable: true,
272
278
  get: function () {
@@ -387,6 +393,12 @@ Object.defineProperty(exports, "HStack", {
387
393
  return _HStack.default;
388
394
  }
389
395
  });
396
+ Object.defineProperty(exports, "HeroSection", {
397
+ enumerable: true,
398
+ get: function () {
399
+ return _HeroSection.default;
400
+ }
401
+ });
390
402
  Object.defineProperty(exports, "HoldingsCard", {
391
403
  enumerable: true,
392
404
  get: function () {
@@ -447,6 +459,12 @@ Object.defineProperty(exports, "LinearProgress", {
447
459
  return _LinearProgress.default;
448
460
  }
449
461
  });
462
+ Object.defineProperty(exports, "Link", {
463
+ enumerable: true,
464
+ get: function () {
465
+ return _Link.default;
466
+ }
467
+ });
450
468
  Object.defineProperty(exports, "ListGroup", {
451
469
  enumerable: true,
452
470
  get: function () {
@@ -1011,6 +1029,7 @@ var _FilterBar = _interopRequireDefault(require("./FilterBar/FilterBar"));
1011
1029
  var _FullscreenModal = _interopRequireDefault(require("./FullscreenModal/FullscreenModal"));
1012
1030
  var _Form = _interopRequireWildcard(require("./Form/Form"));
1013
1031
  var _FormField = _interopRequireDefault(require("./FormField/FormField"));
1032
+ var _ContentSheet = _interopRequireDefault(require("./ContentSheet/ContentSheet"));
1014
1033
  var _CircularProgressBar = _interopRequireDefault(require("./CircularProgressBar/CircularProgressBar"));
1015
1034
  var _CircularProgressBarDoted = _interopRequireDefault(require("./CircularProgressBarDoted/CircularProgressBarDoted"));
1016
1035
  var _CircularRating = _interopRequireDefault(require("./CircularRating/CircularRating"));
@@ -1020,6 +1039,7 @@ var _ComparisonBar = _interopRequireDefault(require("./ComparisonBar/ComparisonB
1020
1039
  var _AllocationComparisonChart = _interopRequireDefault(require("./AllocationComparisonChart/AllocationComparisonChart"));
1021
1040
  var _MonthlyStatusGrid = _interopRequireWildcard(require("./MonthlyStatusGrid/MonthlyStatusGrid"));
1022
1041
  var _Gauge = _interopRequireDefault(require("./Gauge/Gauge"));
1042
+ var _HeroSection = _interopRequireDefault(require("./HeroSection/HeroSection"));
1023
1043
  var _HoldingsCard = _interopRequireDefault(require("./HoldingsCard/HoldingsCard"));
1024
1044
  var _HStack = _interopRequireDefault(require("./HStack/HStack"));
1025
1045
  var _Icon = _interopRequireDefault(require("./Icon/Icon"));
@@ -1027,6 +1047,7 @@ var _IconButton = _interopRequireDefault(require("./IconButton/IconButton"));
1027
1047
  var _IconCapsule = _interopRequireDefault(require("./IconCapsule/IconCapsule"));
1028
1048
  var _Image = _interopRequireDefault(require("./Image/Image"));
1029
1049
  var _LazyList = _interopRequireDefault(require("./LazyList/LazyList"));
1050
+ var _Link = _interopRequireDefault(require("./Link/Link"));
1030
1051
  var _LinearMeter = _interopRequireDefault(require("./LinearMeter/LinearMeter"));
1031
1052
  var _LinearProgress = _interopRequireDefault(require("./LinearProgress/LinearProgress"));
1032
1053
  var _ListGroup = _interopRequireDefault(require("./ListGroup/ListGroup"));