jfs-components 0.0.74 → 0.0.77

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 (92) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/lib/commonjs/components/ActionFooter/ActionFooter.js +147 -82
  3. package/lib/commonjs/components/Avatar/Avatar.js +20 -0
  4. package/lib/commonjs/components/Badge/Badge.js +23 -0
  5. package/lib/commonjs/components/Button/Button.js +37 -0
  6. package/lib/commonjs/components/IconButton/IconButton.js +20 -0
  7. package/lib/commonjs/components/Image/Image.js +26 -1
  8. package/lib/commonjs/components/LottiePlayer/LottiePlayer.js +116 -0
  9. package/lib/commonjs/components/LottiePlayer/LottiePlayer.web.js +82 -0
  10. package/lib/commonjs/components/LottiePlayer/loadNativeLottieView.js +74 -0
  11. package/lib/commonjs/components/LottiePlayer/loadWebLottieView.js +50 -0
  12. package/lib/commonjs/components/PageHero/PageHero.js +41 -5
  13. package/lib/commonjs/components/RechargeCard/RechargeCard.js +32 -17
  14. package/lib/commonjs/components/Text/Text.js +31 -1
  15. package/lib/commonjs/components/index.js +7 -0
  16. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  17. package/lib/commonjs/icons/Icon.js +16 -0
  18. package/lib/commonjs/icons/registry.js +1 -1
  19. package/lib/commonjs/index.js +12 -0
  20. package/lib/commonjs/skeleton/Skeleton.js +234 -0
  21. package/lib/commonjs/skeleton/SkeletonGroup.js +140 -0
  22. package/lib/commonjs/skeleton/index.js +58 -0
  23. package/lib/commonjs/skeleton/shimmer-tokens.js +189 -0
  24. package/lib/commonjs/skeleton/useReducedMotion.js +64 -0
  25. package/lib/module/components/ActionFooter/ActionFooter.js +146 -82
  26. package/lib/module/components/Avatar/Avatar.js +19 -0
  27. package/lib/module/components/Badge/Badge.js +23 -0
  28. package/lib/module/components/Button/Button.js +37 -0
  29. package/lib/module/components/IconButton/IconButton.js +20 -0
  30. package/lib/module/components/Image/Image.js +25 -1
  31. package/lib/module/components/LottiePlayer/LottiePlayer.js +111 -0
  32. package/lib/module/components/LottiePlayer/LottiePlayer.web.js +77 -0
  33. package/lib/module/components/LottiePlayer/loadNativeLottieView.js +69 -0
  34. package/lib/module/components/LottiePlayer/loadWebLottieView.js +45 -0
  35. package/lib/module/components/PageHero/PageHero.js +41 -5
  36. package/lib/module/components/RechargeCard/RechargeCard.js +33 -17
  37. package/lib/module/components/Text/Text.js +31 -1
  38. package/lib/module/components/index.js +1 -0
  39. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  40. package/lib/module/icons/Icon.js +16 -0
  41. package/lib/module/icons/registry.js +1 -1
  42. package/lib/module/index.js +2 -1
  43. package/lib/module/skeleton/Skeleton.js +229 -0
  44. package/lib/module/skeleton/SkeletonGroup.js +133 -0
  45. package/lib/module/skeleton/index.js +6 -0
  46. package/lib/module/skeleton/shimmer-tokens.js +181 -0
  47. package/lib/module/skeleton/useReducedMotion.js +61 -0
  48. package/lib/typescript/src/components/ActionFooter/ActionFooter.d.ts +26 -21
  49. package/lib/typescript/src/components/Avatar/Avatar.d.ts +7 -1
  50. package/lib/typescript/src/components/Badge/Badge.d.ts +7 -1
  51. package/lib/typescript/src/components/Button/Button.d.ts +8 -1
  52. package/lib/typescript/src/components/IconButton/IconButton.d.ts +7 -1
  53. package/lib/typescript/src/components/Image/Image.d.ts +8 -1
  54. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.d.ts +85 -0
  55. package/lib/typescript/src/components/LottiePlayer/LottiePlayer.web.d.ts +28 -0
  56. package/lib/typescript/src/components/LottiePlayer/loadNativeLottieView.d.ts +11 -0
  57. package/lib/typescript/src/components/LottiePlayer/loadWebLottieView.d.ts +11 -0
  58. package/lib/typescript/src/components/PageHero/PageHero.d.ts +31 -5
  59. package/lib/typescript/src/components/Text/Text.d.ts +20 -1
  60. package/lib/typescript/src/components/index.d.ts +1 -0
  61. package/lib/typescript/src/icons/Icon.d.ts +7 -1
  62. package/lib/typescript/src/icons/registry.d.ts +1 -1
  63. package/lib/typescript/src/index.d.ts +1 -0
  64. package/lib/typescript/src/skeleton/Skeleton.d.ts +60 -0
  65. package/lib/typescript/src/skeleton/SkeletonGroup.d.ts +78 -0
  66. package/lib/typescript/src/skeleton/index.d.ts +5 -0
  67. package/lib/typescript/src/skeleton/shimmer-tokens.d.ts +160 -0
  68. package/lib/typescript/src/skeleton/useReducedMotion.d.ts +15 -0
  69. package/package.json +11 -1
  70. package/src/components/ActionFooter/ActionFooter.tsx +152 -86
  71. package/src/components/Avatar/Avatar.tsx +26 -0
  72. package/src/components/Badge/Badge.tsx +27 -0
  73. package/src/components/Button/Button.tsx +40 -0
  74. package/src/components/IconButton/IconButton.tsx +27 -0
  75. package/src/components/Image/Image.tsx +25 -0
  76. package/src/components/LottiePlayer/LottiePlayer.tsx +145 -0
  77. package/src/components/LottiePlayer/LottiePlayer.web.tsx +94 -0
  78. package/src/components/LottiePlayer/loadNativeLottieView.tsx +87 -0
  79. package/src/components/LottiePlayer/loadWebLottieView.tsx +64 -0
  80. package/src/components/PageHero/PageHero.tsx +61 -4
  81. package/src/components/RechargeCard/RechargeCard.tsx +32 -24
  82. package/src/components/Text/Text.tsx +54 -0
  83. package/src/components/index.ts +1 -0
  84. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  85. package/src/icons/Icon.tsx +17 -0
  86. package/src/icons/registry.ts +1 -1
  87. package/src/index.ts +1 -0
  88. package/src/skeleton/Skeleton.tsx +298 -0
  89. package/src/skeleton/SkeletonGroup.tsx +193 -0
  90. package/src/skeleton/index.ts +10 -0
  91. package/src/skeleton/shimmer-tokens.ts +221 -0
  92. 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
@@ -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
@@ -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
@@ -20,7 +20,26 @@ export type TextProps = {
20
20
  style?: StyleProp<TextStyle>;
21
21
  /** Number of lines to limit the text to. */
22
22
  numberOfLines?: number;
23
+ /**
24
+ * Explicit per-instance loading override. When `true`, this `Text` renders
25
+ * a skeleton placeholder regardless of any surrounding `<SkeletonGroup>`.
26
+ * When `false`, the surrounding group is ignored for this instance. When
27
+ * omitted, the surrounding group's `loading` flag wins.
28
+ */
29
+ loading?: boolean;
30
+ /**
31
+ * Optional width used while the skeleton is showing. Numbers are dp;
32
+ * `'100%'` (etc.) is a valid RN dimension. Defaults to a character-count
33
+ * heuristic based on the resolved font size and the supplied content.
34
+ */
35
+ skeletonWidth?: number | `${number}%`;
36
+ /**
37
+ * Optional explicit line count for the skeleton placeholder. Defaults to
38
+ * `numberOfLines ?? 1`. Useful when `numberOfLines` is intentionally
39
+ * unbounded but you want a sensible multi-line placeholder.
40
+ */
41
+ skeletonLines?: number;
23
42
  };
24
- declare function Text({ text, children, textAlign, modes, style, numberOfLines, }: TextProps): import("react/jsx-runtime").JSX.Element;
43
+ declare function Text({ text, children, textAlign, modes, style, numberOfLines, loading, skeletonWidth, skeletonLines, }: TextProps): import("react/jsx-runtime").JSX.Element;
25
44
  export default Text;
26
45
  //# sourceMappingURL=Text.d.ts.map
@@ -47,6 +47,7 @@ export { default as LinearMeter, type LinearMeterProps } from './LinearMeter/Lin
47
47
  export { default as LinearProgress, type LinearProgressProps } from './LinearProgress/LinearProgress';
48
48
  export { default as ListGroup } from './ListGroup/ListGroup';
49
49
  export { default as LottieIntroBlock, type LottieIntroBlockProps } from './LottieIntroBlock/LottieIntroBlock';
50
+ export { default as LottiePlayer, type LottiePlayerProps, type LottieAnimationSource } from './LottiePlayer/LottiePlayer';
50
51
  export { default as ListItem } from './ListItem/ListItem';
51
52
  export { default as MediaCard, type MediaCardProps } from './MediaCard/MediaCard';
52
53
  export { default as MerchantProfile, type MerchantProfileProps } from './MerchantProfile/MerchantProfile';
@@ -18,6 +18,12 @@ type IconProps = AccessibilityProps & {
18
18
  size?: number;
19
19
  color?: string;
20
20
  style?: StyleProp<ViewStyle>;
21
+ /**
22
+ * Explicit per-instance loading override. When `true`, renders a square
23
+ * skeleton at the icon's size; when `false`, the surrounding
24
+ * `<SkeletonGroup>` is ignored. Defaults to inheriting from the group.
25
+ */
26
+ loading?: boolean;
21
27
  };
22
28
  /**
23
29
  * Generic Icon component.
@@ -43,6 +49,6 @@ type IconProps = AccessibilityProps & {
43
49
  * <Icon source={BrandLogo} size={24} color="red" />
44
50
  * ```
45
51
  */
46
- declare function Icon({ name, source, size, color, style, ...rest }: IconProps): import("react/jsx-runtime").JSX.Element;
52
+ declare function Icon({ name, source, size, color, style, loading, ...rest }: IconProps): import("react/jsx-runtime").JSX.Element;
47
53
  export default Icon;
48
54
  //# sourceMappingURL=Icon.d.ts.map
@@ -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-05-19T16:28:08.570Z
7
+ * Generated: 2026-05-25T10:18:38.037Z
8
8
  */
9
9
  export declare const iconRegistry: Record<string, {
10
10
  path: string;
@@ -3,4 +3,5 @@ export * as Icons from './icons';
3
3
  export * from './design-tokens';
4
4
  export * from './Containers';
5
5
  export * from './utils';
6
+ export * from './skeleton';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,60 @@
1
+ import React from 'react';
2
+ import { type DimensionValue, type StyleProp, type ViewStyle } from 'react-native';
3
+ import { type SkeletonKind } from './shimmer-tokens';
4
+ export interface SkeletonProps {
5
+ /**
6
+ * Visual category — controls only the corner-radius token. Sizes are still
7
+ * supplied via `width`/`height`. Defaults to `'other'`.
8
+ */
9
+ kind?: SkeletonKind;
10
+ /** Width of the rectangular placeholder. Numbers are dp, strings are RN dimensions. */
11
+ width?: DimensionValue;
12
+ /** Height of the rectangular placeholder. */
13
+ height?: DimensionValue;
14
+ /**
15
+ * Optional style overrides merged onto the base layer (e.g. `marginTop`,
16
+ * `alignSelf`). Avoid `backgroundColor` and `borderRadius` here — use the
17
+ * design tokens instead so the system stays consistent.
18
+ */
19
+ style?: StyleProp<ViewStyle>;
20
+ /**
21
+ * Modes for token resolution (forwarded to `getVariableByName`). Most
22
+ * consumers can omit this — defaults work for every standard mode.
23
+ */
24
+ modes?: Record<string, any>;
25
+ }
26
+ /**
27
+ * Atomic skeleton placeholder. Renders a base rectangle (background colour +
28
+ * radius per kind) plus an animated overlay that produces the shimmer.
29
+ *
30
+ * Two visual modes share the same engine:
31
+ *
32
+ * - Normal mode (gradient: true): a soft 135° band translates diagonally
33
+ * across the box end-to-end. Its alpha inside the moving band varies
34
+ * 33% → 100% → 33% via gradient stops. The sawtooth clock travels from
35
+ * fully off-screen (−overshoot) to fully off-screen (+overshoot) so the
36
+ * transparent gradient tails clear the box before the loop resets.
37
+ *
38
+ * - Reduced-motion mode (gradient: false): a solid white overlay covers the
39
+ * box and pulses opacity 33% → 100% → 33% in place, with no translation,
40
+ * ease-in-out timing and no stagger.
41
+ *
42
+ * Critical for cross-platform consistency:
43
+ *
44
+ * - The SVG gradient uses `gradientUnits="userSpaceOnUse"` with absolute
45
+ * pixel coordinates that have Δx === Δy. This guarantees the visual angle
46
+ * is exactly 45° in screen pixels (= 135° CSS) on ANY aspect ratio. With
47
+ * the default `objectBoundingBox` units, the gradient line is normalised
48
+ * to the box and tilts off-angle on non-square boxes.
49
+ *
50
+ * - The whole animated overlay sits inside a clipping parent (`overflow:
51
+ * hidden` + `borderRadius`). Translating an `Animated.View` is GPU-cheap
52
+ * on both iOS/Android (Reanimated UI thread) and on web (CSS transforms).
53
+ *
54
+ * - The SVG `id` for the gradient is per-instance (`useId`) so multiple
55
+ * skeletons on a web page don't collide on `url(#…)` resolution.
56
+ */
57
+ declare function SkeletonImpl({ kind, width, height, style, modes, }: SkeletonProps): import("react/jsx-runtime").JSX.Element;
58
+ declare const Skeleton: React.MemoExoticComponent<typeof SkeletonImpl>;
59
+ export default Skeleton;
60
+ //# sourceMappingURL=Skeleton.d.ts.map
@@ -0,0 +1,78 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type SharedValue } from 'react-native-reanimated';
3
+ /**
4
+ * Shape of the value carried by the SkeletonContext.
5
+ *
6
+ * The provider owns ONE Reanimated shared value per group; every child
7
+ * `<Skeleton>` reads it on the UI thread and computes its own opacity from
8
+ * `(clock + perItemPhaseOffset)`. That keeps per-skeleton work bounded to a
9
+ * single `useAnimatedStyle` and avoids per-block JS timers.
10
+ */
11
+ export interface SkeletonContextValue {
12
+ /** Whether the surrounding group is currently in loading state. */
13
+ active: boolean;
14
+ /**
15
+ * Whether reduced-motion treatment should be applied. May be auto-detected
16
+ * from the OS or explicitly overridden via the `reducedMotion` prop on
17
+ * `<SkeletonGroup>`.
18
+ */
19
+ reducedMotion: boolean;
20
+ /**
21
+ * Shared phase value driven on the UI thread. Sawtooth: ramps linearly
22
+ * (or eased) from 0 -> 1 over one `SHIMMER.*.durationMs` period, then
23
+ * jumps back to 0 and repeats. Sawtooth is required so that the moving
24
+ * shimmer band sweeps from end to end at a constant heading and resets
25
+ * cleanly; a ping-pong clock would produce a discontinuity in
26
+ * `(clock + phaseOffset) % 1` at the apex, which translates to a visible
27
+ * jump in the band's position when stagger offsets are non-zero.
28
+ */
29
+ clock: SharedValue<number>;
30
+ /**
31
+ * Atomically registers a child skeleton and returns its registration index.
32
+ * The order is stable for the life of the parent group; the counter is held
33
+ * in a ref so React's render lifecycle doesn't reshuffle it.
34
+ */
35
+ nextIndex(): number;
36
+ }
37
+ export interface SkeletonGroupProps {
38
+ /** When true, descendant skeleton-aware primitives render placeholders. */
39
+ loading: boolean;
40
+ /**
41
+ * Override the auto-detected reduced-motion preference. Pass `undefined` to
42
+ * use the system value (default). Pass `true`/`false` to force.
43
+ */
44
+ reducedMotion?: boolean;
45
+ children?: ReactNode;
46
+ }
47
+ /**
48
+ * Provider that flips an entire subtree into "loading" mode and supplies the
49
+ * shared shimmer clock + stagger index source to every descendant skeleton.
50
+ *
51
+ * Usage:
52
+ * ```tsx
53
+ * <SkeletonGroup loading={!data}>
54
+ * <Card>...JFS primitives auto-skeletonize...</Card>
55
+ * </SkeletonGroup>
56
+ * ```
57
+ *
58
+ * Nesting is supported — an inner `<SkeletonGroup>` fully overrides the
59
+ * outer one for its subtree (its own clock, its own index counter).
60
+ */
61
+ export declare function SkeletonGroup({ loading, reducedMotion: reducedMotionOverride, children, }: SkeletonGroupProps): import("react/jsx-runtime").JSX.Element;
62
+ /**
63
+ * Internal hook used by skeleton-aware primitives (and by `<Skeleton>`
64
+ * itself) to read the surrounding context.
65
+ *
66
+ * Always returns a non-null value: when called outside any provider, the
67
+ * returned object has `active: false` so the consumer falls through to its
68
+ * normal render path. The fallback clock is a no-op shared value so any
69
+ * direct `<Skeleton>` usage outside a group still has something safe to read.
70
+ */
71
+ export declare function useSkeleton(): SkeletonContextValue;
72
+ /**
73
+ * Convenience wrapper around `useSkeleton().nextIndex()` that pins the
74
+ * returned value across re-renders. Each `<Skeleton>` calls this once on
75
+ * mount; subsequent renders re-use the same index from the closure.
76
+ */
77
+ export declare function useStaggerIndex(): number;
78
+ //# sourceMappingURL=SkeletonGroup.d.ts.map
@@ -0,0 +1,5 @@
1
+ export { default as Skeleton, type SkeletonProps } from './Skeleton';
2
+ export { SkeletonGroup, useSkeleton, useStaggerIndex, type SkeletonGroupProps, type SkeletonContextValue, } from './SkeletonGroup';
3
+ export { useReducedMotion } from './useReducedMotion';
4
+ export { SHIMMER, SKELETON_TOKEN, SKELETON_FALLBACK, type SkeletonKind } from './shimmer-tokens';
5
+ //# sourceMappingURL=index.d.ts.map