jfs-components 0.0.74 → 0.0.78

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 (146) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/lib/commonjs/components/Accordion/Accordion.js +55 -55
  3. package/lib/commonjs/components/ActionFooter/ActionFooter.js +193 -82
  4. package/lib/commonjs/components/Avatar/Avatar.js +20 -0
  5. package/lib/commonjs/components/Badge/Badge.js +23 -0
  6. package/lib/commonjs/components/Button/Button.js +37 -0
  7. package/lib/commonjs/components/Checkbox/Checkbox.js +21 -9
  8. package/lib/commonjs/components/DropdownInput/DropdownInput.js +30 -16
  9. package/lib/commonjs/components/ExpandableCheckbox/ExpandableCheckbox.js +167 -0
  10. package/lib/commonjs/components/FormField/FormField.js +14 -1
  11. package/lib/commonjs/components/FullscreenModal/FullscreenModal.js +355 -0
  12. package/lib/commonjs/components/IconButton/IconButton.js +20 -0
  13. package/lib/commonjs/components/Image/Image.js +26 -1
  14. package/lib/commonjs/components/ListItem/ListItem.js +25 -10
  15. package/lib/commonjs/components/LottiePlayer/LottiePlayer.js +116 -0
  16. package/lib/commonjs/components/LottiePlayer/LottiePlayer.web.js +82 -0
  17. package/lib/commonjs/components/LottiePlayer/loadNativeLottieView.js +74 -0
  18. package/lib/commonjs/components/LottiePlayer/loadWebLottieView.js +50 -0
  19. package/lib/commonjs/components/MessageField/MessageField.js +318 -0
  20. package/lib/commonjs/components/NavArrow/NavArrow.js +58 -17
  21. package/lib/commonjs/components/PageHero/PageHero.js +41 -5
  22. package/lib/commonjs/components/RechargeCard/RechargeCard.js +32 -17
  23. package/lib/commonjs/components/Stepper/Step.js +47 -60
  24. package/lib/commonjs/components/Stepper/StepLabel.js +40 -10
  25. package/lib/commonjs/components/Stepper/Stepper.js +15 -17
  26. package/lib/commonjs/components/SuggestiveSearch/SuggestiveSearch.js +487 -0
  27. package/lib/commonjs/components/Text/Text.js +31 -1
  28. package/lib/commonjs/components/TextInput/TextInput.js +16 -1
  29. package/lib/commonjs/components/Title/Title.js +10 -2
  30. package/lib/commonjs/components/index.js +35 -0
  31. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  32. package/lib/commonjs/icons/Icon.js +16 -0
  33. package/lib/commonjs/icons/registry.js +1 -1
  34. package/lib/commonjs/index.js +12 -0
  35. package/lib/commonjs/skeleton/Skeleton.js +234 -0
  36. package/lib/commonjs/skeleton/SkeletonGroup.js +140 -0
  37. package/lib/commonjs/skeleton/index.js +58 -0
  38. package/lib/commonjs/skeleton/shimmer-tokens.js +189 -0
  39. package/lib/commonjs/skeleton/useReducedMotion.js +64 -0
  40. package/lib/module/components/Accordion/Accordion.js +56 -56
  41. package/lib/module/components/ActionFooter/ActionFooter.js +193 -83
  42. package/lib/module/components/Avatar/Avatar.js +19 -0
  43. package/lib/module/components/Badge/Badge.js +23 -0
  44. package/lib/module/components/Button/Button.js +37 -0
  45. package/lib/module/components/Checkbox/Checkbox.js +22 -10
  46. package/lib/module/components/DropdownInput/DropdownInput.js +30 -16
  47. package/lib/module/components/ExpandableCheckbox/ExpandableCheckbox.js +161 -0
  48. package/lib/module/components/FormField/FormField.js +16 -3
  49. package/lib/module/components/FullscreenModal/FullscreenModal.js +350 -0
  50. package/lib/module/components/IconButton/IconButton.js +20 -0
  51. package/lib/module/components/Image/Image.js +25 -1
  52. package/lib/module/components/ListItem/ListItem.js +25 -10
  53. package/lib/module/components/LottiePlayer/LottiePlayer.js +111 -0
  54. package/lib/module/components/LottiePlayer/LottiePlayer.web.js +77 -0
  55. package/lib/module/components/LottiePlayer/loadNativeLottieView.js +69 -0
  56. package/lib/module/components/LottiePlayer/loadWebLottieView.js +45 -0
  57. package/lib/module/components/MessageField/MessageField.js +313 -0
  58. package/lib/module/components/NavArrow/NavArrow.js +59 -18
  59. package/lib/module/components/PageHero/PageHero.js +41 -5
  60. package/lib/module/components/RechargeCard/RechargeCard.js +33 -17
  61. package/lib/module/components/Stepper/Step.js +48 -61
  62. package/lib/module/components/Stepper/StepLabel.js +40 -10
  63. package/lib/module/components/Stepper/Stepper.js +15 -17
  64. package/lib/module/components/SuggestiveSearch/SuggestiveSearch.js +481 -0
  65. package/lib/module/components/Text/Text.js +31 -1
  66. package/lib/module/components/TextInput/TextInput.js +17 -2
  67. package/lib/module/components/Title/Title.js +10 -2
  68. package/lib/module/components/index.js +5 -0
  69. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  70. package/lib/module/icons/Icon.js +16 -0
  71. package/lib/module/icons/registry.js +1 -1
  72. package/lib/module/index.js +2 -1
  73. package/lib/module/skeleton/Skeleton.js +229 -0
  74. package/lib/module/skeleton/SkeletonGroup.js +133 -0
  75. package/lib/module/skeleton/index.js +6 -0
  76. package/lib/module/skeleton/shimmer-tokens.js +181 -0
  77. package/lib/module/skeleton/useReducedMotion.js +61 -0
  78. package/lib/typescript/src/components/Accordion/Accordion.d.ts +14 -20
  79. package/lib/typescript/src/components/ActionFooter/ActionFooter.d.ts +26 -21
  80. package/lib/typescript/src/components/Avatar/Avatar.d.ts +7 -1
  81. package/lib/typescript/src/components/Badge/Badge.d.ts +7 -1
  82. package/lib/typescript/src/components/Button/Button.d.ts +8 -1
  83. package/lib/typescript/src/components/ExpandableCheckbox/ExpandableCheckbox.d.ts +63 -0
  84. package/lib/typescript/src/components/FullscreenModal/FullscreenModal.d.ts +99 -0
  85. package/lib/typescript/src/components/IconButton/IconButton.d.ts +7 -1
  86. package/lib/typescript/src/components/Image/Image.d.ts +8 -1
  87. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.d.ts +85 -0
  88. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.web.d.ts +28 -0
  89. package/lib/typescript/src/components/LottiePlayer/loadNativeLottieView.d.ts +11 -0
  90. package/lib/typescript/src/components/LottiePlayer/loadWebLottieView.d.ts +11 -0
  91. package/lib/typescript/src/components/MessageField/MessageField.d.ts +81 -0
  92. package/lib/typescript/src/components/NavArrow/NavArrow.d.ts +10 -5
  93. package/lib/typescript/src/components/PageHero/PageHero.d.ts +31 -5
  94. package/lib/typescript/src/components/Stepper/Step.d.ts +4 -1
  95. package/lib/typescript/src/components/Stepper/StepLabel.d.ts +4 -1
  96. package/lib/typescript/src/components/Stepper/Stepper.d.ts +3 -1
  97. package/lib/typescript/src/components/SuggestiveSearch/SuggestiveSearch.d.ts +123 -0
  98. package/lib/typescript/src/components/Text/Text.d.ts +20 -1
  99. package/lib/typescript/src/components/index.d.ts +8 -3
  100. package/lib/typescript/src/icons/Icon.d.ts +7 -1
  101. package/lib/typescript/src/icons/registry.d.ts +1 -1
  102. package/lib/typescript/src/index.d.ts +1 -0
  103. package/lib/typescript/src/skeleton/Skeleton.d.ts +60 -0
  104. package/lib/typescript/src/skeleton/SkeletonGroup.d.ts +78 -0
  105. package/lib/typescript/src/skeleton/index.d.ts +5 -0
  106. package/lib/typescript/src/skeleton/shimmer-tokens.d.ts +160 -0
  107. package/lib/typescript/src/skeleton/useReducedMotion.d.ts +15 -0
  108. package/package.json +11 -1
  109. package/src/components/Accordion/Accordion.tsx +113 -73
  110. package/src/components/ActionFooter/ActionFooter.tsx +210 -92
  111. package/src/components/Avatar/Avatar.tsx +26 -0
  112. package/src/components/Badge/Badge.tsx +27 -0
  113. package/src/components/Button/Button.tsx +40 -0
  114. package/src/components/Checkbox/Checkbox.tsx +22 -9
  115. package/src/components/DropdownInput/DropdownInput.tsx +67 -39
  116. package/src/components/ExpandableCheckbox/ExpandableCheckbox.tsx +237 -0
  117. package/src/components/FormField/FormField.tsx +19 -3
  118. package/src/components/FullscreenModal/FullscreenModal.tsx +414 -0
  119. package/src/components/IconButton/IconButton.tsx +27 -0
  120. package/src/components/Image/Image.tsx +25 -0
  121. package/src/components/ListItem/ListItem.tsx +21 -10
  122. package/src/components/LottiePlayer/LottiePlayer.tsx +145 -0
  123. package/src/components/LottiePlayer/LottiePlayer.web.tsx +94 -0
  124. package/src/components/LottiePlayer/loadNativeLottieView.tsx +87 -0
  125. package/src/components/LottiePlayer/loadWebLottieView.tsx +64 -0
  126. package/src/components/MessageField/MessageField.tsx +543 -0
  127. package/src/components/NavArrow/NavArrow.tsx +81 -17
  128. package/src/components/PageHero/PageHero.tsx +61 -4
  129. package/src/components/RechargeCard/RechargeCard.tsx +32 -24
  130. package/src/components/Stepper/Step.tsx +52 -51
  131. package/src/components/Stepper/StepLabel.tsx +46 -9
  132. package/src/components/Stepper/Stepper.tsx +20 -15
  133. package/src/components/SuggestiveSearch/SuggestiveSearch.tsx +756 -0
  134. package/src/components/Text/Text.tsx +54 -0
  135. package/src/components/TextInput/TextInput.tsx +14 -1
  136. package/src/components/Title/Title.tsx +13 -2
  137. package/src/components/index.ts +8 -3
  138. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  139. package/src/icons/Icon.tsx +17 -0
  140. package/src/icons/registry.ts +1 -1
  141. package/src/index.ts +1 -0
  142. package/src/skeleton/Skeleton.tsx +298 -0
  143. package/src/skeleton/SkeletonGroup.tsx +193 -0
  144. package/src/skeleton/index.ts +10 -0
  145. package/src/skeleton/shimmer-tokens.ts +221 -0
  146. package/src/skeleton/useReducedMotion.ts +72 -0
@@ -3,50 +3,55 @@ import { type ViewStyle, type StyleProp } from 'react-native';
3
3
  export type ActionFooterProps = {
4
4
  /**
5
5
  * Content to render inside the action footer slot.
6
- * Typically includes IconButton and Button components.
6
+ * Typically includes `IconButton` and `Button` components.
7
+ * `IconButton` children keep their intrinsic square size; everything else
8
+ * is auto-stretched to share the remaining horizontal space equally.
7
9
  */
8
10
  children?: React.ReactNode;
9
11
  /**
10
12
  * Mode configuration passed to the token resolver.
11
- * Pass the same modes to children components for consistent theming.
13
+ * Automatically merged into every slot child via {@link cloneChildrenWithModes}
14
+ * so callers don't have to thread modes down by hand.
12
15
  */
13
16
  modes?: Record<string, any>;
14
17
  /**
15
- * Optional style overrides for the container
18
+ * Optional style overrides for the outer container.
16
19
  */
17
20
  style?: StyleProp<ViewStyle>;
18
21
  /**
19
- * Accessibility label for the footer region
22
+ * Accessibility label for the footer region (announced for the toolbar).
20
23
  */
21
24
  accessibilityLabel?: string;
22
25
  };
23
26
  /**
24
- * ActionFooter component that provides a fixed footer container for action buttons.
27
+ * ActionFooter a sticky bottom container for primary screen actions.
25
28
  *
26
- * This component is designed to hold action items like IconButton and Button components
27
- * at the bottom of a screen. It includes a shadow for visual separation from content above.
29
+ * Layout contract:
30
+ * - The outer container stretches horizontally (`alignSelf: 'stretch'`) so
31
+ * it fills the parent regardless of whether the parent is a flex column,
32
+ * a ScrollView contentContainer, or a plain View.
33
+ * - The inner slot is a single row sized by its tallest child. It does NOT
34
+ * use `flex: 1` — that previously caused the row to collapse to zero on
35
+ * the first Yoga pass on native, taking the button labels with it.
36
+ * - `IconButton` children keep their intrinsic square size.
37
+ * - Every other child is auto-stretched with the Yoga-safe stretch style
38
+ * above so two `<Button>` siblings render at equal width on iOS, Android,
39
+ * and Web.
28
40
  *
29
- * The `modes` prop is automatically passed to all slot children. If a child has its own
30
- * `modes` prop, it will be merged with the parent's modes (child modes take precedence).
31
- *
32
- * @component
33
- * @param {Object} props - Component props
34
- * @param {React.ReactNode} [props.children] - Action elements to display (e.g., IconButton, Button)
35
- * @param {Object} [props.modes={}] - Mode configuration for design tokens (automatically passed to children)
36
- * @param {Object} [props.style] - Optional style overrides
37
- * @param {string} [props.accessibilityLabel] - Accessibility label for the footer region
41
+ * The `modes` prop is automatically pushed down to every slot child via
42
+ * {@link cloneChildrenWithModes}; explicit child-level modes win over the
43
+ * parent's modes.
38
44
  *
39
45
  * @example
40
46
  * ```tsx
41
- * // Basic usage - modes are automatically passed to all children.
42
- * // Non-IconButton children (e.g., Button) are auto-stretched to fill.
43
47
  * <ActionFooter modes={modes}>
44
48
  * <IconButton iconName="ic_split" />
45
- * <Button label="Request" />
46
- * <Button label="Pay" />
49
+ * <Button label="Request" modes={{ AppearanceBrand: 'Secondary' }} />
50
+ * <Button label="Pay" modes={{ AppearanceBrand: 'Primary' }} />
47
51
  * </ActionFooter>
48
52
  * ```
49
53
  */
50
54
  declare function ActionFooter({ children, modes, style, accessibilityLabel, }: ActionFooterProps): import("react/jsx-runtime").JSX.Element;
51
- export default ActionFooter;
55
+ declare const _default: React.MemoExoticComponent<typeof ActionFooter>;
56
+ export default _default;
52
57
  //# sourceMappingURL=ActionFooter.d.ts.map
@@ -27,8 +27,14 @@ export type AvatarProps = {
27
27
  accessibilityLabel?: string;
28
28
  onPress?: () => void;
29
29
  disabled?: boolean;
30
+ /**
31
+ * Explicit per-instance loading override. When `true`, renders a
32
+ * same-size circular skeleton instead of the avatar. Defaults to
33
+ * inheriting from the surrounding `<SkeletonGroup>`.
34
+ */
35
+ loading?: boolean;
30
36
  } & Omit<React.ComponentProps<typeof View>, 'style' | 'accessibilityRole' | 'accessibilityLabel'>;
31
- declare function Avatar({ monogram, style, modes, imageSource, accessibilityLabel: _accessibilityLabel, ...rest }: AvatarProps): import("react/jsx-runtime").JSX.Element;
37
+ declare function Avatar({ monogram, style, modes, imageSource, accessibilityLabel: _accessibilityLabel, loading, ...rest }: AvatarProps): import("react/jsx-runtime").JSX.Element;
32
38
  declare const _default: React.MemoExoticComponent<typeof Avatar>;
33
39
  export default _default;
34
40
  //# sourceMappingURL=Avatar.d.ts.map
@@ -10,7 +10,13 @@ type BadgeProps = {
10
10
  accessibilityLabel?: string;
11
11
  style?: ViewStyle;
12
12
  labelStyle?: TextStyle;
13
+ /**
14
+ * Explicit per-instance loading override. When `true`, renders a
15
+ * badge-shaped skeleton placeholder instead of the badge. Defaults to
16
+ * inheriting from the surrounding `<SkeletonGroup>`.
17
+ */
18
+ loading?: boolean;
13
19
  } & Omit<React.ComponentProps<typeof View>, 'style' | 'accessibilityLabel' | 'accessibilityRole'>;
14
- declare function Badge({ label, modes, onPress, accessibilityLabel, style, labelStyle, ...rest }: BadgeProps): import("react/jsx-runtime").JSX.Element;
20
+ declare function Badge({ label, modes, onPress, accessibilityLabel, style, labelStyle, loading, ...rest }: BadgeProps): import("react/jsx-runtime").JSX.Element;
15
21
  export default Badge;
16
22
  //# sourceMappingURL=Badge.d.ts.map
@@ -40,6 +40,13 @@ export type ButtonProps = SafePressableProps & {
40
40
  * Web-specific accessibility props (only used on web platform)
41
41
  */
42
42
  webAccessibilityProps?: WebAccessibilityProps;
43
+ /**
44
+ * Explicit per-instance loading override. When `true`, the button renders
45
+ * as a pill-shaped skeleton of the same size; when `false`, the
46
+ * surrounding `<SkeletonGroup>` is ignored. Defaults to inheriting from
47
+ * the group.
48
+ */
49
+ loading?: boolean;
43
50
  };
44
51
  /**
45
52
  * Button component that maps directly to the Figma design using design tokens.
@@ -76,7 +83,7 @@ export type ButtonProps = SafePressableProps & {
76
83
  * advantage of this should pass stable `modes` (the default `EMPTY_MODES`
77
84
  * is already stable) and stable callback props.
78
85
  */
79
- declare function ButtonImpl({ label, children, renderContent, leading, trailing, icon, modes, onPress, disabled, style, labelStyle, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
86
+ declare function ButtonImpl({ label, children, renderContent, leading, trailing, icon, modes, onPress, disabled, style, labelStyle, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, loading, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
80
87
  declare const Button: React.MemoExoticComponent<typeof ButtonImpl>;
81
88
  export default Button;
82
89
  //# sourceMappingURL=Button.d.ts.map
@@ -0,0 +1,63 @@
1
+ import { type StyleProp, type ViewStyle, type TextStyle } from 'react-native';
2
+ export type ExpandableCheckboxProps = {
3
+ /** Long text label rendered next to the checkbox. */
4
+ label?: string;
5
+ /** Whether the checkbox is checked (controlled). */
6
+ checked?: boolean;
7
+ /** Initial checked state (uncontrolled). */
8
+ defaultChecked?: boolean;
9
+ /** Callback fired when the checked state changes. */
10
+ onValueChange?: (checked: boolean) => void;
11
+ /** Whether the row is expanded to reveal the full label (controlled). */
12
+ expanded?: boolean;
13
+ /** Initial expanded state (uncontrolled). Defaults to `false` (Idle). */
14
+ defaultExpanded?: boolean;
15
+ /** Callback fired when the expanded state changes. */
16
+ onExpandedChange?: (expanded: boolean) => void;
17
+ /** Whether the entire row is disabled. */
18
+ disabled?: boolean;
19
+ /** Label for the toggle button shown when the row is collapsed. */
20
+ readMoreLabel?: string;
21
+ /** Label for the toggle button shown when the row is expanded. */
22
+ readLessLabel?: string;
23
+ /** Number of lines to show when collapsed. Defaults to `1`. */
24
+ collapsedLines?: number;
25
+ /** Design token modes for theming (e.g. `{ 'Color Mode': 'Light' }`). */
26
+ modes?: Record<string, any>;
27
+ /** Override outer container styles. */
28
+ style?: StyleProp<ViewStyle>;
29
+ /** Override the label text styles. */
30
+ labelStyle?: StyleProp<TextStyle>;
31
+ /** Accessibility label for the checkbox. Falls back to `label`. */
32
+ accessibilityLabel?: string;
33
+ };
34
+ /**
35
+ * ExpandableCheckbox composes a `Checkbox`, a long-form label and a
36
+ * "Read more" / "Read less" toggle. Mirrors the Figma "Expandable Checkbox"
37
+ * component with two states:
38
+ *
39
+ * - **Idle (collapsed)** — checkbox + truncated label + toggle button arranged
40
+ * in a horizontal row (cross-axis centered).
41
+ * - **Open (expanded)** — checkbox + full multi-line label, with the toggle
42
+ * button right-aligned beneath the row.
43
+ *
44
+ * The checkbox and the toggle button have independent press handlers — pressing
45
+ * the toggle does not affect the checked state, and toggling the checkbox does
46
+ * not collapse / expand the row.
47
+ *
48
+ * @component
49
+ * @param {ExpandableCheckboxProps} props
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * <ExpandableCheckbox
54
+ * label="By checking this box, I (a) acknowledge and (b) agree to the full terms…"
55
+ * defaultChecked
56
+ * onValueChange={setAccepted}
57
+ * modes={{ 'Color Mode': 'Light' }}
58
+ * />
59
+ * ```
60
+ */
61
+ declare function ExpandableCheckbox({ label, checked: controlledChecked, defaultChecked, onValueChange, expanded: controlledExpanded, defaultExpanded, onExpandedChange, disabled, readMoreLabel, readLessLabel, collapsedLines, modes, style, labelStyle, accessibilityLabel, }: ExpandableCheckboxProps): import("react/jsx-runtime").JSX.Element;
62
+ export default ExpandableCheckbox;
63
+ //# sourceMappingURL=ExpandableCheckbox.d.ts.map
@@ -0,0 +1,99 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ export type FullscreenModalProps = {
4
+ /** Small eyebrow line above the headline. */
5
+ eyebrow?: string;
6
+ /** Large hero headline. */
7
+ headline?: string;
8
+ /** Supporting paragraph shown below the headline. */
9
+ supportingText?: string;
10
+ /** Secondary line below the supporting paragraph (e.g. a price / timeline). */
11
+ priceText?: string;
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.
19
+ */
20
+ heroMedia?: React.ReactNode;
21
+ /** Resting height of the hero region. Defaults to 420. */
22
+ heroHeight?: number;
23
+ /**
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.
26
+ */
27
+ heroMinHeight?: number;
28
+ /** Enable the scroll-driven hero collapse. Defaults to true. */
29
+ parallax?: boolean;
30
+ /** Whether to render the floating close button (top-right). Defaults to true. */
31
+ showClose?: boolean;
32
+ /** Press handler for the close button. */
33
+ onClose?: () => void;
34
+ /** Accessibility label for the close button. */
35
+ closeAccessibilityLabel?: string;
36
+ /**
37
+ * Fully custom footer content rendered inside the sticky `ActionFooter`.
38
+ * When provided, `primaryActionLabel` / `disclaimer` are ignored.
39
+ */
40
+ footer?: React.ReactNode;
41
+ /** Label for the default primary action button in the footer. */
42
+ primaryActionLabel?: string;
43
+ /** Press handler for the default primary action button. */
44
+ onPrimaryAction?: () => void;
45
+ /** Disclaimer text shown below the default primary action button. */
46
+ disclaimer?: string;
47
+ /** Solid backdrop color for the scrollable body. Defaults to a near-black. */
48
+ backgroundColor?: string;
49
+ /** Body content (typically `Section`s). `modes` are cascaded automatically. */
50
+ children?: React.ReactNode;
51
+ /** Mode configuration. `context5` is always forced to `'Fullscreen Modal'`. */
52
+ modes?: Record<string, any>;
53
+ /** Style overrides for the outer container. */
54
+ style?: StyleProp<ViewStyle>;
55
+ /** Style overrides for the scroll body wrapper (the dark content area). */
56
+ contentContainerStyle?: StyleProp<ViewStyle>;
57
+ testID?: string;
58
+ };
59
+ /**
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
+ *
63
+ * The component always themes itself with `context5: 'Fullscreen Modal'`
64
+ * (non-overridable) so every nested component (Section, ListItem, Button,
65
+ * Disclaimer, …) resolves the white-on-dark "fullscreen modal" token values.
66
+ * That mode is cascaded into `children`, the footer, and the hero text via
67
+ * `cloneChildrenWithModes` / the merged `modes` object.
68
+ *
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}`.
77
+ *
78
+ * @component
79
+ * @example
80
+ * ```tsx
81
+ * <FullscreenModal
82
+ * eyebrow="Upgrade to JioFinance+"
83
+ * headline="Get more from your money."
84
+ * supportingText="JioFinance+ is your upgraded financial experience…"
85
+ * priceText="₹999/year · ₹0 until 2027"
86
+ * heroMedia={<LottiePlayer source={hero} size={{ width: 360, height: 420 }} />}
87
+ * primaryActionLabel="Upgrade for free"
88
+ * disclaimer="By upgrading, we'll check your eligibility with Experian."
89
+ * onPrimaryAction={() => upgrade()}
90
+ * onClose={() => navigation.goBack()}
91
+ * >
92
+ * <Section title="Key Benefits" slotDirection="column" slot={…} />
93
+ * <Section title="Compare plans" slotDirection="column" slot={…} />
94
+ * </FullscreenModal>
95
+ * ```
96
+ */
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;
98
+ export default FullscreenModal;
99
+ //# sourceMappingURL=FullscreenModal.d.ts.map
@@ -54,8 +54,14 @@ type IconButtonProps = SafePressableProps & {
54
54
  * Web-specific accessibility props (only used on web platform)
55
55
  */
56
56
  webAccessibilityProps?: WebAccessibilityProps;
57
+ /**
58
+ * Explicit per-instance loading override. When `true`, renders a
59
+ * same-size pill-shaped skeleton instead of the button. Defaults to
60
+ * inheriting from the surrounding `<SkeletonGroup>`.
61
+ */
62
+ loading?: boolean;
57
63
  };
58
- declare function IconButton({ iconName, source, modes, onPress, disabled, style, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, isToggle, activeIcon, activeSource, inactiveIcon, inactiveSource, isActive, ...rest }: IconButtonProps): import("react/jsx-runtime").JSX.Element;
64
+ declare function IconButton({ iconName, source, modes, onPress, disabled, style, accessibilityLabel, accessibilityHint, accessibilityState, webAccessibilityProps, isToggle, activeIcon, activeSource, inactiveIcon, inactiveSource, isActive, loading, ...rest }: IconButtonProps): import("react/jsx-runtime").JSX.Element;
59
65
  declare const _default: React.MemoExoticComponent<typeof IconButton>;
60
66
  export default _default;
61
67
  //# sourceMappingURL=IconButton.d.ts.map
@@ -38,8 +38,15 @@ export type ImageProps = {
38
38
  /** Hide from the a11y tree (e.g. when image is purely decorative). */
39
39
  accessibilityElementsHidden?: boolean | undefined;
40
40
  importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants' | undefined;
41
+ /**
42
+ * Explicit per-instance loading override. When `true`, the image renders as
43
+ * a skeleton placeholder at the same box size; when `false`, the
44
+ * surrounding `<SkeletonGroup>` is ignored. Defaults to inheriting from
45
+ * the group.
46
+ */
47
+ loading?: boolean | undefined;
41
48
  };
42
- declare function Image({ imageSource, ratio, resizeMode, width, height, borderRadius, style, accessibilityLabel, accessibilityElementsHidden, importantForAccessibility, }: ImageProps): import("react/jsx-runtime").JSX.Element;
49
+ declare function Image({ imageSource, ratio, resizeMode, width, height, borderRadius, style, accessibilityLabel, accessibilityElementsHidden, importantForAccessibility, loading, }: ImageProps): import("react/jsx-runtime").JSX.Element;
43
50
  declare const _default: React.MemoExoticComponent<typeof Image>;
44
51
  export default _default;
45
52
  //# sourceMappingURL=Image.d.ts.map
@@ -0,0 +1,85 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ /**
4
+ * A parsed Lottie animation. The JSON object you get from
5
+ * `require('./animation.json')` or `fetch().then(r => r.json())`. We keep the
6
+ * type intentionally loose because both `lottie-react-native` and `lottie-react`
7
+ * accept slightly different shapes — `LottiePlayer` narrows back to the
8
+ * platform-specific type internally.
9
+ */
10
+ export type LottieAnimationSource = Record<string, unknown>;
11
+ export type LottiePlayerProps = {
12
+ /**
13
+ * Parsed Lottie animation JSON. Use `require('./animation.json')` in React
14
+ * Native or `import animation from './animation.json'` on web.
15
+ *
16
+ * URI sources (`{ uri: '...' }`) are intentionally not accepted here — web
17
+ * Lottie players require the animation data to be pre-parsed. Fetch and
18
+ * parse the JSON yourself before passing it in if you need a remote source.
19
+ */
20
+ source: LottieAnimationSource;
21
+ /**
22
+ * Override the rendered size. Pass a number for a square box, or
23
+ * `{ width, height }` for non-square.
24
+ *
25
+ * When omitted, size is resolved from the `media/width` and `media/height`
26
+ * design tokens (default `117 × 117`). The `Media / Output` collection
27
+ * exposes `L | M | S` modes (117 / 70 / 20) — pass
28
+ * `modes={{ 'Media / Output': 'M' }}` to render at 70×70, etc.
29
+ */
30
+ size?: number | {
31
+ width: number;
32
+ height: number;
33
+ };
34
+ /** Play the animation on mount. Defaults to `true`. */
35
+ autoPlay?: boolean;
36
+ /** Loop the animation. Defaults to `true`. */
37
+ loop?: boolean;
38
+ /** Mode configuration for design-token theming. */
39
+ modes?: Record<string, any>;
40
+ /** Style overrides applied to the underlying view. */
41
+ style?: StyleProp<ViewStyle>;
42
+ /** Accessibility label. Lottie is decorative by default. */
43
+ accessibilityLabel?: string;
44
+ testID?: string;
45
+ };
46
+ /**
47
+ * Renders a Lottie animation using the consumer's installed
48
+ * `lottie-react-native` (native) or `lottie-react` (web) — both are declared
49
+ * as **optional peer dependencies** of `jfs-components`, so installing the
50
+ * library does not pull them in. Add the relevant package to your app only
51
+ * if you actually use `LottiePlayer`:
52
+ *
53
+ * ```sh
54
+ * # React Native (iOS / Android)
55
+ * npm install lottie-react-native
56
+ * cd ios && pod install
57
+ *
58
+ * # Web (or react-native-web)
59
+ * npm install lottie-react
60
+ * ```
61
+ *
62
+ * The web build (`LottiePlayer.web.tsx`) is picked automatically by Metro /
63
+ * webpack via platform extensions — same pattern as `MediaCard/GlassFill`.
64
+ *
65
+ * Token-driven sizing: when `size` is omitted, `LottiePlayer` reads
66
+ * `media/width` and `media/height` from the Figma variables resolver, so the
67
+ * animation matches the surrounding component's `Media / Output` mode
68
+ * automatically. This is the same sizing contract `PageHero` and
69
+ * `LottieIntroBlock` use for their `media` slots.
70
+ *
71
+ * @component
72
+ * @example
73
+ * ```tsx
74
+ * import animation from './assets/loader.json';
75
+ *
76
+ * <LottiePlayer source={animation} /> // 117 × 117 (default)
77
+ * <LottiePlayer source={animation} size={70} /> // 70 × 70
78
+ * <LottiePlayer source={animation} modes={{ 'Media / Output': 'S' }} /> // 20 × 20
79
+ * <PageHero media={<LottiePlayer source={animation} />} />
80
+ * ```
81
+ */
82
+ declare function LottiePlayer({ source, size, autoPlay, loop, modes: propModes, style, accessibilityLabel, testID, }: LottiePlayerProps): import("react/jsx-runtime").JSX.Element;
83
+ declare const _default: React.MemoExoticComponent<typeof LottiePlayer>;
84
+ export default _default;
85
+ //# sourceMappingURL=LottiePlayer.d.ts.map
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ export type LottieAnimationSource = Record<string, unknown>;
4
+ export type LottiePlayerProps = {
5
+ source: LottieAnimationSource;
6
+ size?: number | {
7
+ width: number;
8
+ height: number;
9
+ };
10
+ autoPlay?: boolean;
11
+ loop?: boolean;
12
+ modes?: Record<string, any>;
13
+ style?: StyleProp<ViewStyle>;
14
+ accessibilityLabel?: string;
15
+ testID?: string;
16
+ };
17
+ /**
18
+ * Web build of `LottiePlayer` — picked automatically by webpack /
19
+ * Metro-for-web via the `.web.tsx` platform extension. Uses `lottie-react`
20
+ * (which wraps `lottie-web`) and renders a plain DOM container.
21
+ *
22
+ * Public API mirrors `LottiePlayer.tsx` (native). See that file for the
23
+ * documented prop reference and usage patterns.
24
+ */
25
+ declare function LottiePlayer({ source, size, autoPlay, loop, modes: propModes, style, accessibilityLabel, testID, }: LottiePlayerProps): import("react/jsx-runtime").JSX.Element;
26
+ declare const _default: React.MemoExoticComponent<typeof LottiePlayer>;
27
+ export default _default;
28
+ //# sourceMappingURL=LottiePlayer.web.d.ts.map
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { type ViewStyle } from 'react-native';
3
+ /** Props we forward to the underlying native Lottie view. */
4
+ export type NativeLottieViewProps = {
5
+ source: Record<string, unknown>;
6
+ autoPlay?: boolean;
7
+ loop?: boolean;
8
+ style?: ViewStyle;
9
+ };
10
+ export declare function getNativeLottieView(): React.ComponentType<NativeLottieViewProps>;
11
+ //# sourceMappingURL=loadNativeLottieView.d.ts.map
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import type { CSSProperties } from 'react';
3
+ /** Props we forward to the underlying web Lottie view. */
4
+ export type WebLottieViewProps = {
5
+ animationData: Record<string, unknown>;
6
+ autoplay?: boolean;
7
+ loop?: boolean;
8
+ style?: CSSProperties;
9
+ };
10
+ export declare function getWebLottieView(): React.ComponentType<WebLottieViewProps>;
11
+ //# sourceMappingURL=loadWebLottieView.d.ts.map
@@ -0,0 +1,81 @@
1
+ import { type StyleProp, type TextInputProps as RNTextInputProps, type TextStyle, type ViewStyle } from 'react-native';
2
+ /**
3
+ * Visual state of the textarea. Mirrors the `FormField States` collection so
4
+ * MessageField slots into the same theming pipeline as FormField. The state
5
+ * is always derived from props (`isInvalid`, `isDisabled`, `isReadOnly` and
6
+ * focus) and is locked in `modes['FormField States']` — passing that key in
7
+ * `modes` is intentionally ignored to keep interactive behaviour and visual
8
+ * state in sync.
9
+ */
10
+ export type MessageFieldState = 'Idle' | 'Active' | 'Read Only' | 'Error' | 'Disabled';
11
+ export type MessageFieldProps = {
12
+ /** Label rendered above the textarea. */
13
+ label?: string;
14
+ /** Placeholder text shown when the textarea is empty. */
15
+ placeholder?: string;
16
+ /**
17
+ * Current value of the textarea (controlled). When provided, the consumer
18
+ * is responsible for updating it via `onChangeText`.
19
+ */
20
+ value?: string;
21
+ /** Initial value when used uncontrolled. Ignored when `value` is provided. */
22
+ defaultValue?: string;
23
+ /** Called whenever the text changes. Fires for both controlled and uncontrolled use. */
24
+ onChangeText?: (text: string) => void;
25
+ /**
26
+ * Form field name. When the field is rendered inside a `<Form>`, this is
27
+ * the key used to look up server-side `validationErrors` and to clear
28
+ * the error when the value changes.
29
+ */
30
+ name?: string;
31
+ /**
32
+ * Maximum number of characters accepted. Drives the counter when
33
+ * `showCounter` is not explicitly false.
34
+ */
35
+ maxLength?: number;
36
+ /**
37
+ * Controls visibility of the character counter.
38
+ * - Default: counter is shown when `maxLength` is provided.
39
+ * - `true`: always show counter (shows `<count>/<maxLength>` when
40
+ * `maxLength` is set, or just `<count>` otherwise).
41
+ * - `false`: never show counter.
42
+ */
43
+ showCounter?: boolean;
44
+ /**
45
+ * Number of visible text rows. When provided, overrides the default
46
+ * `messageField/textarea/height` token to derive the textarea height as
47
+ * `rows * lineHeight + 2 * padding`.
48
+ */
49
+ rows?: number;
50
+ /** Renders a required indicator (asterisk) next to the label. */
51
+ isRequired?: boolean;
52
+ /** Disables interaction and dims the field. */
53
+ isDisabled?: boolean;
54
+ /** Marks the field as invalid and resolves to the `Error` state token mode. */
55
+ isInvalid?: boolean;
56
+ /** Read-only, non-interactive but not dimmed. */
57
+ isReadOnly?: boolean;
58
+ /** Auto-focus the textarea on mount. */
59
+ autoFocus?: boolean;
60
+ /** Modes for design token resolution (e.g. `{ 'Color Mode': 'Light' }`). */
61
+ modes?: Record<string, any>;
62
+ /** Style overrides for the outermost wrapper. */
63
+ style?: StyleProp<ViewStyle>;
64
+ /** Style overrides for the textarea container (border/padding/etc). */
65
+ textareaStyle?: StyleProp<ViewStyle>;
66
+ /** Style overrides for the input text. */
67
+ inputStyle?: StyleProp<TextStyle>;
68
+ /** Accessibility label. Defaults to `label` or `placeholder`. */
69
+ accessibilityLabel?: string;
70
+ /** Accessibility hint. */
71
+ accessibilityHint?: string;
72
+ /** Test identifier. */
73
+ testID?: string;
74
+ /** Called when the textarea receives focus. */
75
+ onFocus?: RNTextInputProps['onFocus'];
76
+ /** Called when the textarea loses focus. */
77
+ onBlur?: RNTextInputProps['onBlur'];
78
+ };
79
+ declare function MessageField({ label, placeholder, value, defaultValue, onChangeText, name, maxLength, showCounter, rows, isRequired, isDisabled, isInvalid, isReadOnly, autoFocus, modes: propModes, style, textareaStyle, inputStyle, accessibilityLabel, accessibilityHint, testID, onFocus, onBlur, }: MessageFieldProps): import("react/jsx-runtime").JSX.Element;
80
+ export default MessageField;
81
+ //# sourceMappingURL=MessageField.d.ts.map
@@ -1,16 +1,21 @@
1
1
  import React from 'react';
2
- import { View, type ViewStyle } from 'react-native';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ import { type SafePressableProps } from '../../utils/web-platform-utils';
3
4
  type NavArrowDirection = 'Back' | 'Forward' | 'Down';
4
- type NavArrowProps = {
5
+ type NavArrowProps = SafePressableProps & {
5
6
  /** Direction of the arrow: 'Back' (left chevron), 'Forward' (right chevron), or 'Down' */
6
7
  direction?: NavArrowDirection;
7
8
  /** Modes used to resolve design tokens */
8
9
  modes?: Record<string, any>;
9
10
  /** Optional additional container style */
10
- style?: ViewStyle;
11
+ style?: StyleProp<ViewStyle>;
11
12
  /** Accessibility label for the arrow */
12
13
  accessibilityLabel?: string;
13
- } & Omit<React.ComponentProps<typeof View>, 'style' | 'accessibilityLabel'>;
14
+ /** Called when the arrow is pressed. Expands the hit area to at least 44×44. */
15
+ onPress?: () => void;
16
+ /** Disables press interaction when `onPress` is provided */
17
+ disabled?: boolean;
18
+ };
14
19
  /**
15
20
  * NavArrow component that displays a chevron arrow for navigation.
16
21
  *
@@ -25,7 +30,7 @@ type NavArrowProps = {
25
30
  * on (tokens, direction, style).
26
31
  * - Wrapped in `React.memo`.
27
32
  */
28
- declare function NavArrow({ direction, modes, style, accessibilityLabel, ...rest }: NavArrowProps): import("react/jsx-runtime").JSX.Element;
33
+ declare function NavArrow({ direction, modes, style, accessibilityLabel, onPress, disabled, ...rest }: NavArrowProps): import("react/jsx-runtime").JSX.Element;
29
34
  declare const _default: React.MemoExoticComponent<typeof NavArrow>;
30
35
  export default _default;
31
36
  //# sourceMappingURL=NavArrow.d.ts.map
@@ -21,6 +21,23 @@ export type PageHeroProps = {
21
21
  * `modes` are automatically cascaded into this slot.
22
22
  */
23
23
  buttonSlot?: React.ReactNode;
24
+ /**
25
+ * Optional media element shown above the text block (eyebrow + headline).
26
+ *
27
+ * Intentionally typed as `React.ReactNode` so the consumer can bring any
28
+ * renderer they like — `<Image />`, `<IconCapsule />`, a Lottie player
29
+ * (`lottie-react-native` / `@lottiefiles/dotlottie-react`), an `<SvgXml />`
30
+ * from `react-native-svg`, a `<Video />` from `react-native-video`, a
31
+ * gradient view, or a custom illustration. The library deliberately does
32
+ * NOT wrap Lottie / video runtimes (they require native modules + pod
33
+ * autolinking on every consumer's app), so PageHero just allocates a
34
+ * token-sized container and lets the slot render whatever it wants.
35
+ *
36
+ * The slot is rendered inside a `width × height` box driven by
37
+ * `media/width` and `media/height` tokens (default 117×117). `modes` are
38
+ * automatically cascaded into the slot via `cloneChildrenWithModes`.
39
+ */
40
+ media?: React.ReactNode;
24
41
  /** Mode configuration for design-token theming. */
25
42
  modes?: Record<string, any>;
26
43
  /** Style overrides applied to the outer container. */
@@ -29,12 +46,14 @@ export type PageHeroProps = {
29
46
  };
30
47
  /**
31
48
  * PageHero displays a centered hero block typically used at the top of a page
32
- * or feature screen. It contains an eyebrow line, a large headline, an optional
33
- * supporting line (e.g. price/timeline), and an optional action button.
49
+ * or feature screen. It contains an optional media slot (illustration / image
50
+ * / Lottie / SVG / video — consumer's choice), an eyebrow line, a large
51
+ * headline, an optional supporting line (e.g. price / timeline), and an
52
+ * optional action button.
34
53
  *
35
54
  * All visual values are resolved from Figma design tokens via
36
- * `getVariableByName`. The button slot cascades the active `modes` to its
37
- * children through `cloneChildrenWithModes`.
55
+ * `getVariableByName`. Slots cascade the active `modes` to their children
56
+ * through `cloneChildrenWithModes`.
38
57
  *
39
58
  * @component
40
59
  * @example
@@ -45,9 +64,16 @@ export type PageHeroProps = {
45
64
  * supportingText="₹999/year · ₹0 until 2027"
46
65
  * buttonLabel="Renew for free"
47
66
  * onButtonPress={() => navigate('Upgrade')}
67
+ * media={
68
+ * <Image
69
+ * imageSource={require('./assets/upgrade.png')}
70
+ * width={117}
71
+ * height={117}
72
+ * />
73
+ * }
48
74
  * />
49
75
  * ```
50
76
  */
51
- declare function PageHero({ eyebrow, headline, supportingText, showSupportingText, buttonLabel, onButtonPress, showButton, buttonSlot, modes: propModes, style, testID, }: PageHeroProps): import("react/jsx-runtime").JSX.Element;
77
+ declare function PageHero({ eyebrow, headline, supportingText, showSupportingText, buttonLabel, onButtonPress, showButton, buttonSlot, media, modes: propModes, style, testID, }: PageHeroProps): import("react/jsx-runtime").JSX.Element;
52
78
  export default PageHero;
53
79
  //# sourceMappingURL=PageHero.d.ts.map