jfs-components 0.1.2 → 0.1.12
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.
- package/CHANGELOG.md +45 -0
- package/lib/commonjs/components/Accordion/Accordion.js +2 -1
- package/lib/commonjs/components/AccordionCheckbox/AccordionCheckbox.js +4 -3
- package/lib/commonjs/components/AccountCard/AccountCard.js +4 -3
- package/lib/commonjs/components/AllocationComparisonChart/AllocationComparisonChart.js +9 -6
- package/lib/commonjs/components/AmountInput/AmountInput.js +8 -5
- package/lib/commonjs/components/AreaLineChart/AreaLineChart.js +11 -7
- package/lib/commonjs/components/Badge/Badge.js +47 -8
- package/lib/commonjs/components/BenefitCard/BenefitCard.js +231 -0
- package/lib/commonjs/components/BrandChip/BrandChip.js +3 -3
- package/lib/commonjs/components/Button/Button.js +2 -1
- package/lib/commonjs/components/CardAdvisory/CardAdvisory.js +2 -1
- package/lib/commonjs/components/CardBankAccount/CardBankAccount.js +3 -2
- package/lib/commonjs/components/CardCTA/CardCTA.js +197 -27
- package/lib/commonjs/components/CardInsight/CardInsight.js +5 -1
- package/lib/commonjs/components/CcCard/CcCard.js +470 -0
- package/lib/commonjs/components/Checkbox/Checkbox.js +4 -3
- package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +4 -3
- package/lib/commonjs/components/CircularProgressBar/CircularProgressBar.js +7 -3
- package/lib/commonjs/components/CircularProgressBarDoted/CircularProgressBarDoted.js +3 -2
- package/lib/commonjs/components/CircularRating/CircularRating.js +2 -1
- package/lib/commonjs/components/ClusterBubble/ClusterBubble.js +3 -2
- package/lib/commonjs/components/CompareTable/CompareTable.js +401 -0
- package/lib/commonjs/components/ComparisonBar/ComparisonBar.js +266 -0
- package/lib/commonjs/components/CoverageBarComparison/CoverageBarComparison.js +3 -2
- package/lib/commonjs/components/DonutChart/DonutChart.js +4 -3
- package/lib/commonjs/components/Dropdown/Dropdown.js +3 -2
- package/lib/commonjs/components/DropdownInput/DropdownInput.js +38 -5
- package/lib/commonjs/components/ExpandableCheckbox/ExpandableCheckbox.js +2 -1
- package/lib/commonjs/components/FormField/FormField.js +45 -4
- package/lib/commonjs/components/Gauge/Gauge.js +1 -1
- package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +3 -2
- package/lib/commonjs/components/InputSearch/InputSearch.js +6 -4
- package/lib/commonjs/components/InstitutionBadge/InstitutionBadge.js +2 -1
- package/lib/commonjs/components/ListGroup/ListGroup.js +2 -1
- package/lib/commonjs/components/ListItem/ListItem.js +3 -2
- package/lib/commonjs/components/MediaCard/MediaCard.js +4 -2
- package/lib/commonjs/components/MetricLegendItem/MetricLegendItem.js +3 -2
- package/lib/commonjs/components/MonthlyStatusGrid/MonthlyStatusGrid.js +6 -3
- package/lib/commonjs/components/NoteInput/NoteInput.js +6 -5
- package/lib/commonjs/components/PdpCcCard/PdpCcCard.js +273 -0
- package/lib/commonjs/components/PoweredByLabel/PoweredByLabel.js +3 -2
- package/lib/commonjs/components/ProductMerchandisingCard/ProductMerchandisingCard.js +427 -0
- package/lib/commonjs/components/ProductOverview/ProductOverview.js +4 -3
- package/lib/commonjs/components/ProgressBadge/ProgressBadge.js +2 -2
- package/lib/commonjs/components/ProjectionMarker/ProjectionMarker.js +162 -0
- package/lib/commonjs/components/Radio/Radio.js +5 -5
- package/lib/commonjs/components/Section/Section.js +3 -2
- package/lib/commonjs/components/Slider/Slider.js +474 -0
- package/lib/commonjs/components/Stack/Stack.js +86 -0
- package/lib/commonjs/components/SuggestiveSearch/SuggestiveSearch.js +10 -1
- package/lib/commonjs/components/SummaryTile/SummaryTile.js +3 -2
- package/lib/commonjs/components/Table/Table.js +324 -0
- package/lib/commonjs/components/Text/Text.js +2 -1
- package/lib/commonjs/components/TextInput/TextInput.js +22 -9
- package/lib/commonjs/components/TextSegment/TextSegment.js +119 -0
- package/lib/commonjs/components/ThreadHero/ThreadHero.js +4 -5
- package/lib/commonjs/components/Title/Title.js +2 -1
- package/lib/commonjs/components/Toast/Toast.js +3 -2
- package/lib/commonjs/components/TransactionBubble/TransactionBubble.js +2 -1
- package/lib/commonjs/components/TransactionStatus/TransactionStatus.js +3 -2
- package/lib/commonjs/components/UpiHandle/UpiHandle.js +2 -2
- package/lib/commonjs/components/index.js +107 -0
- package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/commonjs/design-tokens/figma-modes.generated.js +39 -9
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/commonjs/utils/GlassFill/GlassFill.js +271 -0
- package/lib/commonjs/utils/GlassFill/GlassFill.web.js +120 -0
- package/lib/commonjs/utils/react-utils.js +78 -0
- package/lib/commonjs/utils/web-platform-utils.js +59 -0
- package/lib/module/components/Accordion/Accordion.js +3 -2
- package/lib/module/components/AccordionCheckbox/AccordionCheckbox.js +5 -4
- package/lib/module/components/AccountCard/AccountCard.js +5 -4
- package/lib/module/components/AllocationComparisonChart/AllocationComparisonChart.js +10 -7
- package/lib/module/components/AmountInput/AmountInput.js +6 -4
- package/lib/module/components/AreaLineChart/AreaLineChart.js +12 -8
- package/lib/module/components/Badge/Badge.js +49 -10
- package/lib/module/components/BenefitCard/BenefitCard.js +225 -0
- package/lib/module/components/BrandChip/BrandChip.js +4 -4
- package/lib/module/components/Button/Button.js +3 -2
- package/lib/module/components/CardAdvisory/CardAdvisory.js +3 -2
- package/lib/module/components/CardBankAccount/CardBankAccount.js +4 -3
- package/lib/module/components/CardCTA/CardCTA.js +198 -28
- package/lib/module/components/CardInsight/CardInsight.js +5 -1
- package/lib/module/components/CcCard/CcCard.js +464 -0
- package/lib/module/components/Checkbox/Checkbox.js +5 -4
- package/lib/module/components/CheckboxItem/CheckboxItem.js +5 -4
- package/lib/module/components/CircularProgressBar/CircularProgressBar.js +8 -4
- package/lib/module/components/CircularProgressBarDoted/CircularProgressBarDoted.js +4 -3
- package/lib/module/components/CircularRating/CircularRating.js +3 -2
- package/lib/module/components/ClusterBubble/ClusterBubble.js +4 -3
- package/lib/module/components/CompareTable/CompareTable.js +396 -0
- package/lib/module/components/ComparisonBar/ComparisonBar.js +260 -0
- package/lib/module/components/CoverageBarComparison/CoverageBarComparison.js +4 -3
- package/lib/module/components/DonutChart/DonutChart.js +5 -4
- package/lib/module/components/Dropdown/Dropdown.js +4 -3
- package/lib/module/components/DropdownInput/DropdownInput.js +40 -7
- package/lib/module/components/ExpandableCheckbox/ExpandableCheckbox.js +2 -1
- package/lib/module/components/FormField/FormField.js +48 -7
- package/lib/module/components/Gauge/Gauge.js +1 -1
- package/lib/module/components/HoldingsCard/HoldingsCard.js +4 -3
- package/lib/module/components/InputSearch/InputSearch.js +6 -4
- package/lib/module/components/InstitutionBadge/InstitutionBadge.js +3 -2
- package/lib/module/components/ListGroup/ListGroup.js +3 -2
- package/lib/module/components/ListItem/ListItem.js +4 -3
- package/lib/module/components/MediaCard/MediaCard.js +4 -2
- package/lib/module/components/MetricLegendItem/MetricLegendItem.js +4 -3
- package/lib/module/components/MonthlyStatusGrid/MonthlyStatusGrid.js +7 -4
- package/lib/module/components/NoteInput/NoteInput.js +7 -6
- package/lib/module/components/PdpCcCard/PdpCcCard.js +267 -0
- package/lib/module/components/PoweredByLabel/PoweredByLabel.js +4 -3
- package/lib/module/components/ProductMerchandisingCard/ProductMerchandisingCard.js +421 -0
- package/lib/module/components/ProductOverview/ProductOverview.js +5 -4
- package/lib/module/components/ProgressBadge/ProgressBadge.js +3 -3
- package/lib/module/components/ProjectionMarker/ProjectionMarker.js +157 -0
- package/lib/module/components/Radio/Radio.js +5 -4
- package/lib/module/components/Section/Section.js +4 -3
- package/lib/module/components/Slider/Slider.js +469 -0
- package/lib/module/components/Stack/Stack.js +81 -0
- package/lib/module/components/SuggestiveSearch/SuggestiveSearch.js +10 -1
- package/lib/module/components/SummaryTile/SummaryTile.js +4 -3
- package/lib/module/components/Table/Table.js +315 -0
- package/lib/module/components/Text/Text.js +3 -2
- package/lib/module/components/TextInput/TextInput.js +24 -11
- package/lib/module/components/TextSegment/TextSegment.js +114 -0
- package/lib/module/components/ThreadHero/ThreadHero.js +5 -6
- package/lib/module/components/Title/Title.js +3 -2
- package/lib/module/components/Toast/Toast.js +4 -3
- package/lib/module/components/TransactionBubble/TransactionBubble.js +3 -2
- package/lib/module/components/TransactionStatus/TransactionStatus.js +4 -3
- package/lib/module/components/UpiHandle/UpiHandle.js +3 -3
- package/lib/module/components/index.js +11 -0
- package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/module/design-tokens/figma-modes.generated.js +39 -9
- package/lib/module/icons/registry.js +1 -1
- package/lib/module/utils/GlassFill/GlassFill.js +265 -0
- package/lib/module/utils/GlassFill/GlassFill.web.js +115 -0
- package/lib/module/utils/react-utils.js +75 -0
- package/lib/module/utils/web-platform-utils.js +58 -0
- package/lib/typescript/src/components/Accordion/Accordion.d.ts +7 -1
- package/lib/typescript/src/components/AccordionCheckbox/AccordionCheckbox.d.ts +7 -1
- package/lib/typescript/src/components/AccountCard/AccountCard.d.ts +7 -1
- package/lib/typescript/src/components/AllocationComparisonChart/AllocationComparisonChart.d.ts +7 -1
- package/lib/typescript/src/components/AmountInput/AmountInput.d.ts +3 -2
- package/lib/typescript/src/components/AreaLineChart/AreaLineChart.d.ts +8 -1
- package/lib/typescript/src/components/Badge/Badge.d.ts +32 -2
- package/lib/typescript/src/components/BenefitCard/BenefitCard.d.ts +93 -0
- package/lib/typescript/src/components/BrandChip/BrandChip.d.ts +7 -1
- package/lib/typescript/src/components/Button/Button.d.ts +7 -1
- package/lib/typescript/src/components/CardAdvisory/CardAdvisory.d.ts +7 -1
- package/lib/typescript/src/components/CardBankAccount/CardBankAccount.d.ts +7 -1
- package/lib/typescript/src/components/CardCTA/CardCTA.d.ts +27 -5
- package/lib/typescript/src/components/CcCard/CcCard.d.ts +137 -0
- package/lib/typescript/src/components/Checkbox/Checkbox.d.ts +3 -2
- package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +2 -2
- package/lib/typescript/src/components/CircularProgressBar/CircularProgressBar.d.ts +7 -1
- package/lib/typescript/src/components/CircularProgressBarDoted/CircularProgressBarDoted.d.ts +7 -1
- package/lib/typescript/src/components/CircularRating/CircularRating.d.ts +7 -1
- package/lib/typescript/src/components/ClusterBubble/ClusterBubble.d.ts +7 -1
- package/lib/typescript/src/components/CompareTable/CompareTable.d.ts +94 -0
- package/lib/typescript/src/components/ComparisonBar/ComparisonBar.d.ts +118 -0
- package/lib/typescript/src/components/CoverageBarComparison/CoverageBarComparison.d.ts +7 -1
- package/lib/typescript/src/components/DonutChart/DonutChart.d.ts +7 -1
- package/lib/typescript/src/components/Dropdown/Dropdown.d.ts +7 -1
- package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +26 -1
- package/lib/typescript/src/components/ExpandableCheckbox/ExpandableCheckbox.d.ts +7 -1
- package/lib/typescript/src/components/FormField/FormField.d.ts +2 -2
- package/lib/typescript/src/components/HoldingsCard/HoldingsCard.d.ts +7 -1
- package/lib/typescript/src/components/InputSearch/InputSearch.d.ts +23 -2
- package/lib/typescript/src/components/InstitutionBadge/InstitutionBadge.d.ts +7 -1
- package/lib/typescript/src/components/ListGroup/ListGroup.d.ts +7 -1
- package/lib/typescript/src/components/ListItem/ListItem.d.ts +7 -1
- package/lib/typescript/src/components/MetricLegendItem/MetricLegendItem.d.ts +7 -1
- package/lib/typescript/src/components/MonthlyStatusGrid/MonthlyStatusGrid.d.ts +14 -2
- package/lib/typescript/src/components/NoteInput/NoteInput.d.ts +19 -2
- package/lib/typescript/src/components/PdpCcCard/PdpCcCard.d.ts +84 -0
- package/lib/typescript/src/components/PoweredByLabel/PoweredByLabel.d.ts +7 -1
- package/lib/typescript/src/components/ProductMerchandisingCard/ProductMerchandisingCard.d.ts +87 -0
- package/lib/typescript/src/components/ProductOverview/ProductOverview.d.ts +7 -1
- package/lib/typescript/src/components/ProgressBadge/ProgressBadge.d.ts +7 -1
- package/lib/typescript/src/components/ProjectionMarker/ProjectionMarker.d.ts +88 -0
- package/lib/typescript/src/components/Radio/Radio.d.ts +3 -2
- package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +2 -2
- package/lib/typescript/src/components/Section/Section.d.ts +7 -1
- package/lib/typescript/src/components/Slider/Slider.d.ts +105 -0
- package/lib/typescript/src/components/Stack/Stack.d.ts +81 -0
- package/lib/typescript/src/components/SummaryTile/SummaryTile.d.ts +7 -1
- package/lib/typescript/src/components/Table/Table.d.ts +139 -0
- package/lib/typescript/src/components/Text/Text.d.ts +7 -1
- package/lib/typescript/src/components/TextInput/TextInput.d.ts +9 -29
- package/lib/typescript/src/components/TextSegment/TextSegment.d.ts +106 -0
- package/lib/typescript/src/components/ThreadHero/ThreadHero.d.ts +7 -1
- package/lib/typescript/src/components/Title/Title.d.ts +7 -1
- package/lib/typescript/src/components/Toast/Toast.d.ts +7 -1
- package/lib/typescript/src/components/TransactionBubble/TransactionBubble.d.ts +7 -1
- package/lib/typescript/src/components/TransactionStatus/TransactionStatus.d.ts +7 -1
- package/lib/typescript/src/components/UpiHandle/UpiHandle.d.ts +7 -1
- package/lib/typescript/src/components/index.d.ts +14 -3
- package/lib/typescript/src/design-tokens/figma-modes.generated.d.ts +22 -2
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/lib/typescript/src/utils/GlassFill/GlassFill.d.ts +84 -0
- package/lib/typescript/src/utils/GlassFill/GlassFill.web.d.ts +43 -0
- package/lib/typescript/src/utils/react-utils.d.ts +47 -0
- package/lib/typescript/src/utils/web-platform-utils.d.ts +36 -0
- package/package.json +2 -1
- package/src/components/Accordion/Accordion.tsx +9 -2
- package/src/components/AccordionCheckbox/AccordionCheckbox.tsx +10 -3
- package/src/components/AccountCard/AccountCard.tsx +10 -3
- package/src/components/AllocationComparisonChart/AllocationComparisonChart.tsx +14 -4
- package/src/components/AmountInput/AmountInput.tsx +7 -5
- package/src/components/AreaLineChart/AreaLineChart.tsx +15 -5
- package/src/components/Badge/Badge.tsx +78 -8
- package/src/components/BenefitCard/BenefitCard.tsx +309 -0
- package/src/components/BrandChip/BrandChip.tsx +9 -3
- package/src/components/Button/Button.tsx +9 -2
- package/src/components/CardAdvisory/CardAdvisory.tsx +9 -2
- package/src/components/CardBankAccount/CardBankAccount.tsx +9 -2
- package/src/components/CardCTA/CardCTA.tsx +214 -41
- package/src/components/CardInsight/CardInsight.tsx +7 -1
- package/src/components/CcCard/CcCard.tsx +598 -0
- package/src/components/Checkbox/Checkbox.tsx +5 -4
- package/src/components/CheckboxItem/CheckboxItem.tsx +5 -4
- package/src/components/CircularProgressBar/CircularProgressBar.tsx +14 -4
- package/src/components/CircularProgressBarDoted/CircularProgressBarDoted.tsx +10 -3
- package/src/components/CircularRating/CircularRating.tsx +9 -2
- package/src/components/ClusterBubble/ClusterBubble.tsx +9 -2
- package/src/components/CompareTable/CompareTable.tsx +525 -0
- package/src/components/ComparisonBar/ComparisonBar.tsx +356 -0
- package/src/components/CoverageBarComparison/CoverageBarComparison.tsx +9 -2
- package/src/components/DonutChart/DonutChart.tsx +10 -3
- package/src/components/Dropdown/Dropdown.tsx +9 -2
- package/src/components/DropdownInput/DropdownInput.tsx +64 -5
- package/src/components/ExpandableCheckbox/ExpandableCheckbox.tsx +8 -1
- package/src/components/FormField/FormField.tsx +52 -6
- package/src/components/Gauge/Gauge.tsx +1 -1
- package/src/components/HoldingsCard/HoldingsCard.tsx +9 -2
- package/src/components/InputSearch/InputSearch.tsx +8 -5
- package/src/components/InstitutionBadge/InstitutionBadge.tsx +9 -2
- package/src/components/ListGroup/ListGroup.tsx +9 -2
- package/src/components/ListItem/ListItem.tsx +10 -3
- package/src/components/MediaCard/MediaCard.tsx +2 -2
- package/src/components/MetricLegendItem/MetricLegendItem.tsx +9 -2
- package/src/components/MonthlyStatusGrid/MonthlyStatusGrid.tsx +17 -2
- package/src/components/NoteInput/NoteInput.tsx +8 -6
- package/src/components/PdpCcCard/PdpCcCard.tsx +356 -0
- package/src/components/PoweredByLabel/PoweredByLabel.tsx +9 -2
- package/src/components/ProductMerchandisingCard/ProductMerchandisingCard.tsx +490 -0
- package/src/components/ProductOverview/ProductOverview.tsx +10 -3
- package/src/components/ProgressBadge/ProgressBadge.tsx +9 -3
- package/src/components/ProjectionMarker/ProjectionMarker.tsx +284 -0
- package/src/components/Radio/Radio.tsx +5 -4
- package/src/components/Section/Section.tsx +10 -3
- package/src/components/Slider/Slider.tsx +635 -0
- package/src/components/Stack/Stack.tsx +131 -0
- package/src/components/SuggestiveSearch/SuggestiveSearch.tsx +10 -1
- package/src/components/SummaryTile/SummaryTile.tsx +9 -2
- package/src/components/Table/Table.tsx +449 -0
- package/src/components/Text/Text.tsx +9 -2
- package/src/components/TextInput/TextInput.tsx +22 -12
- package/src/components/TextSegment/TextSegment.tsx +173 -0
- package/src/components/ThreadHero/ThreadHero.tsx +10 -3
- package/src/components/Title/Title.tsx +9 -2
- package/src/components/Toast/Toast.tsx +9 -2
- package/src/components/TransactionBubble/TransactionBubble.tsx +9 -2
- package/src/components/TransactionStatus/TransactionStatus.tsx +9 -2
- package/src/components/UpiHandle/UpiHandle.tsx +9 -3
- package/src/components/index.ts +33 -3
- package/src/design-tokens/Coin Variables-variables-full.json +1 -1
- package/src/design-tokens/figma-modes.generated.ts +39 -9
- package/src/icons/registry.ts +1 -1
- package/src/utils/GlassFill/GlassFill.tsx +305 -0
- package/src/utils/GlassFill/GlassFill.web.tsx +148 -0
- package/src/utils/react-utils.ts +84 -0
- package/src/utils/web-platform-utils.ts +68 -0
- package/lib/commonjs/components/MediaCard/GlassFill.js +0 -62
- package/lib/commonjs/components/MediaCard/GlassFill.web.js +0 -48
- package/lib/module/components/MediaCard/GlassFill.js +0 -57
- package/lib/module/components/MediaCard/GlassFill.web.js +0 -43
- package/lib/typescript/scripts/extract-component-tokens.d.ts +0 -9
- package/lib/typescript/scripts/generate-component-docs.d.ts +0 -9
- package/lib/typescript/scripts/generate-icon-registry.d.ts +0 -3
- package/lib/typescript/scripts/generate-mode-types.d.ts +0 -2
- package/lib/typescript/scripts/retype-modes.d.cts +0 -2
- package/lib/typescript/src/components/MediaCard/GlassFill.d.ts +0 -47
- package/lib/typescript/src/components/MediaCard/GlassFill.web.d.ts +0 -20
- package/src/components/MediaCard/GlassFill.tsx +0 -89
- package/src/components/MediaCard/GlassFill.web.tsx +0 -53
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { View, Text, type ViewStyle, type TextStyle, type StyleProp } from 'react-native'
|
|
2
|
+
import { View, Text, type ViewStyle, type TextStyle, type StyleProp, type ImageSourcePropType } from 'react-native'
|
|
3
3
|
import { findVariablesByPattern, getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
4
4
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
5
5
|
import { cloneChildrenWithModes, EMPTY_MODES } from '../../utils/react-utils'
|
|
@@ -8,12 +8,24 @@ import Button from '../Button/Button'
|
|
|
8
8
|
import Badge from '../Badge/Badge'
|
|
9
9
|
import ButtonGroup from '../ButtonGroup/ButtonGroup'
|
|
10
10
|
import IconButton from '../IconButton/IconButton'
|
|
11
|
+
import Avatar from '../Avatar/Avatar'
|
|
11
12
|
import type { Modes } from '../../design-tokens'
|
|
12
13
|
|
|
13
|
-
export type CardCTAType = 'cta' | 'rating'
|
|
14
|
+
export type CardCTAType = 'cta' | 'rating' | 'sip'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Accepted `type` values. The canonical (and historical) values are lowercase
|
|
18
|
+
* (`'cta' | 'rating' | 'sip'`). The Figma variant names are PascalCase
|
|
19
|
+
* (`'CTA' | 'Rating' | 'Sip'`) — we accept those too and normalize internally
|
|
20
|
+
* so callers can pass either casing without a breaking change.
|
|
21
|
+
*/
|
|
22
|
+
export type CardCTATypeInput = CardCTAType | 'CTA' | 'Rating' | 'Sip'
|
|
14
23
|
|
|
15
24
|
const optionalTokenAvailability = new Map<string, boolean>()
|
|
16
25
|
|
|
26
|
+
const toWeight = (w: number | string): TextStyle['fontWeight'] =>
|
|
27
|
+
(typeof w === 'number' ? `${w}` : w) as TextStyle['fontWeight']
|
|
28
|
+
|
|
17
29
|
function getOptionalVariableByName<T>(name: string, modes: Modes, fallback: T): T {
|
|
18
30
|
let isAvailable = optionalTokenAvailability.get(name)
|
|
19
31
|
|
|
@@ -30,8 +42,13 @@ function getOptionalVariableByName<T>(name: string, modes: Modes, fallback: T):
|
|
|
30
42
|
}
|
|
31
43
|
|
|
32
44
|
export type CardCTAProps = {
|
|
33
|
-
/**
|
|
34
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Visual layout variant. `'cta'` (default) is the horizontal CTA card,
|
|
47
|
+
* `'rating'` is the rating card, and `'sip'` is the avatar-led card with a
|
|
48
|
+
* headline/description/subtitle footer. PascalCase Figma names
|
|
49
|
+
* (`'CTA' | 'Rating' | 'Sip'`) are also accepted.
|
|
50
|
+
*/
|
|
51
|
+
type?: CardCTATypeInput;
|
|
35
52
|
/** Title text */
|
|
36
53
|
title?: string;
|
|
37
54
|
/** Body / subtitle text */
|
|
@@ -50,6 +67,14 @@ export type CardCTAProps = {
|
|
|
50
67
|
onPressLike?: () => void;
|
|
51
68
|
/** Callback for the default dislike action */
|
|
52
69
|
onPressDislike?: () => void;
|
|
70
|
+
/** [sip] Headline text shown above the description row */
|
|
71
|
+
headline?: string;
|
|
72
|
+
/** [sip] Description text (left of subtitle) */
|
|
73
|
+
description?: string;
|
|
74
|
+
/** [sip] Subtitle text (right of description) */
|
|
75
|
+
subtitle?: string;
|
|
76
|
+
/** [sip] Image source for the default Avatar */
|
|
77
|
+
avatarSource?: ImageSourcePropType | string;
|
|
53
78
|
/** Mode configuration for design token resolution */
|
|
54
79
|
modes?: Modes;
|
|
55
80
|
/** Slot: replaces the default icon area (right side) */
|
|
@@ -60,6 +85,8 @@ export type CardCTAProps = {
|
|
|
60
85
|
ratingBadgeSlot?: React.ReactNode;
|
|
61
86
|
/** Slot: replaces the default like/dislike action group */
|
|
62
87
|
ratingActionsSlot?: React.ReactNode;
|
|
88
|
+
/** [sip] Slot: replaces the default Avatar */
|
|
89
|
+
avatarSlot?: React.ReactNode;
|
|
63
90
|
/** Container style overrides */
|
|
64
91
|
style?: StyleProp<ViewStyle>;
|
|
65
92
|
};
|
|
@@ -75,16 +102,24 @@ function CardCTA({
|
|
|
75
102
|
showRatingActions = true,
|
|
76
103
|
onPressLike,
|
|
77
104
|
onPressDislike,
|
|
105
|
+
headline = 'Headline',
|
|
106
|
+
description = 'Description',
|
|
107
|
+
subtitle = 'Subtitle',
|
|
108
|
+
avatarSource,
|
|
78
109
|
modes: propModes = EMPTY_MODES,
|
|
79
110
|
iconSlot,
|
|
80
111
|
buttonSlot,
|
|
81
112
|
ratingBadgeSlot,
|
|
82
113
|
ratingActionsSlot,
|
|
114
|
+
avatarSlot,
|
|
83
115
|
style,
|
|
84
116
|
}: CardCTAProps) {
|
|
85
117
|
const { modes: globalModes } = useTokens()
|
|
86
118
|
const modes = { ...globalModes, ...propModes }
|
|
87
|
-
|
|
119
|
+
// Accept both lowercase (canonical) and Figma PascalCase variant names.
|
|
120
|
+
const normalizedType = (typeof type === 'string' ? type.toLowerCase() : 'cta') as CardCTAType
|
|
121
|
+
const isRating = normalizedType === 'rating'
|
|
122
|
+
const isSip = normalizedType === 'sip'
|
|
88
123
|
|
|
89
124
|
const background = getVariableByName('cardCTA/background', modes) || '#ffffff'
|
|
90
125
|
const radius = getVariableByName('cardCTA/radius', modes) || 12
|
|
@@ -103,14 +138,14 @@ function CardCTA({
|
|
|
103
138
|
const titleColor = getVariableByName('cardCTA/title/color', modes) || '#0c0d10'
|
|
104
139
|
const titleFontFamily = getVariableByName('cardCTA/title/fontFamily', modes) || 'JioType Var'
|
|
105
140
|
const titleFontSize = getVariableByName('cardCTA/title/fontSize', modes) || 16
|
|
106
|
-
const titleLineHeight = getVariableByName('cardCTA/title/lineHeight', modes) ||
|
|
141
|
+
const titleLineHeight = getVariableByName('cardCTA/title/lineHeight', modes) || 18
|
|
107
142
|
const titleFontWeightRaw = getVariableByName('cardCTA/title/fontWeight', modes) || 700
|
|
108
143
|
const titleFontWeight = typeof titleFontWeightRaw === 'number' ? titleFontWeightRaw.toString() : titleFontWeightRaw
|
|
109
144
|
|
|
110
145
|
const bodyColor = getVariableByName('cardCTA/body/color', modes) || '#13002d'
|
|
111
146
|
const bodyFontFamily = getVariableByName('cardCTA/body/fontFamily', modes) || 'JioType Var'
|
|
112
|
-
const bodyFontSize = getVariableByName('cardCTA/body/fontSize', modes) ||
|
|
113
|
-
const bodyLineHeight = getVariableByName('cardCTA/body/lineHeight', modes) ||
|
|
147
|
+
const bodyFontSize = getVariableByName('cardCTA/body/fontSize', modes) || 14
|
|
148
|
+
const bodyLineHeight = getVariableByName('cardCTA/body/lineHeight', modes) || 17
|
|
114
149
|
const bodyFontWeightRaw = getVariableByName('cardCTA/body/fontWeight', modes) || 400
|
|
115
150
|
const bodyFontWeight = typeof bodyFontWeightRaw === 'number' ? bodyFontWeightRaw.toString() : bodyFontWeightRaw
|
|
116
151
|
|
|
@@ -122,6 +157,34 @@ function CardCTA({
|
|
|
122
157
|
const ratingFooterPaddingTop = getOptionalVariableByName('cardCTA/rating/footer/top', modes, 0)
|
|
123
158
|
const ratingFooterPaddingBottom = getOptionalVariableByName('cardCTA/rating/footer/bottom', modes, 12)
|
|
124
159
|
|
|
160
|
+
// Sip variant footer text block (Headline / Description / Subtitle). These
|
|
161
|
+
// `ccCard/*` tokens were introduced for the Sip layout — resolve them
|
|
162
|
+
// optionally so older token snapshots that lack them fall back gracefully.
|
|
163
|
+
const sipFooterGap = getOptionalVariableByName('ccCard/footer/textWrap/gap', modes, 4)
|
|
164
|
+
|
|
165
|
+
const sipHeadlineColor = getOptionalVariableByName('ccCard/headline/color', modes, '#707275')
|
|
166
|
+
const sipHeadlineFontFamily = getOptionalVariableByName('ccCard/headline/fontFamily', modes, 'JioType Var')
|
|
167
|
+
const sipHeadlineFontSize = getOptionalVariableByName('ccCard/headline/fontSize', modes, 10)
|
|
168
|
+
const sipHeadlineLineHeight = getOptionalVariableByName('ccCard/headline/lineHeight', modes, 13)
|
|
169
|
+
const sipHeadlineFontWeightRaw = getOptionalVariableByName<string | number>('ccCard/headline/fontWeight', modes, 500)
|
|
170
|
+
const sipHeadlineFontWeight = typeof sipHeadlineFontWeightRaw === 'number' ? sipHeadlineFontWeightRaw.toString() : sipHeadlineFontWeightRaw
|
|
171
|
+
|
|
172
|
+
const sipDescriptionColor = getOptionalVariableByName('ccCard/title/color', modes, '#081007')
|
|
173
|
+
const sipDescriptionFontFamily = getOptionalVariableByName('ccCard/title/fontFamily', modes, 'JioType Var')
|
|
174
|
+
const sipDescriptionFontSize = getOptionalVariableByName('ccCard/title/fontSize', modes, 14)
|
|
175
|
+
const sipDescriptionLineHeight = getOptionalVariableByName('ccCard/title/lineHeight', modes, 15)
|
|
176
|
+
const sipDescriptionFontWeightRaw = getOptionalVariableByName<string | number>('ccCard/title/fontWeight', modes, 700)
|
|
177
|
+
const sipDescriptionFontWeight = typeof sipDescriptionFontWeightRaw === 'number' ? sipDescriptionFontWeightRaw.toString() : sipDescriptionFontWeightRaw
|
|
178
|
+
|
|
179
|
+
const sipSubtitleColor = getOptionalVariableByName('ccCard/subtitle/color', modes, '#707275')
|
|
180
|
+
const sipSubtitleFontFamily = getOptionalVariableByName('ccCard/subtitle/fontFamily', modes, 'JioType Var')
|
|
181
|
+
const sipSubtitleFontSize = getOptionalVariableByName('ccCard/subtitle/fontSize', modes, 10)
|
|
182
|
+
const sipSubtitleLineHeight = getOptionalVariableByName('ccCard/subtitle/lineHeight', modes, 13)
|
|
183
|
+
const sipSubtitleFontWeightRaw = getOptionalVariableByName<string | number>('ccCard/subtitle/fontWeight', modes, 500)
|
|
184
|
+
const sipSubtitleFontWeight = typeof sipSubtitleFontWeightRaw === 'number' ? sipSubtitleFontWeightRaw.toString() : sipSubtitleFontWeightRaw
|
|
185
|
+
|
|
186
|
+
const avatarModes = { ...modes, 'Avatar Size': 'L' }
|
|
187
|
+
|
|
125
188
|
const buttonModes = {...modes, AppearanceBrand: 'Secondary', 'Button / Size': 'S'}
|
|
126
189
|
const iconButtonModes = {'Button / Size': 'S', 'Emphasis': 'Low', 'AppearanceBrand':'Neutral',...modes }
|
|
127
190
|
const effectiveButtonLabel = buttonLabel ?? (isRating ? 'Save' : 'Button')
|
|
@@ -130,33 +193,72 @@ function CardCTA({
|
|
|
130
193
|
|
|
131
194
|
const buttonPaddingH = getVariableByName('button/padding/horizontal', buttonModes) || 20
|
|
132
195
|
const buttonBorderSize = getVariableByName('button/border/size', buttonModes) ?? 1
|
|
196
|
+
// Small safety pad so sub-pixel rounding between the measure pass and the
|
|
197
|
+
// rendered glyph run can never clip the final character.
|
|
133
198
|
const measuredButtonWidth = measuredButtonLabelWidth === null
|
|
134
199
|
? undefined
|
|
135
|
-
: Math.ceil(measuredButtonLabelWidth + (buttonPaddingH as number) * 2 + (buttonBorderSize as number) * 2)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
200
|
+
: Math.ceil(measuredButtonLabelWidth + (buttonPaddingH as number) * 2 + (buttonBorderSize as number) * 2 + 2)
|
|
201
|
+
|
|
202
|
+
// ROOT-CAUSE FIX for the Android "jumping button" feedback loop + clipping.
|
|
203
|
+
//
|
|
204
|
+
// Previously the *visible* label measured itself via `onTextLayout` and we
|
|
205
|
+
// fed that width straight back onto the same Button. Because the button is
|
|
206
|
+
// width-constrained by its parent, Android clamps the overflowing text and
|
|
207
|
+
// even character-breaks a single word ("Save" -> "Sav"/"e"); the re-applied
|
|
208
|
+
// width re-triggers layout, producing an endless ~60fps width oscillation.
|
|
209
|
+
//
|
|
210
|
+
// We now measure an *off-screen* copy of the label, laid out at an
|
|
211
|
+
// effectively unbounded width, so its reported single-line width is
|
|
212
|
+
// intrinsic and constant regardless of the button's applied width — the
|
|
213
|
+
// measurement can no longer depend on the value it produces, so the loop is
|
|
214
|
+
// impossible. Crucially the measurer reuses the Button's own resolved label
|
|
215
|
+
// styles (passed into `renderContent`), so the measured font matches the
|
|
216
|
+
// rendered font exactly and the width is never an under-estimate. The label
|
|
217
|
+
// is always a single line that overflows rather than wraps or truncates.
|
|
218
|
+
const handleMeasureTextLayout = React.useCallback((event: any) => {
|
|
219
|
+
const line = event?.nativeEvent?.lines?.[0]
|
|
220
|
+
const width = line && typeof line.width === 'number' ? line.width : 0
|
|
221
|
+
if (width <= 0) return
|
|
222
|
+
|
|
223
|
+
setMeasuredButtonLabelWidth((currentWidth) =>
|
|
224
|
+
currentWidth !== null && Math.abs(currentWidth - width) < 0.5
|
|
225
|
+
? currentWidth
|
|
226
|
+
: Math.ceil(width)
|
|
143
227
|
)
|
|
144
|
-
if (nextWidth <= 0) return
|
|
145
|
-
|
|
146
|
-
setMeasuredButtonLabelWidth((currentWidth) => {
|
|
147
|
-
if (currentWidth !== null && Math.abs(currentWidth - nextWidth) < 1) {
|
|
148
|
-
return currentWidth
|
|
149
|
-
}
|
|
150
|
-
return nextWidth
|
|
151
|
-
})
|
|
152
228
|
}, [])
|
|
153
229
|
|
|
230
|
+
// Off-screen measurer wrapper: absolute + opacity 0 + pointerEvents none =>
|
|
231
|
+
// out of flow, invisible, never intercepts touches, zero layout impact.
|
|
232
|
+
const measurerWrapStyle: ViewStyle = { position: 'absolute', left: 0, top: 0, opacity: 0 }
|
|
233
|
+
|
|
234
|
+
// Renders the visible single-line label (never wraps, never ellipsizes) plus
|
|
235
|
+
// the co-located off-screen measurer that shares the Button's exact label
|
|
236
|
+
// styles. `width: 9999` forces the measurer onto one line so `onTextLayout`
|
|
237
|
+
// reports the true intrinsic width.
|
|
238
|
+
const renderButtonContent = (labelExtraStyle: TextStyle) => (labelStyles: StyleProp<TextStyle>) => (
|
|
239
|
+
<>
|
|
240
|
+
<Text numberOfLines={1} ellipsizeMode="clip" style={[labelStyles, labelExtraStyle]}>
|
|
241
|
+
{nonWrappingButtonLabel}
|
|
242
|
+
</Text>
|
|
243
|
+
<View
|
|
244
|
+
pointerEvents="none"
|
|
245
|
+
accessibilityElementsHidden
|
|
246
|
+
importantForAccessibility="no"
|
|
247
|
+
style={measurerWrapStyle}
|
|
248
|
+
>
|
|
249
|
+
<Text style={[labelStyles, { width: 9999 }]} onTextLayout={handleMeasureTextLayout}>
|
|
250
|
+
{nonWrappingButtonLabel}
|
|
251
|
+
</Text>
|
|
252
|
+
</View>
|
|
253
|
+
</>
|
|
254
|
+
)
|
|
255
|
+
|
|
154
256
|
const containerStyle: ViewStyle = {
|
|
155
257
|
backgroundColor: background,
|
|
156
258
|
borderRadius: radius,
|
|
157
259
|
borderWidth: borderSize,
|
|
158
260
|
borderColor,
|
|
159
|
-
flexDirection: isRating ? 'column' : 'row',
|
|
261
|
+
flexDirection: isRating || isSip ? 'column' : 'row',
|
|
160
262
|
overflow: 'visible',
|
|
161
263
|
}
|
|
162
264
|
|
|
@@ -245,6 +347,53 @@ function CardCTA({
|
|
|
245
347
|
fontWeight: bodyFontWeight,
|
|
246
348
|
}
|
|
247
349
|
|
|
350
|
+
const sipWrapStyle: ViewStyle = {
|
|
351
|
+
width: '100%',
|
|
352
|
+
paddingHorizontal: leftPaddingH,
|
|
353
|
+
paddingVertical: leftPaddingV,
|
|
354
|
+
gap: leftGap,
|
|
355
|
+
alignItems: 'flex-start',
|
|
356
|
+
justifyContent: 'flex-start',
|
|
357
|
+
overflow: 'visible',
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const sipFooterTextWrapStyle: ViewStyle = {
|
|
361
|
+
gap: sipFooterGap,
|
|
362
|
+
alignItems: 'flex-start',
|
|
363
|
+
alignSelf: 'stretch',
|
|
364
|
+
minWidth: 0,
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const sipDescriptionWrapStyle: ViewStyle = {
|
|
368
|
+
flexDirection: 'row',
|
|
369
|
+
gap: sipFooterGap,
|
|
370
|
+
alignItems: 'flex-end',
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const sipHeadlineStyle: TextStyle = {
|
|
374
|
+
color: sipHeadlineColor,
|
|
375
|
+
fontFamily: sipHeadlineFontFamily,
|
|
376
|
+
fontSize: sipHeadlineFontSize,
|
|
377
|
+
lineHeight: sipHeadlineLineHeight,
|
|
378
|
+
fontWeight: toWeight(sipHeadlineFontWeightRaw),
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const sipDescriptionStyle: TextStyle = {
|
|
382
|
+
color: sipDescriptionColor,
|
|
383
|
+
fontFamily: sipDescriptionFontFamily,
|
|
384
|
+
fontSize: sipDescriptionFontSize,
|
|
385
|
+
lineHeight: sipDescriptionLineHeight,
|
|
386
|
+
fontWeight: toWeight(sipDescriptionFontWeightRaw),
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const sipSubtitleStyle: TextStyle = {
|
|
390
|
+
color: sipSubtitleColor,
|
|
391
|
+
fontFamily: sipSubtitleFontFamily,
|
|
392
|
+
fontSize: sipSubtitleFontSize,
|
|
393
|
+
lineHeight: sipSubtitleLineHeight,
|
|
394
|
+
fontWeight: toWeight(sipSubtitleFontWeightRaw),
|
|
395
|
+
}
|
|
396
|
+
|
|
248
397
|
const ratingContentStyle: ViewStyle = {
|
|
249
398
|
paddingHorizontal: ratingContentPaddingH,
|
|
250
399
|
paddingVertical: ratingContentPaddingV,
|
|
@@ -294,6 +443,44 @@ function CardCTA({
|
|
|
294
443
|
flexWrap: 'nowrap',
|
|
295
444
|
}
|
|
296
445
|
|
|
446
|
+
if (isSip) {
|
|
447
|
+
return (
|
|
448
|
+
<View style={[containerStyle, style]}>
|
|
449
|
+
<View style={sipWrapStyle}>
|
|
450
|
+
{avatarSlot ? (
|
|
451
|
+
cloneChildrenWithModes(avatarSlot, avatarModes)
|
|
452
|
+
) : (
|
|
453
|
+
<Avatar style="Image" imageSource={avatarSource} modes={avatarModes} />
|
|
454
|
+
)}
|
|
455
|
+
<View style={textWrapStyle}>
|
|
456
|
+
<Text style={titleStyle}>{title}</Text>
|
|
457
|
+
<Text style={bodyStyle}>{body}</Text>
|
|
458
|
+
</View>
|
|
459
|
+
<View style={sipFooterTextWrapStyle}>
|
|
460
|
+
<Text style={sipHeadlineStyle}>{headline}</Text>
|
|
461
|
+
<View style={sipDescriptionWrapStyle}>
|
|
462
|
+
<Text style={sipDescriptionStyle}>{description}</Text>
|
|
463
|
+
<Text style={sipSubtitleStyle}>{subtitle}</Text>
|
|
464
|
+
</View>
|
|
465
|
+
</View>
|
|
466
|
+
<View style={buttonWrapStyle}>
|
|
467
|
+
{buttonSlot ? (
|
|
468
|
+
cloneChildrenWithModes(buttonSlot, buttonModes)
|
|
469
|
+
) : (
|
|
470
|
+
<Button
|
|
471
|
+
label={effectiveButtonLabel}
|
|
472
|
+
onPress={onPressButton || (() => {})}
|
|
473
|
+
modes={buttonModes}
|
|
474
|
+
style={buttonStyle}
|
|
475
|
+
renderContent={renderButtonContent(buttonLabelStyle)}
|
|
476
|
+
/>
|
|
477
|
+
)}
|
|
478
|
+
</View>
|
|
479
|
+
</View>
|
|
480
|
+
</View>
|
|
481
|
+
)
|
|
482
|
+
}
|
|
483
|
+
|
|
297
484
|
if (isRating) {
|
|
298
485
|
return (
|
|
299
486
|
<View style={[containerStyle, style]}>
|
|
@@ -318,14 +505,7 @@ function CardCTA({
|
|
|
318
505
|
onPress={onPressButton || (() => {})}
|
|
319
506
|
modes={buttonModes}
|
|
320
507
|
style={ratingButtonStyle}
|
|
321
|
-
renderContent={(
|
|
322
|
-
<Text
|
|
323
|
-
onTextLayout={handleButtonLabelTextLayout}
|
|
324
|
-
style={[labelStyles, ratingButtonLabelStyle]}
|
|
325
|
-
>
|
|
326
|
-
{nonWrappingButtonLabel}
|
|
327
|
-
</Text>
|
|
328
|
-
)}
|
|
508
|
+
renderContent={renderButtonContent(ratingButtonLabelStyle)}
|
|
329
509
|
/>
|
|
330
510
|
)}
|
|
331
511
|
</View>
|
|
@@ -368,14 +548,7 @@ function CardCTA({
|
|
|
368
548
|
onPress={onPressButton || (() => {})}
|
|
369
549
|
modes={buttonModes}
|
|
370
550
|
style={buttonStyle}
|
|
371
|
-
renderContent={(
|
|
372
|
-
<Text
|
|
373
|
-
onTextLayout={handleButtonLabelTextLayout}
|
|
374
|
-
style={[labelStyles, buttonLabelStyle]}
|
|
375
|
-
>
|
|
376
|
-
{nonWrappingButtonLabel}
|
|
377
|
-
</Text>
|
|
378
|
-
)}
|
|
551
|
+
renderContent={renderButtonContent(buttonLabelStyle)}
|
|
379
552
|
/>
|
|
380
553
|
)}
|
|
381
554
|
</View>
|
|
@@ -71,7 +71,11 @@ function CardInsight({
|
|
|
71
71
|
const background =
|
|
72
72
|
(getVariableByName('cardInsight/background', modes) as string | null) ?? '#ffffff'
|
|
73
73
|
const radius =
|
|
74
|
-
(getVariableByName('cardInsight/radius', modes) as number | null) ??
|
|
74
|
+
(getVariableByName('cardInsight/radius', modes) as number | null) ?? 12
|
|
75
|
+
const borderWidth =
|
|
76
|
+
(getVariableByName('cardInsight/borderWidth', modes) as number | null) ?? 1
|
|
77
|
+
const borderColor =
|
|
78
|
+
(getVariableByName('cardInsight/border/color', modes) as string | null) ?? '#ffffff'
|
|
75
79
|
const paddingHorizontal =
|
|
76
80
|
(getVariableByName('cardInsight/padding/horizontal', modes) as number | null) ?? 12
|
|
77
81
|
const paddingVertical =
|
|
@@ -164,6 +168,8 @@ function CardInsight({
|
|
|
164
168
|
width,
|
|
165
169
|
backgroundColor: background,
|
|
166
170
|
borderRadius: radius,
|
|
171
|
+
borderWidth,
|
|
172
|
+
borderColor,
|
|
167
173
|
paddingHorizontal,
|
|
168
174
|
paddingVertical,
|
|
169
175
|
gap,
|