jfs-components 0.0.85 → 0.0.95

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 (28) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/lib/commonjs/assets.d.js +1 -0
  3. package/lib/commonjs/components/AllocationComparisonChart/AllocationComparisonChart.js +299 -0
  4. package/lib/commonjs/components/FullscreenModal/FullscreenModal.js +104 -94
  5. package/lib/commonjs/components/Icon/Icon.js +112 -0
  6. package/lib/commonjs/components/index.js +14 -0
  7. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  8. package/lib/commonjs/icons/registry.js +1 -1
  9. package/lib/module/assets.d.js +1 -0
  10. package/lib/module/components/AllocationComparisonChart/AllocationComparisonChart.js +293 -0
  11. package/lib/module/components/FullscreenModal/FullscreenModal.js +106 -96
  12. package/lib/module/components/Icon/Icon.js +106 -0
  13. package/lib/module/components/index.js +2 -0
  14. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  15. package/lib/module/icons/registry.js +1 -1
  16. package/lib/typescript/src/components/AllocationComparisonChart/AllocationComparisonChart.d.ts +118 -0
  17. package/lib/typescript/src/components/FullscreenModal/FullscreenModal.d.ts +39 -29
  18. package/lib/typescript/src/components/Icon/Icon.d.ts +75 -0
  19. package/lib/typescript/src/components/index.d.ts +2 -0
  20. package/lib/typescript/src/icons/registry.d.ts +1 -1
  21. package/package.json +1 -1
  22. package/src/assets.d.ts +24 -0
  23. package/src/components/AllocationComparisonChart/AllocationComparisonChart.tsx +450 -0
  24. package/src/components/FullscreenModal/FullscreenModal.tsx +131 -126
  25. package/src/components/Icon/Icon.tsx +167 -0
  26. package/src/components/index.ts +2 -0
  27. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  28. package/src/icons/registry.ts +1 -1
@@ -0,0 +1,118 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ /**
4
+ * One vertical pill in the {@link AllocationComparisonChartProps.data} array.
5
+ *
6
+ * Each segment renders a single bar whose **height encodes `value`** (the
7
+ * "current" reading) and, when supplied, a **`baseline`** overlay drawn from
8
+ * the bottom up with a dashed marker line (the "recommended" reading). Both
9
+ * are measured against the same shared scale so bars and baselines are
10
+ * directly comparable across segments.
11
+ */
12
+ export type AllocationSegment = {
13
+ /** Stable React key (falls back to the array index). */
14
+ key?: React.Key;
15
+ /** Caption rendered under the bar — e.g. `"Small & Mid"`. */
16
+ label: React.ReactNode;
17
+ /**
18
+ * Primary value driving the bar's height (the "current" reading). Scaled
19
+ * against {@link AllocationComparisonChartProps.max}.
20
+ */
21
+ value: number;
22
+ /**
23
+ * Optional comparison value (the "recommended" reading). When provided, a
24
+ * filled overlay is drawn from the bottom of the bar up to this level.
25
+ * Omit to render a plain bar.
26
+ */
27
+ baseline?: number;
28
+ /**
29
+ * Whether to draw the dashed reference line + value label at the top of the
30
+ * `baseline` overlay. Defaults to `true` **only for the first segment that
31
+ * has a `baseline`** and `false` for the rest, so the marker stays a
32
+ * focused callout rather than repeating on every bar. Set explicitly to
33
+ * force it on/off per segment. Has no effect without a `baseline`.
34
+ */
35
+ showMarker?: boolean;
36
+ /**
37
+ * Text shown above the bar. Defaults to `formatValue(value)`. Pass `null`
38
+ * to hide it.
39
+ */
40
+ valueLabel?: React.ReactNode;
41
+ /**
42
+ * Text shown beside the dashed baseline marker. Defaults to
43
+ * `formatValue(baseline)`. Pass `null` to hide just the marker label while
44
+ * keeping the dashed line.
45
+ */
46
+ baselineLabel?: React.ReactNode;
47
+ /** Hard-override the bar (current) fill color. */
48
+ color?: string;
49
+ /** Hard-override the baseline (recommended) overlay color. */
50
+ baselineColor?: string;
51
+ /** Per-segment accessibility label. */
52
+ accessibilityLabel?: string;
53
+ };
54
+ export type AllocationComparisonChartProps = {
55
+ /**
56
+ * The segments to plot, left → right. Each carries its `value`, optional
57
+ * `baseline` and its `label`, so a bar can never drift from its caption.
58
+ */
59
+ data?: AllocationSegment[];
60
+ /**
61
+ * Maximum value used to scale every bar **and** baseline. Defaults to the
62
+ * largest `value`/`baseline` across `data`. Pass an explicit `max` (e.g.
63
+ * `100` for percentages) for a fixed scale.
64
+ */
65
+ max?: number;
66
+ /**
67
+ * Height in px of the bar area — i.e. the height of a bar whose value
68
+ * equals `max`. Excludes the value/caption label rows. Default: `154`.
69
+ */
70
+ height?: number;
71
+ /** Width of each pill bar in px. Default: the `segmentIndicator/track/width` token (`28`). */
72
+ barWidth?: number;
73
+ /** Show the legend row above the chart. Default: `true`. */
74
+ showLegend?: boolean;
75
+ /** Legend label for the bar (current) series. Default: `"Current"`. */
76
+ valueLegendLabel?: React.ReactNode;
77
+ /**
78
+ * Legend label for the baseline (recommended) series. Default:
79
+ * `"Recommended"`. The baseline legend item only appears when at least one
80
+ * segment defines a `baseline`.
81
+ */
82
+ baselineLegendLabel?: React.ReactNode;
83
+ /**
84
+ * Formats numeric `value`/`baseline` into the default labels. Default:
85
+ * `(v) => \`${v}%\``.
86
+ */
87
+ formatValue?: (value: number) => string;
88
+ /** Design token modes for theming (e.g. `{ 'Color Mode': 'Light' }`). */
89
+ modes?: Record<string, any>;
90
+ /** Container style override. */
91
+ style?: StyleProp<ViewStyle>;
92
+ /** Style applied to the bars row. */
93
+ chartStyle?: StyleProp<ViewStyle>;
94
+ /** Style applied to the legend row. */
95
+ legendStyle?: StyleProp<ViewStyle>;
96
+ /** Accessibility label for the whole chart. */
97
+ accessibilityLabel?: string;
98
+ };
99
+ /**
100
+ * `AllocationComparisonChart` plots a row of vertical pill bars that compare a
101
+ * **current** reading (each bar's height) against an optional **recommended**
102
+ * baseline (a filled overlay drawn from the bottom up, marked with a dashed
103
+ * line). Every bar and baseline shares a single scale, so heights are directly
104
+ * comparable across segments — no axes required.
105
+ *
106
+ * The chart is driven entirely by the `data` array: each entry pairs a
107
+ * `value`, an optional `baseline` and its `label`, so a bar can never drift
108
+ * out of sync with its caption or its baseline marker.
109
+ *
110
+ * Colors, fonts, spacing and the pill radius resolve from the Figma
111
+ * `segmentIndicator/*`, `metricLegendItem/*` and `allocationComparisonChart/*`
112
+ * tokens via the `modes` prop.
113
+ *
114
+ * @component
115
+ */
116
+ declare function AllocationComparisonChart({ data, max, height, barWidth, showLegend, valueLegendLabel, baselineLegendLabel, formatValue, modes: propModes, style, chartStyle, legendStyle, accessibilityLabel, }: AllocationComparisonChartProps): import("react/jsx-runtime").JSX.Element;
117
+ export default AllocationComparisonChart;
118
+ //# sourceMappingURL=AllocationComparisonChart.d.ts.map
@@ -10,23 +10,23 @@ export type FullscreenModalProps = {
10
10
  /** Secondary line below the supporting paragraph (e.g. a price / timeline). */
11
11
  priceText?: string;
12
12
  /**
13
- * Media rendered full-bleed behind the hero text and driven by the parallax
14
- * scroll effect. Bring any renderer most commonly a `LottiePlayer`, but an
15
- * `Image`, `Video`, or `SvgXml` works too. Size it to fill the hero box
16
- * (`heroHeight` tall, full modal width) and let it `cover` so that as the
17
- * hero collapses in height the art is cropped, never distorted. `modes` are
18
- * cascaded into it.
13
+ * Full-bleed background media for the whole modal. It is pinned to the top
14
+ * and laid out at the full modal width; size it with an aspect ratio
15
+ * (e.g. `<Image ratio={1080 / 4140} />`) so its height follows the width
16
+ * naturally. It renders as a single continuous background BEHIND both the
17
+ * hero text and the body content — there is no separate body box stacked on
18
+ * top of it. Bring any renderer — most commonly an `Image`, but a
19
+ * `LottiePlayer`, `Video`, or `SvgXml` works too. It never intercepts
20
+ * touches and the foreground content scrolls over it (no parallax).
21
+ * `modes` are cascaded into it.
19
22
  */
20
23
  heroMedia?: React.ReactNode;
21
- /** Resting height of the hero region. Defaults to 420. */
22
- heroHeight?: number;
23
24
  /**
24
- * Collapsed height the hero shrinks to at full scroll. Defaults to
25
- * `heroHeight * 0.45`. Only the height changes the width is always full.
25
+ * Height reserved for the hero text region (eyebrow / headline / supporting
26
+ * / price), whose content is anchored to the bottom. Applies whether or not
27
+ * `heroMedia` is present. Defaults to 420.
26
28
  */
27
- heroMinHeight?: number;
28
- /** Enable the scroll-driven hero collapse. Defaults to true. */
29
- parallax?: boolean;
29
+ heroHeight?: number;
30
30
  /** Whether to render the floating close button (top-right). Defaults to true. */
31
31
  showClose?: boolean;
32
32
  /** Press handler for the close button. */
@@ -44,21 +44,24 @@ export type FullscreenModalProps = {
44
44
  onPrimaryAction?: () => void;
45
45
  /** Disclaimer text shown below the default primary action button. */
46
46
  disclaimer?: string;
47
- /** Solid backdrop color for the scrollable body. Defaults to a near-black. */
48
- backgroundColor?: string;
49
47
  /** Body content (typically `Section`s). `modes` are cascaded automatically. */
50
48
  children?: React.ReactNode;
51
- /** Mode configuration. `context5` is always forced to `'Fullscreen Modal'`. */
49
+ /**
50
+ * Mode configuration. `Page type` defaults to `'JioPlus'` (overridable here),
51
+ * and `context5` is always forced to `'Fullscreen Modal'` (non-overridable).
52
+ * The resolved modes cascade to the body, hero media, and the `ActionFooter`.
53
+ */
52
54
  modes?: Record<string, any>;
53
55
  /** Style overrides for the outer container. */
54
56
  style?: StyleProp<ViewStyle>;
55
- /** Style overrides for the scroll body wrapper (the dark content area). */
57
+ /** Style overrides for the transparent body wrapper. */
56
58
  contentContainerStyle?: StyleProp<ViewStyle>;
57
59
  testID?: string;
58
60
  };
59
61
  /**
60
- * FullscreenModal — a full-screen takeover surface with a parallax media hero,
61
- * a scrollable body, a floating close button, and a sticky `ActionFooter`.
62
+ * FullscreenModal — a full-screen takeover surface with a full-bleed media
63
+ * hero, a scrollable body, a floating close button, and a sticky
64
+ * `ActionFooter`.
62
65
  *
63
66
  * The component always themes itself with `context5: 'Fullscreen Modal'`
64
67
  * (non-overridable) so every nested component (Section, ListItem, Button,
@@ -66,14 +69,21 @@ export type FullscreenModalProps = {
66
69
  * That mode is cascaded into `children`, the footer, and the hero text via
67
70
  * `cloneChildrenWithModes` / the merged `modes` object.
68
71
  *
69
- * ### Parallax
70
- * As the user scrolls up, the hero collapses by **height only** (from
71
- * `heroHeight` to `heroMinHeight`) its **full width is always preserved**.
72
- * The `heroMedia` is pinned to the top at a fixed size and `cover`-cropped by
73
- * the collapsing clip, so it keeps a perfect aspect ratio the whole time
74
- * (never scaled or squished). Because it collapses slower than the content
75
- * scrolls, the media lags behind for the parallax depth cue. Disable with
76
- * `parallax={false}`.
72
+ * ### Background media
73
+ * The `heroMedia` is a single full-bleed background pinned to the top of the
74
+ * modal at the full width and its own natural aspect ratio. It lives at the
75
+ * ROOT behind both the scrolling content and the (transparent) footer so
76
+ * it fills the whole surface and is NEVER clipped to the content height. It
77
+ * also contributes ZERO scroll height: the scroll extent is driven purely by
78
+ * the in-flow foreground (hero text + `children`), so the number of body
79
+ * elements dictates how far the surface scrolls. It still scrolls in lockstep
80
+ * WITH the content (the background is translated by the scroll offset), so the
81
+ * content reads as sitting ON one continuous image that moves with it — there
82
+ * is no parallax and no separate solid body box.
83
+ *
84
+ * Pass a background sized to the full width at its natural ratio
85
+ * (e.g. `<Image imageSource={bg} ratio={1080 / 4140} />`). Use an asset at
86
+ * least as tall as the surface so it covers the full modal.
77
87
  *
78
88
  * @component
79
89
  * @example
@@ -83,7 +93,7 @@ export type FullscreenModalProps = {
83
93
  * headline="Get more from your money."
84
94
  * supportingText="JioFinance+ is your upgraded financial experience…"
85
95
  * priceText="₹999/year · ₹0 until 2027"
86
- * heroMedia={<LottiePlayer source={hero} size={{ width: 360, height: 420 }} />}
96
+ * heroMedia={<Image imageSource={hero} ratio={1080 / 4140} />}
87
97
  * primaryActionLabel="Upgrade for free"
88
98
  * disclaimer="By upgrading, we'll check your eligibility with Experian."
89
99
  * onPrimaryAction={() => upgrade()}
@@ -94,6 +104,6 @@ export type FullscreenModalProps = {
94
104
  * </FullscreenModal>
95
105
  * ```
96
106
  */
97
- declare function FullscreenModal({ eyebrow, headline, supportingText, priceText, heroMedia, heroHeight, heroMinHeight, parallax, showClose, onClose, closeAccessibilityLabel, footer, primaryActionLabel, onPrimaryAction, disclaimer, backgroundColor, children, modes: propModes, style, contentContainerStyle, testID, }: FullscreenModalProps): import("react/jsx-runtime").JSX.Element;
107
+ declare function FullscreenModal({ eyebrow, headline, supportingText, priceText, heroMedia, heroHeight, showClose, onClose, closeAccessibilityLabel, footer, primaryActionLabel, onPrimaryAction, disclaimer, children, modes: propModes, style, contentContainerStyle, testID, }: FullscreenModalProps): import("react/jsx-runtime").JSX.Element;
98
108
  export default FullscreenModal;
99
109
  //# sourceMappingURL=FullscreenModal.d.ts.map
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import { type AccessibilityProps, type StyleProp, type ViewStyle } from 'react-native';
3
+ import type { UnifiedSource } from '../../utils/MediaSource';
4
+ type IconProps = AccessibilityProps & {
5
+ /**
6
+ * Built-in icon name from the registry, in the `ic_something` format
7
+ * (e.g. `'ic_card'`, `'ic_scan_qr_code'`). When omitted and no `source` or
8
+ * `children` slot is supplied, defaults to `'ic_card'` to match the Figma
9
+ * design's default glyph.
10
+ */
11
+ iconName?: string;
12
+ /**
13
+ * Unified fallback source rendered when `iconName` is missing or not in the
14
+ * registry. Accepts a remote URI, an inline SVG XML string, a `require()`
15
+ * asset, an SVG React component, or an already-rendered element. The media
16
+ * is tinted with the mode-resolved icon color so it follows design tokens
17
+ * just like a built-in icon. See {@link UnifiedSource}.
18
+ */
19
+ source?: UnifiedSource;
20
+ /**
21
+ * Icon slot. Render any node here (another `Icon`, a custom SVG component,
22
+ * etc.) and it takes precedence over `iconName`/`source`. `modes` cascade
23
+ * into the slotted children automatically.
24
+ */
25
+ children?: React.ReactNode;
26
+ /**
27
+ * Override the mode-resolved icon color. When omitted the value comes from
28
+ * the `icon/color` design token.
29
+ */
30
+ color?: string;
31
+ /**
32
+ * Override the mode-resolved icon size (in px). When omitted the value comes
33
+ * from the `icon/size` design token.
34
+ */
35
+ size?: number;
36
+ modes?: Record<string, any>;
37
+ style?: StyleProp<ViewStyle>;
38
+ };
39
+ /**
40
+ * Icon component — a design-token-driven wrapper around a single glyph.
41
+ *
42
+ * It mirrors the Figma "Icon" component: a padded, centered container whose
43
+ * color and size are resolved from the `icon/*` design tokens via `modes`.
44
+ * The glyph itself can be supplied three ways, in order of precedence:
45
+ *
46
+ * 1. `children` — a real slot for any node (custom SVG component, nested
47
+ * `Icon`, etc.). `modes` cascade into the slot automatically.
48
+ * 2. `iconName` — a registry icon in the `ic_something` format.
49
+ * 3. `source` — a {@link UnifiedSource} fallback (remote URI, inline SVG XML,
50
+ * `require()` asset, SVG component, or React element), tinted with the
51
+ * mode-resolved icon color.
52
+ *
53
+ * `color` and `size` props let consumers override the token values per
54
+ * instance without touching `modes`.
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * // Built-in registry icon (default path).
59
+ * <Icon iconName="ic_card" modes={{ 'Color Mode': 'Light' }} />
60
+ *
61
+ * // Per-instance overrides.
62
+ * <Icon iconName="ic_ccv" color="#5c00b5" size={24} />
63
+ *
64
+ * // Fallback to an external source when the name isn't in the registry.
65
+ * <Icon source="https://cdn.example.com/glyph.svg" />
66
+ *
67
+ * // Slot: render any node as the icon.
68
+ * <Icon><BrandLogo /></Icon>
69
+ * ```
70
+ */
71
+ declare function Icon({ iconName, source, children, color, size, modes: propModes, style: styleProp, ...rest }: IconProps): import("react/jsx-runtime").JSX.Element;
72
+ declare const _default: React.MemoExoticComponent<typeof Icon>;
73
+ export default _default;
74
+ export type { IconProps };
75
+ //# sourceMappingURL=Icon.d.ts.map
@@ -38,10 +38,12 @@ export { default as CircularProgressBarDoted, type CircularProgressBarDotedProps
38
38
  export { default as CircularRating, type CircularRatingProps } from './CircularRating/CircularRating';
39
39
  export { default as CoverageRing, type CoverageRingProps } from './CoverageRing/CoverageRing';
40
40
  export { default as CoverageBarComparison, type CoverageBarComparisonProps, type CoverageBarComparisonItem } from './CoverageBarComparison/CoverageBarComparison';
41
+ export { default as AllocationComparisonChart, type AllocationComparisonChartProps, type AllocationSegment } from './AllocationComparisonChart/AllocationComparisonChart';
41
42
  export { default as MonthlyStatusGrid, CalendarGlyph, type MonthlyStatusGridProps, type MonthlyStatusGridMonth, type MonthlyStatus, type CalendarGlyphProps } from './MonthlyStatusGrid/MonthlyStatusGrid';
42
43
  export { default as Gauge, type GaugeProps } from './Gauge/Gauge';
43
44
  export { default as HoldingsCard, type HoldingsCardProps } from './HoldingsCard/HoldingsCard';
44
45
  export { default as HStack, type HStackProps } from './HStack/HStack';
46
+ export { default as Icon, type IconProps } from './Icon/Icon';
45
47
  export { default as IconButton } from './IconButton/IconButton';
46
48
  export { default as IconCapsule } from './IconCapsule/IconCapsule';
47
49
  export { default as Image, type ImageProps } from './Image/Image';
@@ -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-02T15:42:11.888Z
7
+ * Generated: 2026-06-04T14:40:09.533Z
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.0.85",
3
+ "version": "0.0.95",
4
4
  "description": "React Native Jio Finance Components Library",
5
5
  "author": "sunshuaiqi@gmail.com",
6
6
  "license": "MIT",
@@ -0,0 +1,24 @@
1
+ declare module '*.png' {
2
+ const value: string
3
+ export default value
4
+ }
5
+
6
+ declare module '*.jpg' {
7
+ const value: string
8
+ export default value
9
+ }
10
+
11
+ declare module '*.jpeg' {
12
+ const value: string
13
+ export default value
14
+ }
15
+
16
+ declare module '*.gif' {
17
+ const value: string
18
+ export default value
19
+ }
20
+
21
+ declare module '*.webp' {
22
+ const value: string
23
+ export default value
24
+ }