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
@@ -10,7 +10,25 @@ export type CheckboxItemProps = {
10
10
  onValueChange?: (checked: boolean) => void;
11
11
  /** Whether the row is disabled — both the checkbox and row press handler are disabled. */
12
12
  disabled?: boolean;
13
- /** The label text rendered next to the checkbox. */
13
+ /**
14
+ * Content rendered in the row's label slot (between the leading and trailing
15
+ * edges). This is the primary way to supply the label and mirrors the Figma
16
+ * "slot" — pass a plain string for the default token-styled label, or any
17
+ * custom node (e.g. a `<Text>`, a row of `<Text>` + `<Badge>`, etc.) for full
18
+ * control. Custom nodes receive the same `modes` as the parent.
19
+ *
20
+ * When both `children` and the legacy {@link label} prop are provided,
21
+ * `children` wins.
22
+ */
23
+ children?: React.ReactNode;
24
+ /**
25
+ * The label content rendered next to the checkbox.
26
+ *
27
+ * @deprecated Prefer the `children` slot instead
28
+ * (`<CheckboxItem>Fixed deposit • 0245</CheckboxItem>`). `label` is kept for
29
+ * backward compatibility and behaves identically — it is used only when no
30
+ * `children` are provided.
31
+ */
14
32
  label?: React.ReactNode;
15
33
  /**
16
34
  * Position of the checkbox control relative to the label.
@@ -59,13 +77,18 @@ export type CheckboxItemProps = {
59
77
  * ```tsx
60
78
  * const [checked, setChecked] = useState(false)
61
79
  *
80
+ * // Recommended: pass the label via the children slot.
62
81
  * <CheckboxItem
63
- * label="Fixed deposit • 0245"
64
82
  * checked={checked}
65
83
  * onValueChange={setChecked}
66
84
  * control="leading"
67
85
  * modes={{ 'Color Mode': 'Light' }}
68
- * />
86
+ * >
87
+ * Fixed deposit • 0245
88
+ * </CheckboxItem>
89
+ *
90
+ * // Still supported (deprecated): the `label` prop.
91
+ * <CheckboxItem label="Fixed deposit • 0245" />
69
92
  * ```
70
93
  */
71
94
  declare const CheckboxItem: React.ForwardRefExoticComponent<CheckboxItemProps & React.RefAttributes<View>>;
@@ -17,6 +17,11 @@ export type ChipSelectProps = {
17
17
  * @default "ic_calendar_week"
18
18
  */
19
19
  icon?: string;
20
+ /**
21
+ * Whether to show the close icon when active.
22
+ * @default true
23
+ */
24
+ showCloseIcon?: boolean;
20
25
  /**
21
26
  * Modes for design token resolution.
22
27
  */
@@ -38,6 +43,6 @@ export type ChipSelectProps = {
38
43
  * ChipSelect component for selecting options (e.g. Date selection).
39
44
  * Based on Figma Node 1901-4727.
40
45
  */
41
- declare function ChipSelect({ label, active, icon, modes, style, labelSlot, onPress, }: ChipSelectProps): import("react/jsx-runtime").JSX.Element;
46
+ declare function ChipSelect({ label, active, icon, showCloseIcon, modes, style, labelSlot, onPress, }: ChipSelectProps): import("react/jsx-runtime").JSX.Element;
42
47
  export default ChipSelect;
43
48
  //# sourceMappingURL=ChipSelect.d.ts.map
@@ -0,0 +1,71 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewProps, type ViewStyle } from 'react-native';
3
+ import type { Modes } from '../../design-tokens';
4
+ export type ContentSheetProps = {
5
+ /**
6
+ * Sheet content. The sheet is one big slot: whatever you place here is
7
+ * stacked in a column (separated by the `contentSheet/gap` token) inside the
8
+ * sheet's padding. The sheet has **no fixed height** — it grows and shrinks
9
+ * to fit these children automatically.
10
+ */
11
+ children?: React.ReactNode;
12
+ /**
13
+ * Design-token modes. Cascaded to every slot child via
14
+ * {@link cloneChildrenWithModes} so nested `ListItem`/`Section`/etc. resolve
15
+ * the same theme without you wiring `modes` onto each one.
16
+ */
17
+ modes?: Modes;
18
+ /**
19
+ * Keep the sheet above the on-screen keyboard. When the keyboard opens the
20
+ * sheet rises by exactly the keyboard height; when it closes the sheet drops
21
+ * back. The follow animation is driven entirely on the UI thread
22
+ * (`useAnimatedKeyboard`) so it never schedules a React re-render and stays
23
+ * in perfect sync with the keyboard on both iOS and Android.
24
+ *
25
+ * On web this is a no-op (soft keyboards there don't overlay content).
26
+ * Default `true`.
27
+ */
28
+ avoidKeyboard?: boolean;
29
+ /**
30
+ * Extra gap (px) inserted between the top of the keyboard and the bottom of
31
+ * the sheet while the keyboard is open. Default `0` (sheet sits flush on the
32
+ * keyboard).
33
+ */
34
+ keyboardSpacing?: number;
35
+ /**
36
+ * Add the device's bottom safe-area inset (home indicator) on top of the
37
+ * sheet's bottom padding, so content never sits under the indicator when the
38
+ * sheet rests at the bottom of the screen. Default `true`.
39
+ */
40
+ safeAreaBottom?: boolean;
41
+ /**
42
+ * Pin the sheet to the bottom of its parent (absolute, full width). This is
43
+ * the default behaviour — the sheet "just stays at the bottom".
44
+ *
45
+ * Set to `false` to render the sheet in normal flow instead (e.g. when you
46
+ * compose it inside your own layout container). Keyboard avoidance still
47
+ * works in both modes.
48
+ */
49
+ pinToBottom?: boolean;
50
+ /** Optional style override applied to the sheet container. */
51
+ style?: StyleProp<ViewStyle>;
52
+ } & Omit<ViewProps, 'style' | 'children'>;
53
+ /**
54
+ * ContentSheet — a bottom-anchored surface that is essentially one big slot
55
+ * with padding and rounded top corners, mirroring the Figma "Content Sheet".
56
+ *
57
+ * Behaviour highlights:
58
+ * - **Auto height (free & automatic).** The sheet never sets an explicit
59
+ * height. React Native's layout engine (Yoga) sizes it to its children on
60
+ * the native thread, so when the slot content grows or shrinks the sheet
61
+ * follows with zero JS measurement and zero extra re-renders — the most
62
+ * performant option possible.
63
+ * - **Keyboard avoidance** on iOS and Android via `avoidKeyboard` (UI-thread
64
+ * `useAnimatedKeyboard`, no re-renders).
65
+ * - **Bottom pinned** by default; opt out with `pinToBottom={false}`.
66
+ * - **Token-driven** styling via `getVariableByName` + `modes`, with `modes`
67
+ * cascaded to all slot children.
68
+ */
69
+ declare function ContentSheet({ children, modes, avoidKeyboard, keyboardSpacing, safeAreaBottom, pinToBottom, style, ...rest }: ContentSheetProps): import("react/jsx-runtime").JSX.Element;
70
+ export default ContentSheet;
71
+ //# sourceMappingURL=ContentSheet.d.ts.map
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ import type { Modes } from '../../design-tokens';
4
+ export type HeroSectionProps = {
5
+ /** Headline text rendered by the internal {@link Title}. */
6
+ title?: string;
7
+ /** Optional subtitle shown below the title. Omit to hide it. */
8
+ subtitle?: string;
9
+ /** Horizontal alignment of the title/subtitle block. */
10
+ titleTextAlign?: 'Left' | 'Center';
11
+ /** Whether to render the title block. Ignored when `titleSlot` is provided. */
12
+ showTitle?: boolean;
13
+ /**
14
+ * Fully replace the default title block. When provided, `title`, `subtitle`,
15
+ * `titleTextAlign`, and `showTitle` are ignored. `modes` cascade into the slot.
16
+ */
17
+ titleSlot?: React.ReactNode;
18
+ /**
19
+ * Whether to render the search + filter row. Ignored when `searchSlot`
20
+ * is provided.
21
+ */
22
+ showSearch?: boolean;
23
+ /** Controlled value for the search input. */
24
+ searchValue?: string;
25
+ /** Change handler for the search input. */
26
+ onSearchChange?: (text: string) => void;
27
+ /** Placeholder for the search input. */
28
+ searchPlaceholder?: string;
29
+ /**
30
+ * Fully replace the search input (the flexible left part of the row). When
31
+ * provided, `searchValue`, `onSearchChange`, and `searchPlaceholder` are
32
+ * ignored. `modes` cascade into the slot.
33
+ */
34
+ searchSlot?: React.ReactNode;
35
+ /** Whether to render the trailing filter icon button. */
36
+ showFilter?: boolean;
37
+ /** Icon name for the filter button (from the icon registry). */
38
+ filterIcon?: string;
39
+ /** Press handler for the filter button. */
40
+ onFilterPress?: () => void;
41
+ /** Accessibility label for the filter button. */
42
+ filterAccessibilityLabel?: string;
43
+ /**
44
+ * Fully replace the trailing filter control. When provided, `filterIcon`,
45
+ * `onFilterPress`, and `showFilter` are ignored. `modes` cascade into the slot.
46
+ */
47
+ filterSlot?: React.ReactNode;
48
+ /** Content rendered in the body area below the search row. */
49
+ children?: React.ReactNode;
50
+ /** Mode configuration for design-token theming. */
51
+ modes?: Modes;
52
+ /** Style overrides applied to the outer container. */
53
+ style?: StyleProp<ViewStyle>;
54
+ testID?: string;
55
+ };
56
+ /**
57
+ * HeroSection is a page-level header block: a title (with optional subtitle),
58
+ * an optional search row (a flexible search input plus a trailing filter
59
+ * button), and a free-form content slot below.
60
+ *
61
+ * All spacing/background values resolve from the `HeroSection / Output` design
62
+ * token collection via `getVariableByName`. `modes` cascade to every slot and
63
+ * child component so downstream tokens stay in sync.
64
+ *
65
+ * @example
66
+ * ```tsx
67
+ * <HeroSection
68
+ * title="Transactions"
69
+ * subtitle="Last 30 days"
70
+ * searchValue={query}
71
+ * onSearchChange={setQuery}
72
+ * onFilterPress={openFilters}
73
+ * >
74
+ * <TransactionList data={items} />
75
+ * </HeroSection>
76
+ * ```
77
+ */
78
+ declare function HeroSection({ title, subtitle, titleTextAlign, showTitle, titleSlot, showSearch, searchValue, onSearchChange, searchPlaceholder, searchSlot, showFilter, filterIcon, onFilterPress, filterAccessibilityLabel, filterSlot, children, modes: propModes, style, testID, }: HeroSectionProps): import("react/jsx-runtime").JSX.Element;
79
+ export default HeroSection;
80
+ //# sourceMappingURL=HeroSection.d.ts.map
@@ -1,6 +1,15 @@
1
1
  import React from 'react';
2
- import { type ImageSourcePropType, type ImageStyle, type StyleProp, type ViewStyle, type ImageResizeMode } from 'react-native';
2
+ import { type ImageSourcePropType, type ImageStyle, type StyleProp, type ViewStyle, type ImageResizeMode, type ImageLoadEventData, type ImageErrorEventData, type NativeSyntheticEvent } from 'react-native';
3
3
  type ImageResizeMethod = 'auto' | 'resize' | 'scale' | 'none';
4
+ /**
5
+ * iOS URL cache control (maps to RN's `source.cache`, no-op on Android/web):
6
+ * - `'default'` — use the native platform's default caching.
7
+ * - `'reload'` — ignore any cache, always fetch from the network.
8
+ * - `'force-cache'` — use the cached response regardless of age; fetch
9
+ * only if absent.
10
+ * - `'only-if-cached'` — use the cache only; never hit the network.
11
+ */
12
+ type ImageCacheControl = 'default' | 'reload' | 'force-cache' | 'only-if-cached';
4
13
  export type ImageProps = {
5
14
  /**
6
15
  * Image source. Accepts the same shapes as React Native's `<Image>` plus a
@@ -61,8 +70,24 @@ export type ImageProps = {
61
70
  * the group.
62
71
  */
63
72
  loading?: boolean | undefined;
73
+ /**
74
+ * iOS URL cache strategy applied to remote (`{ uri }`) sources. Injected into
75
+ * the RN `source.cache` field so callers don't have to re-shape the source
76
+ * object themselves. No-op for local/required assets and on Android/web.
77
+ */
78
+ cache?: ImageCacheControl | undefined;
79
+ /**
80
+ * Called when the image finishes loading successfully. Forwarded straight to
81
+ * RN's `<Image onLoad>`.
82
+ */
83
+ onLoad?: ((event: NativeSyntheticEvent<ImageLoadEventData>) => void) | undefined;
84
+ /**
85
+ * Called when the image fails to load. Forwarded straight to RN's
86
+ * `<Image onError>`.
87
+ */
88
+ onError?: ((event: NativeSyntheticEvent<ImageErrorEventData>) => void) | undefined;
64
89
  };
65
- declare function Image({ imageSource, ratio, resizeMode, resizeMethod, width, height, borderRadius, style, accessibilityLabel, accessibilityElementsHidden, importantForAccessibility, loading, }: ImageProps): import("react/jsx-runtime").JSX.Element;
90
+ declare function Image({ imageSource, ratio, resizeMode, resizeMethod, width, height, borderRadius, style, accessibilityLabel, accessibilityElementsHidden, importantForAccessibility, loading, cache, onLoad, onError, }: ImageProps): import("react/jsx-runtime").JSX.Element;
66
91
  declare const _default: React.MemoExoticComponent<typeof Image>;
67
92
  export default _default;
68
93
  //# sourceMappingURL=Image.d.ts.map
@@ -0,0 +1,73 @@
1
+ import React from 'react';
2
+ import { type TextStyle, type StyleProp, type GestureResponderEvent } from 'react-native';
3
+ import type { Modes } from '../../design-tokens';
4
+ export type LinkProps = {
5
+ /**
6
+ * The link label. You may also pass content as JSX children
7
+ * (e.g. `<Link>Terms</Link>`); when both are provided, `children` wins.
8
+ * Mirrors the {@link Text} API so `Link` is a near-drop-in, underlined
9
+ * sibling of `Text`.
10
+ */
11
+ text?: string;
12
+ /** Child nodes (string or nested `Text`/`Link`). Wins over `text`. */
13
+ children?: React.ReactNode;
14
+ /**
15
+ * Called when the link is activated. Navigation is the consumer's job
16
+ * (e.g. `Linking.openURL`, a router push) — `Link` is intentionally
17
+ * navigation-agnostic and React Native friendly (no `href`/`target`).
18
+ */
19
+ onPress?: (event: GestureResponderEvent) => void;
20
+ /** Disables interaction and dims the label. */
21
+ disabled?: boolean;
22
+ /**
23
+ * Layout sizing (matches the Figma `autolayout` variant).
24
+ * - `Fill` (default): the label stretches to fill the parent's width, so
25
+ * `textAlign="Center"` is visible and the whole line is tappable.
26
+ * - `Hug`: the label hugs its content width.
27
+ */
28
+ autolayout?: 'Fill' | 'Hug';
29
+ /** Horizontal alignment of the label (matches `Text`). */
30
+ textAlign?: 'Left' | 'Center';
31
+ /** Modes configuration for design token resolution (cascades from `TextSegment`). */
32
+ modes?: Modes;
33
+ /** Style override for the label. */
34
+ style?: StyleProp<TextStyle>;
35
+ /** Number of lines to limit the label to. */
36
+ numberOfLines?: number;
37
+ /** Never truncate — drops the clamp/ellipsis and lets the label overflow. See {@link Text}. */
38
+ disableTruncation?: boolean;
39
+ /** Force a single non-wrapping line (implies `disableTruncation`). See {@link Text}. */
40
+ singleLine?: boolean;
41
+ /** Accessibility label; defaults to the resolved text content. */
42
+ accessibilityLabel?: string;
43
+ /** Accessibility hint describing what activating the link does. */
44
+ accessibilityHint?: string;
45
+ };
46
+ /**
47
+ * Link — an underlined, pressable text primitive.
48
+ *
49
+ * It renders a single React Native `<Text>` (not a `Pressable`), so it flows
50
+ * inline and can be nested inside {@link TextSegment} exactly like a `Text`
51
+ * run — the React Native equivalent of an `<a>` inside a `<p>`. Font family,
52
+ * size, weight, line-height and letter-spacing come from the dedicated `link/*`
53
+ * tokens, while the colour resolves from `text/foreground` (so a link sits on
54
+ * the same colour as the surrounding copy). The label is always underlined.
55
+ *
56
+ * @example Standalone
57
+ * ```tsx
58
+ * <Link text="Forgot PIN?" onPress={() => navigation.navigate('ResetPin')} />
59
+ * ```
60
+ *
61
+ * @example Inline inside TextSegment
62
+ * ```tsx
63
+ * <TextSegment>
64
+ * <Text>By continuing you agree to our </Text>
65
+ * <Link onPress={openTerms}>Terms</Link>
66
+ * <Text>.</Text>
67
+ * </TextSegment>
68
+ * ```
69
+ */
70
+ declare function Link({ text, children, onPress, disabled, autolayout, textAlign, modes, style, numberOfLines, disableTruncation, singleLine, accessibilityLabel, accessibilityHint, }: LinkProps): import("react/jsx-runtime").JSX.Element;
71
+ declare const _default: React.MemoExoticComponent<typeof Link>;
72
+ export default _default;
73
+ //# sourceMappingURL=Link.d.ts.map
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewStyle, type TextStyle } from 'react-native';
3
+ import type { Modes } from '../../design-tokens';
4
+ export type MetricDataProps = {
5
+ /** Top label (small, 12px). Hidden when omitted. */
6
+ title?: string;
7
+ /**
8
+ * The prominent value (20px bold). Pass a string, or any node (e.g. a
9
+ * `MoneyValue`) to compose a richer value.
10
+ */
11
+ value?: string | React.ReactNode;
12
+ /** Sub-label below the value (12px, muted). Hidden when omitted. */
13
+ caption?: string;
14
+ /**
15
+ * Optional glyph shown to the left of the value. Pass a registry icon name
16
+ * (e.g. `'ic_card'`) or a custom node. Rendered at 18px, tinted to the value
17
+ * colour. Hidden when omitted.
18
+ */
19
+ icon?: string | React.ReactNode;
20
+ /** Design-token modes for theming. */
21
+ modes?: Modes;
22
+ /** Override the container styles. */
23
+ style?: StyleProp<ViewStyle>;
24
+ /** Override the title text styles. */
25
+ titleStyle?: StyleProp<TextStyle>;
26
+ /** Override the value text styles. */
27
+ valueStyle?: StyleProp<TextStyle>;
28
+ /** Override the caption text styles. */
29
+ captionStyle?: StyleProp<TextStyle>;
30
+ /**
31
+ * Accessibility label. Defaults to the resolved `title`, `value` and
32
+ * `caption` text joined together.
33
+ */
34
+ accessibilityLabel?: string;
35
+ };
36
+ /**
37
+ * MetricData — a compact, centered metric block.
38
+ *
39
+ * Stacks a small `title`, a prominent `value` (with an optional leading
40
+ * `icon`), and a muted `caption`. Typography, colours, gaps and padding all
41
+ * resolve from the `metricdata/*` design tokens. `title`, `caption` and `icon`
42
+ * are optional; only `value` is shown by default.
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * <MetricData title="Balance" value="₹1,20,000" caption="as of today" />
47
+ * <MetricData title="Cards" value="12" icon="ic_card" caption="active" />
48
+ * ```
49
+ */
50
+ declare function MetricData({ title, value, caption, icon, modes, style, titleStyle, valueStyle, captionStyle, accessibilityLabel, }: MetricDataProps): import("react/jsx-runtime").JSX.Element;
51
+ declare const _default: React.MemoExoticComponent<typeof MetricData>;
52
+ export default _default;
53
+ //# sourceMappingURL=MetricData.d.ts.map
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import { View, type StyleProp, type ViewStyle } from 'react-native';
3
+ import type { Modes } from '../../design-tokens';
4
+ export type RatingProps = {
5
+ /** Number of filled stars. Rounded to the nearest whole star for display. */
6
+ value?: number;
7
+ /** Total number of stars to render. */
8
+ max?: number;
9
+ /**
10
+ * Called with the new rating (1..max) when a star is pressed. Providing this
11
+ * makes the control interactive; omit it (or set `readOnly`) for a display.
12
+ */
13
+ onChange?: (value: number) => void;
14
+ /** Force a read-only display even when `onChange` is provided. */
15
+ readOnly?: boolean;
16
+ /** Override the star edge length. Defaults to the `ratingStar/width` token. */
17
+ starSize?: number;
18
+ /** Override the spacing between stars. Defaults to the `rating/gap` token. */
19
+ gap?: number;
20
+ /** Design token modes forwarded to token lookups. */
21
+ modes?: Modes;
22
+ /** Optional container style overrides. */
23
+ style?: StyleProp<ViewStyle>;
24
+ /** Accessibility label for the whole rating. Defaults to "X of Y stars". */
25
+ accessibilityLabel?: string;
26
+ } & Omit<React.ComponentProps<typeof View>, 'style'>;
27
+ declare function Rating({ value, max, onChange, readOnly, starSize, gap, modes: propModes, style, accessibilityLabel, ...rest }: RatingProps): import("react/jsx-runtime").JSX.Element;
28
+ declare const _default: React.MemoExoticComponent<typeof Rating>;
29
+ export default _default;
30
+ //# sourceMappingURL=Rating.d.ts.map
@@ -36,6 +36,7 @@ export { default as FullscreenModal, type FullscreenModalProps } from './Fullscr
36
36
  export { default as Form, type FormProps } from './Form/Form';
37
37
  export { useFormContext } from './Form/Form';
38
38
  export { default as FormField, type FormFieldProps, type FormFieldType } from './FormField/FormField';
39
+ export { default as ContentSheet, type ContentSheetProps } from './ContentSheet/ContentSheet';
39
40
  export { default as CircularProgressBar, type CircularProgressBarProps } from './CircularProgressBar/CircularProgressBar';
40
41
  export { default as CircularProgressBarDoted, type CircularProgressBarDotedProps } from './CircularProgressBarDoted/CircularProgressBarDoted';
41
42
  export { default as CircularRating, type CircularRatingProps } from './CircularRating/CircularRating';
@@ -45,6 +46,7 @@ export { default as ComparisonBar, type ComparisonBarProps, type ComparisonBarIt
45
46
  export { default as AllocationComparisonChart, type AllocationComparisonChartProps, type AllocationSegment } from './AllocationComparisonChart/AllocationComparisonChart';
46
47
  export { default as MonthlyStatusGrid, CalendarGlyph, type MonthlyStatusGridProps, type MonthlyStatusGridMonth, type MonthlyStatus, type CalendarGlyphProps } from './MonthlyStatusGrid/MonthlyStatusGrid';
47
48
  export { default as Gauge, type GaugeProps } from './Gauge/Gauge';
49
+ export { default as HeroSection, type HeroSectionProps } from './HeroSection/HeroSection';
48
50
  export { default as HoldingsCard, type HoldingsCardProps } from './HoldingsCard/HoldingsCard';
49
51
  export { default as HStack, type HStackProps } from './HStack/HStack';
50
52
  export { default as Icon, type IconProps } from './Icon/Icon';
@@ -52,6 +54,7 @@ export { default as IconButton } from './IconButton/IconButton';
52
54
  export { default as IconCapsule } from './IconCapsule/IconCapsule';
53
55
  export { default as Image, type ImageProps } from './Image/Image';
54
56
  export { default as LazyList } from './LazyList/LazyList';
57
+ export { default as Link, type LinkProps } from './Link/Link';
55
58
  export { default as LinearMeter, type LinearMeterProps } from './LinearMeter/LinearMeter';
56
59
  export { default as LinearProgress, type LinearProgressProps } from './LinearProgress/LinearProgress';
57
60
  export { default as ListGroup } from './ListGroup/ListGroup';
@@ -78,6 +78,7 @@ export declare const FIGMA_MODES: {
78
78
  readonly "contentInset/Right": readonly ["Default", "S", "M", "L"];
79
79
  readonly "ContentSheet / Output": readonly ["Default"];
80
80
  readonly Context: readonly ["Default", "Nudge&Alert", "CTACard", "ListItem"];
81
+ readonly "context 10": readonly ["Default", "Profile card"];
81
82
  readonly "context 8": readonly ["Default", "Section"];
82
83
  readonly "context 9": readonly ["Default", "Stack"];
83
84
  readonly Context2: readonly ["Default", "AppBar"];
@@ -116,6 +117,7 @@ export declare const FIGMA_MODES: {
116
117
  readonly FullScreenModal: readonly ["Default"];
117
118
  readonly Gap: readonly ["S", "M", "L", "None"];
118
119
  readonly "Gauge / Output": readonly ["Default"];
120
+ readonly "Grid / Output": readonly ["Default"];
119
121
  readonly "Handle Boolean": readonly ["False", "True"];
120
122
  readonly "Heading / Output": readonly ["Default"];
121
123
  readonly "Heading text": readonly ["Default", "Slot"];
@@ -139,6 +141,7 @@ export declare const FIGMA_MODES: {
139
141
  readonly "LinearProgress / Output": readonly ["Default"];
140
142
  readonly "LinearProgress Size": readonly ["M", "L"];
141
143
  readonly "Link / Output": readonly ["Default"];
144
+ readonly "Link Apperances": readonly ["Neutral", "Primary", "Secondary", "Tertiary"];
142
145
  readonly "List Item / Output": readonly ["Default"];
143
146
  readonly "List Item Style": readonly ["Default", "Boxed", "Minimal"];
144
147
  readonly "listGroup / Output": readonly ["Default"];
@@ -157,6 +160,7 @@ export declare const FIGMA_MODES: {
157
160
  readonly NavArrow: readonly ["Default"];
158
161
  readonly "NavArrow / Output": readonly ["Default"];
159
162
  readonly "NavArrow Direction": readonly ["Left&Right", "Top&Bottom"];
163
+ readonly "New Collection": readonly ["Default"];
160
164
  readonly "NoteInput / Output": readonly ["Default"];
161
165
  readonly "Nudge / Output": readonly ["Default"];
162
166
  readonly "Nudge padding": readonly ["Default", "None"];
@@ -178,12 +182,16 @@ export declare const FIGMA_MODES: {
178
182
  readonly "Product Merchandising card": readonly ["Default"];
179
183
  readonly "ProductLabel / Output": readonly ["Default"];
180
184
  readonly "ProductOverview / Output": readonly ["Default"];
185
+ readonly "Profile Card Appearance": readonly ["Default", "Premium"];
181
186
  readonly "ProgressBadge / Output": readonly ["Default"];
182
187
  readonly ProjectionMarker: readonly ["Default"];
183
188
  readonly "QR code / Output": readonly ["Idle"];
184
189
  readonly "Radio / Output": readonly ["Default"];
185
190
  readonly Radius: readonly ["S", "M", "L", "None"];
186
191
  readonly "RangeTrack / Output": readonly ["Default"];
192
+ readonly "Rating / Output": readonly ["Default"];
193
+ readonly "Rating Star / Output": readonly ["Default"];
194
+ readonly "Rating Star State": readonly ["idle", "selected"];
187
195
  readonly "RechargeCard / Output": readonly ["Default"];
188
196
  readonly rotfl: readonly ["Default"];
189
197
  readonly "SavingsGoalSummary / Output": readonly ["Default"];
@@ -4,7 +4,7 @@
4
4
  * Auto-generated from SVG files in src/icons/
5
5
  * DO NOT EDIT MANUALLY - Run "npm run icons:generate" to regenerate
6
6
  *
7
- * Generated: 2026-06-29T11:40:01.320Z
7
+ * Generated: 2026-07-03T01:43:10.333Z
8
8
  */
9
9
  export declare const iconRegistry: Record<string, {
10
10
  path: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jfs-components",
3
- "version": "0.1.19",
3
+ "version": "0.1.25",
4
4
  "description": "React Native Jio Finance Components Library",
5
5
  "author": "sunshuaiqi@gmail.com",
6
6
  "license": "MIT",
@@ -281,22 +281,37 @@ function CardCTA({
281
281
  zIndex: 1,
282
282
  }
283
283
 
284
- // NOTE: rightWrap must NOT shrink on native. On Android (Yoga), the default
285
- // `flex: 2` shorthand expands to `{ flexGrow: 2, flexShrink: 1, flexBasis: 0 }`,
286
- // which combined with `minWidth: 0` lets Yoga shrink this wrapper below
287
- // its own padding+IconCapsule width when leftWrap's text is long. Once that
288
- // happens the horizontal padding collapses, `alignItems: 'flex-end'` pins
289
- // the IconCapsule against the inner edge, and the icon ends up visually
290
- // touching the body text (the wrapper "appears not to exist"). Web hides
291
- // this because browsers honor `min-width: auto` on flex items. Use
292
- // explicit `flexGrow`/`flexShrink: 0`/`flexBasis: 'auto'` so the wrapper
293
- // is sized to its content as a floor and only grows for the design's
294
- // 3:2 ratio when extra space is available. leftWrap already absorbs tight
295
- // space via `flexShrink: 1` + `minWidth: 0`.
284
+ // NOTE: rightWrap must implement the design's TRUE `2fr` column.
285
+ //
286
+ // History of this styletwo Yoga pitfalls pull in opposite directions:
287
+ //
288
+ // 1. `flex: 2` (=> flexBasis: 0, flexShrink: 1): on Android, Yoga could
289
+ // shrink the wrapper below its padding+IconCapsule width when the left
290
+ // text was long, collapsing the padding and gluing the icon to the
291
+ // text. Browsers hide this because they honor `min-width: auto`; Yoga
292
+ // always treats min-width as 0 unless told otherwise.
293
+ // 2. The previous workaround, `flexBasis: 'auto'` + `flexGrow: 2`, fixed
294
+ // #1 but broke the column ratio: Yoga then sizes the wrapper to its
295
+ // content FIRST (icon + padding) and distributes only the leftover
296
+ // space 3:2. The icon width gets baked in on top of the 2fr share, so
297
+ // the right column ends up much wider than the design's 2fr and the
298
+ // body text wraps early with dead space to its right.
299
+ //
300
+ // Fundamental fix: keep the genuine fr-unit geometry (`flexBasis: 0`,
301
+ // grow 3:2, no shrink) and replace Yoga's missing `min-width: auto` with
302
+ // an explicit computed floor — the resolved IconCapsule size plus the
303
+ // wrapper's own horizontal padding. The column is exactly 2fr whenever
304
+ // space allows and can never collapse below its content.
305
+ const iconCapsuleModes = { ...modes, 'IconCapsule / Size': 'M', Emphasis: 'Medium', AppearanceBrand: 'Secondary' }
306
+ const rightWrapMinWidth =
307
+ ((getVariableByName('iconCapsule/size', iconCapsuleModes) as number) || 0) +
308
+ ((rightPaddingH as number) || 0) * 2
309
+
296
310
  const rightWrapStyle: ViewStyle = {
297
311
  flexGrow: 2,
298
312
  flexShrink: 0,
299
- flexBasis: 'auto',
313
+ flexBasis: 0,
314
+ minWidth: rightWrapMinWidth,
300
315
  paddingHorizontal: rightPaddingH,
301
316
  paddingVertical: rightPaddingV,
302
317
  alignItems: 'flex-end',
@@ -555,9 +570,9 @@ function CardCTA({
555
570
  </View>
556
571
  <View style={rightWrapStyle}>
557
572
  {iconSlot ? (
558
- cloneChildrenWithModes(iconSlot, {...modes, 'IconCapsule / Size': 'M',Emphasis: 'Medium', AppearanceBrand: 'Secondary'})
573
+ cloneChildrenWithModes(iconSlot, iconCapsuleModes)
559
574
  ) : (
560
- <IconCapsule iconName={iconName} modes={{...modes, 'IconCapsule / Size': 'M',Emphasis: 'Medium', AppearanceBrand: 'Secondary'}} />
575
+ <IconCapsule iconName={iconName} modes={iconCapsuleModes} />
561
576
  )}
562
577
  </View>
563
578
  </View>