jfs-components 0.1.19 → 0.1.23

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 (40) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +31 -8
  3. package/lib/commonjs/components/ContentSheet/ContentSheet.js +131 -0
  4. package/lib/commonjs/components/HeroSection/HeroSection.js +165 -0
  5. package/lib/commonjs/components/Image/Image.js +33 -7
  6. package/lib/commonjs/components/Link/Link.js +115 -0
  7. package/lib/commonjs/components/ListItem/ListItem.js +16 -1
  8. package/lib/commonjs/components/index.js +21 -0
  9. package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
  10. package/lib/commonjs/design-tokens/figma-modes.generated.js +53 -43
  11. package/lib/commonjs/icons/registry.js +1 -1
  12. package/lib/module/components/CheckboxItem/CheckboxItem.js +31 -8
  13. package/lib/module/components/ContentSheet/ContentSheet.js +126 -0
  14. package/lib/module/components/HeroSection/HeroSection.js +159 -0
  15. package/lib/module/components/Image/Image.js +34 -7
  16. package/lib/module/components/Link/Link.js +110 -0
  17. package/lib/module/components/ListItem/ListItem.js +16 -1
  18. package/lib/module/components/index.js +3 -0
  19. package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
  20. package/lib/module/design-tokens/figma-modes.generated.js +53 -43
  21. package/lib/module/icons/registry.js +1 -1
  22. package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +26 -3
  23. package/lib/typescript/src/components/ContentSheet/ContentSheet.d.ts +71 -0
  24. package/lib/typescript/src/components/HeroSection/HeroSection.d.ts +80 -0
  25. package/lib/typescript/src/components/Image/Image.d.ts +27 -2
  26. package/lib/typescript/src/components/Link/Link.d.ts +73 -0
  27. package/lib/typescript/src/components/index.d.ts +3 -0
  28. package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +8 -0
  29. package/lib/typescript/src/icons/registry.d.ts +1 -1
  30. package/package.json +1 -1
  31. package/src/components/CheckboxItem/CheckboxItem.tsx +59 -14
  32. package/src/components/ContentSheet/ContentSheet.tsx +217 -0
  33. package/src/components/HeroSection/HeroSection.tsx +231 -0
  34. package/src/components/Image/Image.tsx +55 -3
  35. package/src/components/Link/Link.tsx +159 -0
  36. package/src/components/ListItem/ListItem.tsx +15 -0
  37. package/src/components/index.ts +3 -0
  38. package/src/design-tokens/Coin Variables-variables-full.json +1 -1
  39. package/src/design-tokens/figma-modes.generated.ts +53 -43
  40. package/src/icons/registry.ts +1 -1
@@ -10,7 +10,25 @@ export type CheckboxItemProps = {
10
10
  onValueChange?: (checked: boolean) => void;
11
11
  /** Whether the row is disabled — both the checkbox and row press handler are disabled. */
12
12
  disabled?: boolean;
13
- /** The label text rendered next to the checkbox. */
13
+ /**
14
+ * Content rendered in the row's label slot (between the leading and trailing
15
+ * edges). This is the primary way to supply the label and mirrors the Figma
16
+ * "slot" — pass a plain string for the default token-styled label, or any
17
+ * custom node (e.g. a `<Text>`, a row of `<Text>` + `<Badge>`, etc.) for full
18
+ * control. Custom nodes receive the same `modes` as the parent.
19
+ *
20
+ * When both `children` and the legacy {@link label} prop are provided,
21
+ * `children` wins.
22
+ */
23
+ children?: React.ReactNode;
24
+ /**
25
+ * The label content rendered next to the checkbox.
26
+ *
27
+ * @deprecated Prefer the `children` slot instead
28
+ * (`<CheckboxItem>Fixed deposit • 0245</CheckboxItem>`). `label` is kept for
29
+ * backward compatibility and behaves identically — it is used only when no
30
+ * `children` are provided.
31
+ */
14
32
  label?: React.ReactNode;
15
33
  /**
16
34
  * Position of the checkbox control relative to the label.
@@ -59,13 +77,18 @@ export type CheckboxItemProps = {
59
77
  * ```tsx
60
78
  * const [checked, setChecked] = useState(false)
61
79
  *
80
+ * // Recommended: pass the label via the children slot.
62
81
  * <CheckboxItem
63
- * label="Fixed deposit • 0245"
64
82
  * checked={checked}
65
83
  * onValueChange={setChecked}
66
84
  * control="leading"
67
85
  * modes={{ 'Color Mode': 'Light' }}
68
- * />
86
+ * >
87
+ * Fixed deposit • 0245
88
+ * </CheckboxItem>
89
+ *
90
+ * // Still supported (deprecated): the `label` prop.
91
+ * <CheckboxItem label="Fixed deposit • 0245" />
69
92
  * ```
70
93
  */
71
94
  declare const CheckboxItem: React.ForwardRefExoticComponent<CheckboxItemProps & React.RefAttributes<View>>;
@@ -0,0 +1,71 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewProps, type ViewStyle } from 'react-native';
3
+ import type { Modes } from '../../design-tokens';
4
+ export type ContentSheetProps = {
5
+ /**
6
+ * Sheet content. The sheet is one big slot: whatever you place here is
7
+ * stacked in a column (separated by the `contentSheet/gap` token) inside the
8
+ * sheet's padding. The sheet has **no fixed height** — it grows and shrinks
9
+ * to fit these children automatically.
10
+ */
11
+ children?: React.ReactNode;
12
+ /**
13
+ * Design-token modes. Cascaded to every slot child via
14
+ * {@link cloneChildrenWithModes} so nested `ListItem`/`Section`/etc. resolve
15
+ * the same theme without you wiring `modes` onto each one.
16
+ */
17
+ modes?: Modes;
18
+ /**
19
+ * Keep the sheet above the on-screen keyboard. When the keyboard opens the
20
+ * sheet rises by exactly the keyboard height; when it closes the sheet drops
21
+ * back. The follow animation is driven entirely on the UI thread
22
+ * (`useAnimatedKeyboard`) so it never schedules a React re-render and stays
23
+ * in perfect sync with the keyboard on both iOS and Android.
24
+ *
25
+ * On web this is a no-op (soft keyboards there don't overlay content).
26
+ * Default `true`.
27
+ */
28
+ avoidKeyboard?: boolean;
29
+ /**
30
+ * Extra gap (px) inserted between the top of the keyboard and the bottom of
31
+ * the sheet while the keyboard is open. Default `0` (sheet sits flush on the
32
+ * keyboard).
33
+ */
34
+ keyboardSpacing?: number;
35
+ /**
36
+ * Add the device's bottom safe-area inset (home indicator) on top of the
37
+ * sheet's bottom padding, so content never sits under the indicator when the
38
+ * sheet rests at the bottom of the screen. Default `true`.
39
+ */
40
+ safeAreaBottom?: boolean;
41
+ /**
42
+ * Pin the sheet to the bottom of its parent (absolute, full width). This is
43
+ * the default behaviour — the sheet "just stays at the bottom".
44
+ *
45
+ * Set to `false` to render the sheet in normal flow instead (e.g. when you
46
+ * compose it inside your own layout container). Keyboard avoidance still
47
+ * works in both modes.
48
+ */
49
+ pinToBottom?: boolean;
50
+ /** Optional style override applied to the sheet container. */
51
+ style?: StyleProp<ViewStyle>;
52
+ } & Omit<ViewProps, 'style' | 'children'>;
53
+ /**
54
+ * ContentSheet — a bottom-anchored surface that is essentially one big slot
55
+ * with padding and rounded top corners, mirroring the Figma "Content Sheet".
56
+ *
57
+ * Behaviour highlights:
58
+ * - **Auto height (free & automatic).** The sheet never sets an explicit
59
+ * height. React Native's layout engine (Yoga) sizes it to its children on
60
+ * the native thread, so when the slot content grows or shrinks the sheet
61
+ * follows with zero JS measurement and zero extra re-renders — the most
62
+ * performant option possible.
63
+ * - **Keyboard avoidance** on iOS and Android via `avoidKeyboard` (UI-thread
64
+ * `useAnimatedKeyboard`, no re-renders).
65
+ * - **Bottom pinned** by default; opt out with `pinToBottom={false}`.
66
+ * - **Token-driven** styling via `getVariableByName` + `modes`, with `modes`
67
+ * cascaded to all slot children.
68
+ */
69
+ declare function ContentSheet({ children, modes, avoidKeyboard, keyboardSpacing, safeAreaBottom, pinToBottom, style, ...rest }: ContentSheetProps): import("react/jsx-runtime").JSX.Element;
70
+ export default ContentSheet;
71
+ //# sourceMappingURL=ContentSheet.d.ts.map
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ import type { Modes } from '../../design-tokens';
4
+ export type HeroSectionProps = {
5
+ /** Headline text rendered by the internal {@link Title}. */
6
+ title?: string;
7
+ /** Optional subtitle shown below the title. Omit to hide it. */
8
+ subtitle?: string;
9
+ /** Horizontal alignment of the title/subtitle block. */
10
+ titleTextAlign?: 'Left' | 'Center';
11
+ /** Whether to render the title block. Ignored when `titleSlot` is provided. */
12
+ showTitle?: boolean;
13
+ /**
14
+ * Fully replace the default title block. When provided, `title`, `subtitle`,
15
+ * `titleTextAlign`, and `showTitle` are ignored. `modes` cascade into the slot.
16
+ */
17
+ titleSlot?: React.ReactNode;
18
+ /**
19
+ * Whether to render the search + filter row. Ignored when `searchSlot`
20
+ * is provided.
21
+ */
22
+ showSearch?: boolean;
23
+ /** Controlled value for the search input. */
24
+ searchValue?: string;
25
+ /** Change handler for the search input. */
26
+ onSearchChange?: (text: string) => void;
27
+ /** Placeholder for the search input. */
28
+ searchPlaceholder?: string;
29
+ /**
30
+ * Fully replace the search input (the flexible left part of the row). When
31
+ * provided, `searchValue`, `onSearchChange`, and `searchPlaceholder` are
32
+ * ignored. `modes` cascade into the slot.
33
+ */
34
+ searchSlot?: React.ReactNode;
35
+ /** Whether to render the trailing filter icon button. */
36
+ showFilter?: boolean;
37
+ /** Icon name for the filter button (from the icon registry). */
38
+ filterIcon?: string;
39
+ /** Press handler for the filter button. */
40
+ onFilterPress?: () => void;
41
+ /** Accessibility label for the filter button. */
42
+ filterAccessibilityLabel?: string;
43
+ /**
44
+ * Fully replace the trailing filter control. When provided, `filterIcon`,
45
+ * `onFilterPress`, and `showFilter` are ignored. `modes` cascade into the slot.
46
+ */
47
+ filterSlot?: React.ReactNode;
48
+ /** Content rendered in the body area below the search row. */
49
+ children?: React.ReactNode;
50
+ /** Mode configuration for design-token theming. */
51
+ modes?: Modes;
52
+ /** Style overrides applied to the outer container. */
53
+ style?: StyleProp<ViewStyle>;
54
+ testID?: string;
55
+ };
56
+ /**
57
+ * HeroSection is a page-level header block: a title (with optional subtitle),
58
+ * an optional search row (a flexible search input plus a trailing filter
59
+ * button), and a free-form content slot below.
60
+ *
61
+ * All spacing/background values resolve from the `HeroSection / Output` design
62
+ * token collection via `getVariableByName`. `modes` cascade to every slot and
63
+ * child component so downstream tokens stay in sync.
64
+ *
65
+ * @example
66
+ * ```tsx
67
+ * <HeroSection
68
+ * title="Transactions"
69
+ * subtitle="Last 30 days"
70
+ * searchValue={query}
71
+ * onSearchChange={setQuery}
72
+ * onFilterPress={openFilters}
73
+ * >
74
+ * <TransactionList data={items} />
75
+ * </HeroSection>
76
+ * ```
77
+ */
78
+ declare function HeroSection({ title, subtitle, titleTextAlign, showTitle, titleSlot, showSearch, searchValue, onSearchChange, searchPlaceholder, searchSlot, showFilter, filterIcon, onFilterPress, filterAccessibilityLabel, filterSlot, children, modes: propModes, style, testID, }: HeroSectionProps): import("react/jsx-runtime").JSX.Element;
79
+ export default HeroSection;
80
+ //# sourceMappingURL=HeroSection.d.ts.map
@@ -1,6 +1,15 @@
1
1
  import React from 'react';
2
- import { type ImageSourcePropType, type ImageStyle, type StyleProp, type ViewStyle, type ImageResizeMode } from 'react-native';
2
+ import { type ImageSourcePropType, type ImageStyle, type StyleProp, type ViewStyle, type ImageResizeMode, type ImageLoadEventData, type ImageErrorEventData, type NativeSyntheticEvent } from 'react-native';
3
3
  type ImageResizeMethod = 'auto' | 'resize' | 'scale' | 'none';
4
+ /**
5
+ * iOS URL cache control (maps to RN's `source.cache`, no-op on Android/web):
6
+ * - `'default'` — use the native platform's default caching.
7
+ * - `'reload'` — ignore any cache, always fetch from the network.
8
+ * - `'force-cache'` — use the cached response regardless of age; fetch
9
+ * only if absent.
10
+ * - `'only-if-cached'` — use the cache only; never hit the network.
11
+ */
12
+ type ImageCacheControl = 'default' | 'reload' | 'force-cache' | 'only-if-cached';
4
13
  export type ImageProps = {
5
14
  /**
6
15
  * Image source. Accepts the same shapes as React Native's `<Image>` plus a
@@ -61,8 +70,24 @@ export type ImageProps = {
61
70
  * the group.
62
71
  */
63
72
  loading?: boolean | undefined;
73
+ /**
74
+ * iOS URL cache strategy applied to remote (`{ uri }`) sources. Injected into
75
+ * the RN `source.cache` field so callers don't have to re-shape the source
76
+ * object themselves. No-op for local/required assets and on Android/web.
77
+ */
78
+ cache?: ImageCacheControl | undefined;
79
+ /**
80
+ * Called when the image finishes loading successfully. Forwarded straight to
81
+ * RN's `<Image onLoad>`.
82
+ */
83
+ onLoad?: ((event: NativeSyntheticEvent<ImageLoadEventData>) => void) | undefined;
84
+ /**
85
+ * Called when the image fails to load. Forwarded straight to RN's
86
+ * `<Image onError>`.
87
+ */
88
+ onError?: ((event: NativeSyntheticEvent<ImageErrorEventData>) => void) | undefined;
64
89
  };
65
- declare function Image({ imageSource, ratio, resizeMode, resizeMethod, width, height, borderRadius, style, accessibilityLabel, accessibilityElementsHidden, importantForAccessibility, loading, }: ImageProps): import("react/jsx-runtime").JSX.Element;
90
+ declare function Image({ imageSource, ratio, resizeMode, resizeMethod, width, height, borderRadius, style, accessibilityLabel, accessibilityElementsHidden, importantForAccessibility, loading, cache, onLoad, onError, }: ImageProps): import("react/jsx-runtime").JSX.Element;
66
91
  declare const _default: React.MemoExoticComponent<typeof Image>;
67
92
  export default _default;
68
93
  //# sourceMappingURL=Image.d.ts.map
@@ -0,0 +1,73 @@
1
+ import React from 'react';
2
+ import { type TextStyle, type StyleProp, type GestureResponderEvent } from 'react-native';
3
+ import type { Modes } from '../../design-tokens';
4
+ export type LinkProps = {
5
+ /**
6
+ * The link label. You may also pass content as JSX children
7
+ * (e.g. `<Link>Terms</Link>`); when both are provided, `children` wins.
8
+ * Mirrors the {@link Text} API so `Link` is a near-drop-in, underlined
9
+ * sibling of `Text`.
10
+ */
11
+ text?: string;
12
+ /** Child nodes (string or nested `Text`/`Link`). Wins over `text`. */
13
+ children?: React.ReactNode;
14
+ /**
15
+ * Called when the link is activated. Navigation is the consumer's job
16
+ * (e.g. `Linking.openURL`, a router push) — `Link` is intentionally
17
+ * navigation-agnostic and React Native friendly (no `href`/`target`).
18
+ */
19
+ onPress?: (event: GestureResponderEvent) => void;
20
+ /** Disables interaction and dims the label. */
21
+ disabled?: boolean;
22
+ /**
23
+ * Layout sizing (matches the Figma `autolayout` variant).
24
+ * - `Fill` (default): the label stretches to fill the parent's width, so
25
+ * `textAlign="Center"` is visible and the whole line is tappable.
26
+ * - `Hug`: the label hugs its content width.
27
+ */
28
+ autolayout?: 'Fill' | 'Hug';
29
+ /** Horizontal alignment of the label (matches `Text`). */
30
+ textAlign?: 'Left' | 'Center';
31
+ /** Modes configuration for design token resolution (cascades from `TextSegment`). */
32
+ modes?: Modes;
33
+ /** Style override for the label. */
34
+ style?: StyleProp<TextStyle>;
35
+ /** Number of lines to limit the label to. */
36
+ numberOfLines?: number;
37
+ /** Never truncate — drops the clamp/ellipsis and lets the label overflow. See {@link Text}. */
38
+ disableTruncation?: boolean;
39
+ /** Force a single non-wrapping line (implies `disableTruncation`). See {@link Text}. */
40
+ singleLine?: boolean;
41
+ /** Accessibility label; defaults to the resolved text content. */
42
+ accessibilityLabel?: string;
43
+ /** Accessibility hint describing what activating the link does. */
44
+ accessibilityHint?: string;
45
+ };
46
+ /**
47
+ * Link — an underlined, pressable text primitive.
48
+ *
49
+ * It renders a single React Native `<Text>` (not a `Pressable`), so it flows
50
+ * inline and can be nested inside {@link TextSegment} exactly like a `Text`
51
+ * run — the React Native equivalent of an `<a>` inside a `<p>`. Font family,
52
+ * size, weight, line-height and letter-spacing come from the dedicated `link/*`
53
+ * tokens, while the colour resolves from `text/foreground` (so a link sits on
54
+ * the same colour as the surrounding copy). The label is always underlined.
55
+ *
56
+ * @example Standalone
57
+ * ```tsx
58
+ * <Link text="Forgot PIN?" onPress={() => navigation.navigate('ResetPin')} />
59
+ * ```
60
+ *
61
+ * @example Inline inside TextSegment
62
+ * ```tsx
63
+ * <TextSegment>
64
+ * <Text>By continuing you agree to our </Text>
65
+ * <Link onPress={openTerms}>Terms</Link>
66
+ * <Text>.</Text>
67
+ * </TextSegment>
68
+ * ```
69
+ */
70
+ declare function Link({ text, children, onPress, disabled, autolayout, textAlign, modes, style, numberOfLines, disableTruncation, singleLine, accessibilityLabel, accessibilityHint, }: LinkProps): import("react/jsx-runtime").JSX.Element;
71
+ declare const _default: React.MemoExoticComponent<typeof Link>;
72
+ export default _default;
73
+ //# sourceMappingURL=Link.d.ts.map
@@ -36,6 +36,7 @@ export { default as FullscreenModal, type FullscreenModalProps } from './Fullscr
36
36
  export { default as Form, type FormProps } from './Form/Form';
37
37
  export { useFormContext } from './Form/Form';
38
38
  export { default as FormField, type FormFieldProps, type FormFieldType } from './FormField/FormField';
39
+ export { default as ContentSheet, type ContentSheetProps } from './ContentSheet/ContentSheet';
39
40
  export { default as CircularProgressBar, type CircularProgressBarProps } from './CircularProgressBar/CircularProgressBar';
40
41
  export { default as CircularProgressBarDoted, type CircularProgressBarDotedProps } from './CircularProgressBarDoted/CircularProgressBarDoted';
41
42
  export { default as CircularRating, type CircularRatingProps } from './CircularRating/CircularRating';
@@ -45,6 +46,7 @@ export { default as ComparisonBar, type ComparisonBarProps, type ComparisonBarIt
45
46
  export { default as AllocationComparisonChart, type AllocationComparisonChartProps, type AllocationSegment } from './AllocationComparisonChart/AllocationComparisonChart';
46
47
  export { default as MonthlyStatusGrid, CalendarGlyph, type MonthlyStatusGridProps, type MonthlyStatusGridMonth, type MonthlyStatus, type CalendarGlyphProps } from './MonthlyStatusGrid/MonthlyStatusGrid';
47
48
  export { default as Gauge, type GaugeProps } from './Gauge/Gauge';
49
+ export { default as HeroSection, type HeroSectionProps } from './HeroSection/HeroSection';
48
50
  export { default as HoldingsCard, type HoldingsCardProps } from './HoldingsCard/HoldingsCard';
49
51
  export { default as HStack, type HStackProps } from './HStack/HStack';
50
52
  export { default as Icon, type IconProps } from './Icon/Icon';
@@ -52,6 +54,7 @@ export { default as IconButton } from './IconButton/IconButton';
52
54
  export { default as IconCapsule } from './IconCapsule/IconCapsule';
53
55
  export { default as Image, type ImageProps } from './Image/Image';
54
56
  export { default as LazyList } from './LazyList/LazyList';
57
+ export { default as Link, type LinkProps } from './Link/Link';
55
58
  export { default as LinearMeter, type LinearMeterProps } from './LinearMeter/LinearMeter';
56
59
  export { default as LinearProgress, type LinearProgressProps } from './LinearProgress/LinearProgress';
57
60
  export { default as ListGroup } from './ListGroup/ListGroup';
@@ -78,6 +78,7 @@ export declare const FIGMA_MODES: {
78
78
  readonly "contentInset/Right": readonly ["Default", "S", "M", "L"];
79
79
  readonly "ContentSheet / Output": readonly ["Default"];
80
80
  readonly Context: readonly ["Default", "Nudge&Alert", "CTACard", "ListItem"];
81
+ readonly "context 10": readonly ["Default", "Profile card"];
81
82
  readonly "context 8": readonly ["Default", "Section"];
82
83
  readonly "context 9": readonly ["Default", "Stack"];
83
84
  readonly Context2: readonly ["Default", "AppBar"];
@@ -116,6 +117,7 @@ export declare const FIGMA_MODES: {
116
117
  readonly FullScreenModal: readonly ["Default"];
117
118
  readonly Gap: readonly ["S", "M", "L", "None"];
118
119
  readonly "Gauge / Output": readonly ["Default"];
120
+ readonly "Grid / Output": readonly ["Default"];
119
121
  readonly "Handle Boolean": readonly ["False", "True"];
120
122
  readonly "Heading / Output": readonly ["Default"];
121
123
  readonly "Heading text": readonly ["Default", "Slot"];
@@ -139,6 +141,7 @@ export declare const FIGMA_MODES: {
139
141
  readonly "LinearProgress / Output": readonly ["Default"];
140
142
  readonly "LinearProgress Size": readonly ["M", "L"];
141
143
  readonly "Link / Output": readonly ["Default"];
144
+ readonly "Link Apperances": readonly ["Neutral", "Primary", "Secondary", "Tertiary"];
142
145
  readonly "List Item / Output": readonly ["Default"];
143
146
  readonly "List Item Style": readonly ["Default", "Boxed", "Minimal"];
144
147
  readonly "listGroup / Output": readonly ["Default"];
@@ -157,6 +160,7 @@ export declare const FIGMA_MODES: {
157
160
  readonly NavArrow: readonly ["Default"];
158
161
  readonly "NavArrow / Output": readonly ["Default"];
159
162
  readonly "NavArrow Direction": readonly ["Left&Right", "Top&Bottom"];
163
+ readonly "New Collection": readonly ["Default"];
160
164
  readonly "NoteInput / Output": readonly ["Default"];
161
165
  readonly "Nudge / Output": readonly ["Default"];
162
166
  readonly "Nudge padding": readonly ["Default", "None"];
@@ -178,12 +182,16 @@ export declare const FIGMA_MODES: {
178
182
  readonly "Product Merchandising card": readonly ["Default"];
179
183
  readonly "ProductLabel / Output": readonly ["Default"];
180
184
  readonly "ProductOverview / Output": readonly ["Default"];
185
+ readonly "Profile Card Appearance": readonly ["Default", "Premium"];
181
186
  readonly "ProgressBadge / Output": readonly ["Default"];
182
187
  readonly ProjectionMarker: readonly ["Default"];
183
188
  readonly "QR code / Output": readonly ["Idle"];
184
189
  readonly "Radio / Output": readonly ["Default"];
185
190
  readonly Radius: readonly ["S", "M", "L", "None"];
186
191
  readonly "RangeTrack / Output": readonly ["Default"];
192
+ readonly "Rating / Output": readonly ["Default"];
193
+ readonly "Rating Star / Output": readonly ["Default"];
194
+ readonly "Rating Star State": readonly ["idle", "selected"];
187
195
  readonly "RechargeCard / Output": readonly ["Default"];
188
196
  readonly rotfl: readonly ["Default"];
189
197
  readonly "SavingsGoalSummary / Output": readonly ["Default"];
@@ -4,7 +4,7 @@
4
4
  * Auto-generated from SVG files in src/icons/
5
5
  * DO NOT EDIT MANUALLY - Run "npm run icons:generate" to regenerate
6
6
  *
7
- * Generated: 2026-06-29T11:40:01.320Z
7
+ * Generated: 2026-07-01T12:55:42.353Z
8
8
  */
9
9
  export declare const iconRegistry: Record<string, {
10
10
  path: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jfs-components",
3
- "version": "0.1.19",
3
+ "version": "0.1.23",
4
4
  "description": "React Native Jio Finance Components Library",
5
5
  "author": "sunshuaiqi@gmail.com",
6
6
  "license": "MIT",
@@ -21,7 +21,25 @@ export type CheckboxItemProps = {
21
21
  onValueChange?: (checked: boolean) => void
22
22
  /** Whether the row is disabled — both the checkbox and row press handler are disabled. */
23
23
  disabled?: boolean
24
- /** The label text rendered next to the checkbox. */
24
+ /**
25
+ * Content rendered in the row's label slot (between the leading and trailing
26
+ * edges). This is the primary way to supply the label and mirrors the Figma
27
+ * "slot" — pass a plain string for the default token-styled label, or any
28
+ * custom node (e.g. a `<Text>`, a row of `<Text>` + `<Badge>`, etc.) for full
29
+ * control. Custom nodes receive the same `modes` as the parent.
30
+ *
31
+ * When both `children` and the legacy {@link label} prop are provided,
32
+ * `children` wins.
33
+ */
34
+ children?: React.ReactNode
35
+ /**
36
+ * The label content rendered next to the checkbox.
37
+ *
38
+ * @deprecated Prefer the `children` slot instead
39
+ * (`<CheckboxItem>Fixed deposit • 0245</CheckboxItem>`). `label` is kept for
40
+ * backward compatibility and behaves identically — it is used only when no
41
+ * `children` are provided.
42
+ */
25
43
  label?: React.ReactNode
26
44
  /**
27
45
  * Position of the checkbox control relative to the label.
@@ -71,13 +89,18 @@ export type CheckboxItemProps = {
71
89
  * ```tsx
72
90
  * const [checked, setChecked] = useState(false)
73
91
  *
92
+ * // Recommended: pass the label via the children slot.
74
93
  * <CheckboxItem
75
- * label="Fixed deposit • 0245"
76
94
  * checked={checked}
77
95
  * onValueChange={setChecked}
78
96
  * control="leading"
79
97
  * modes={{ 'Color Mode': 'Light' }}
80
- * />
98
+ * >
99
+ * Fixed deposit • 0245
100
+ * </CheckboxItem>
101
+ *
102
+ * // Still supported (deprecated): the `label` prop.
103
+ * <CheckboxItem label="Fixed deposit • 0245" />
81
104
  * ```
82
105
  */
83
106
  const CheckboxItem = forwardRef<View, CheckboxItemProps>(function CheckboxItem({
@@ -85,7 +108,8 @@ const CheckboxItem = forwardRef<View, CheckboxItemProps>(function CheckboxItem({
85
108
  defaultChecked = false,
86
109
  onValueChange,
87
110
  disabled = false,
88
- label = 'Fixed deposit • 0245',
111
+ children,
112
+ label,
89
113
  control = 'leading',
90
114
  endSlot,
91
115
  endSlotWidth = 80,
@@ -94,6 +118,20 @@ const CheckboxItem = forwardRef<View, CheckboxItemProps>(function CheckboxItem({
94
118
  labelStyle,
95
119
  accessibilityLabel,
96
120
  }: CheckboxItemProps, ref: React.Ref<View>) {
121
+ // Label slot resolution — the `children` slot is the primary API; the legacy
122
+ // `label` prop is a backward-compatible fallback. Precedence:
123
+ // 1. `children`, when provided (non-null / non-false).
124
+ // 2. otherwise the legacy `label` prop, whenever it was passed at all —
125
+ // including an explicit `null`/`false`, which (as before) hides the
126
+ // label entirely.
127
+ // 3. otherwise the Figma placeholder, so the default story still renders
128
+ // something meaningful.
129
+ const hasChildren = children != null && children !== false
130
+ const slotContent: React.ReactNode = hasChildren
131
+ ? children
132
+ : label !== undefined
133
+ ? label
134
+ : 'Fixed deposit • 0245'
97
135
  const isTrailing = control === 'trailing'
98
136
  const isControlled = controlledChecked !== undefined
99
137
  const [internalChecked, setInternalChecked] = useState(defaultChecked)
@@ -146,7 +184,7 @@ const CheckboxItem = forwardRef<View, CheckboxItemProps>(function CheckboxItem({
146
184
  }
147
185
 
148
186
  const a11yLabel =
149
- accessibilityLabel ?? (typeof label === 'string' ? label : undefined)
187
+ accessibilityLabel ?? (typeof slotContent === 'string' ? slotContent : undefined)
150
188
 
151
189
  const checkboxNode = (
152
190
  <Checkbox
@@ -158,16 +196,23 @@ const CheckboxItem = forwardRef<View, CheckboxItemProps>(function CheckboxItem({
158
196
  />
159
197
  )
160
198
 
199
+ // A plain string/number renders with the token-driven label style. Any other
200
+ // node is treated as custom slot content: it fills the label region and
201
+ // receives the parent `modes` (so nested design-system components theme
202
+ // correctly). An explicit null/false hides the label entirely (legacy
203
+ // behaviour of the `label` prop).
204
+ const isTextSlot =
205
+ typeof slotContent === 'string' || typeof slotContent === 'number'
161
206
  const labelNode =
162
- label != null && label !== false ? (
163
- typeof label === 'string' || typeof label === 'number' ? (
164
- <Text style={[resolvedLabelStyle, labelStyle]} selectable={false}>
165
- {label}
166
- </Text>
167
- ) : (
168
- <View style={{ flex: 1, minWidth: 0 }}>{label}</View>
169
- )
170
- ) : null
207
+ slotContent == null || slotContent === false ? null : isTextSlot ? (
208
+ <Text style={[resolvedLabelStyle, labelStyle]} selectable={false}>
209
+ {slotContent}
210
+ </Text>
211
+ ) : (
212
+ <View style={{ flex: 1, minWidth: 0 }}>
213
+ {cloneChildrenWithModes(slotContent, modes)}
214
+ </View>
215
+ )
171
216
 
172
217
  const endSlotNode = endSlot ? (
173
218
  <View