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,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { StyleProp, ViewStyle } from 'react-native';
|
|
2
3
|
import type { Modes } from '../design-tokens';
|
|
3
4
|
/**
|
|
4
5
|
* A shared, frozen empty modes object.
|
|
@@ -20,6 +21,52 @@ export declare const EMPTY_MODES: Readonly<Record<string, any>>;
|
|
|
20
21
|
* This ensures that all child components in slots receive the modes prop from the parent.
|
|
21
22
|
*/
|
|
22
23
|
export declare function cloneChildrenWithModes(children: React.ReactNode, modes: Modes, forcedModes?: Modes): React.ReactNode[];
|
|
24
|
+
/**
|
|
25
|
+
* Merges a style onto each direct (top-level) child element, with the injected
|
|
26
|
+
* style taking precedence over the child's own style.
|
|
27
|
+
*
|
|
28
|
+
* Used by the Stack family to *enforce* cross-axis stretching from the container
|
|
29
|
+
* itself: a child can set its own `alignSelf` (which, per the flexbox spec,
|
|
30
|
+
* overrides the parent's `alignItems`), so to guarantee equal heights / full
|
|
31
|
+
* width regardless of what individual children declare, we append
|
|
32
|
+
* `{ alignSelf: 'stretch' }` to every direct child.
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* - Only top-level children are touched. Grandchildren are intentionally left
|
|
36
|
+
* alone — we never want to leak layout styles deeper into the tree.
|
|
37
|
+
* - Non-element children (strings, numbers) are passed through untouched.
|
|
38
|
+
* - This relies on the child forwarding `style` to its outer/root view. Built-in
|
|
39
|
+
* RN primitives and components that spread `style` onto their root honour it;
|
|
40
|
+
* a child that fully ignores `style` cannot be forced (this is a hard React
|
|
41
|
+
* Native limitation, not something this helper can work around).
|
|
42
|
+
* - Per Yoga, stretch has no effect on an axis where the child has a *fixed*
|
|
43
|
+
* dimension (e.g. an explicit `height` for a row). Such children opt out by
|
|
44
|
+
* design; this helper does not strip explicit dimensions.
|
|
45
|
+
*/
|
|
46
|
+
export declare function injectChildStyle(children: React.ReactNode, style: StyleProp<ViewStyle>): React.ReactNode;
|
|
47
|
+
/**
|
|
48
|
+
* Combines several refs (object refs and/or callback refs) into a single
|
|
49
|
+
* callback ref. Useful when a component needs to keep its own internal ref to a
|
|
50
|
+
* node while still honouring a ref forwarded by the consumer.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* const inputRef = useRef<RNTextInput>(null)
|
|
54
|
+
* <RNTextInput ref={mergeRefs(inputRef, forwardedRef)} />
|
|
55
|
+
*/
|
|
56
|
+
export declare function mergeRefs<T>(...refs: Array<React.Ref<T> | undefined | null>): React.RefCallback<T>;
|
|
57
|
+
export type EllipsizeMode = 'head' | 'middle' | 'tail' | 'clip';
|
|
58
|
+
/**
|
|
59
|
+
* Resolves the `numberOfLines` / `ellipsizeMode` pair for a `<Text>` based on a
|
|
60
|
+
* `disableTruncation` flag.
|
|
61
|
+
*
|
|
62
|
+
* When `disableTruncation` is `true`, both values are returned as `undefined`
|
|
63
|
+
* so the text wraps to as many lines as it needs and never shows the trailing
|
|
64
|
+
* ellipsis. Otherwise the provided values are passed through unchanged.
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveTruncation(disableTruncation: boolean | undefined, numberOfLines?: number, ellipsizeMode?: EllipsizeMode): {
|
|
67
|
+
numberOfLines?: number;
|
|
68
|
+
ellipsizeMode?: EllipsizeMode;
|
|
69
|
+
};
|
|
23
70
|
/**
|
|
24
71
|
* Flattens React children, extracting them from Fragments.
|
|
25
72
|
* Useful for Group components that need to process individual items (e.g., for layout or styling)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
1
2
|
import type { PressableProps } from 'react-native';
|
|
2
3
|
/**
|
|
3
4
|
* Web-specific props that should NOT be passed to React Native's Pressable component.
|
|
@@ -131,6 +132,41 @@ export declare function usePressableWebSupport({ restProps, onPress, disabled, a
|
|
|
131
132
|
tabIndex?: 0 | -1;
|
|
132
133
|
onKeyDown?: (e: any) => void;
|
|
133
134
|
};
|
|
135
|
+
/**
|
|
136
|
+
* Detects pointer presses (mouse / touch) that land OUTSIDE the node held by
|
|
137
|
+
* `containerRef` and invokes `onOutsidePress`.
|
|
138
|
+
*
|
|
139
|
+
* Why this exists:
|
|
140
|
+
* On web, React Native pressables (`Pressable`, `Button`, links, etc.) do not
|
|
141
|
+
* always claim DOM focus the way a native `<button>`/`<input>` does. As a
|
|
142
|
+
* result, tapping an *interactive* element outside a focused `<input>` may
|
|
143
|
+
* never trigger the input's native `blur` event, leaving a field stuck in its
|
|
144
|
+
* "Active" visual state. Listening for document-level pointer-down in the
|
|
145
|
+
* capture phase lets a component force a blur (or close a popover, etc.)
|
|
146
|
+
* regardless of whether the outside target takes focus.
|
|
147
|
+
*
|
|
148
|
+
* Behavior & safety:
|
|
149
|
+
* - **Web only.** On native (or when `document` is unavailable) this is a
|
|
150
|
+
* no-op, so it is safe to call unconditionally.
|
|
151
|
+
* - Listeners are attached only while `enabled` is `true`, and are removed on
|
|
152
|
+
* cleanup / when disabled — there is no standing global listener.
|
|
153
|
+
* - Uses the **capture** phase so it runs before element-level handlers, and
|
|
154
|
+
* listens to both `mousedown` and `touchstart` for parity across devices.
|
|
155
|
+
* - The latest `onOutsidePress` is read through a ref, so passing a fresh
|
|
156
|
+
* inline closure every render does NOT re-subscribe the listener.
|
|
157
|
+
*
|
|
158
|
+
* @param containerRef - Ref to the root host node to treat as "inside".
|
|
159
|
+
* @param onOutsidePress - Called when a pointer press occurs outside the node.
|
|
160
|
+
* @param enabled - When `false`, no listener is attached. Defaults to `true`.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```tsx
|
|
164
|
+
* const rootRef = useRef<View>(null)
|
|
165
|
+
* const inputRef = useRef<RNTextInput>(null)
|
|
166
|
+
* useWebOutsidePress(rootRef, () => inputRef.current?.blur(), isFocused)
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export declare function useWebOutsidePress(containerRef: RefObject<any>, onOutsidePress: () => void, enabled?: boolean): void;
|
|
134
170
|
/**
|
|
135
171
|
* Type guard to check if running on web platform
|
|
136
172
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jfs-components",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "React Native Jio Finance Components Library",
|
|
5
5
|
"author": "sunshuaiqi@gmail.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"lint": "eslint .",
|
|
31
31
|
"build-react": "webpack --mode production",
|
|
32
32
|
"start-react": "webpack-dev-server --config ./webpack.config.js --mode development",
|
|
33
|
+
"tokens": "node scripts/figma-token-explorer.js",
|
|
33
34
|
"extract-tokens": "node scripts/extract-component-tokens.js",
|
|
34
35
|
"generate-mode-types": "node scripts/generate-mode-types.js",
|
|
35
36
|
"generate-docs": "node scripts/generate-component-docs.js",
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
15
15
|
import Icon from '../../icons/Icon'
|
|
16
16
|
import { usePressableWebSupport, type WebAccessibilityProps } from '../../utils/web-platform-utils'
|
|
17
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
17
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
18
18
|
import type { Modes } from '../../design-tokens'
|
|
19
19
|
|
|
20
20
|
// Enable LayoutAnimation on Android
|
|
@@ -87,6 +87,12 @@ export type AccordionProps = {
|
|
|
87
87
|
accessibilityState?: AccessibilityState;
|
|
88
88
|
/** Web-specific accessibility props (only used on web platform) */
|
|
89
89
|
webAccessibilityProps?: WebAccessibilityProps;
|
|
90
|
+
/**
|
|
91
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
92
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
93
|
+
* lines as it needs even when horizontal space is tight.
|
|
94
|
+
*/
|
|
95
|
+
disableTruncation?: boolean;
|
|
90
96
|
} & React.ComponentProps<typeof View>;
|
|
91
97
|
|
|
92
98
|
/**
|
|
@@ -117,6 +123,7 @@ function Accordion({
|
|
|
117
123
|
accessibilityHint,
|
|
118
124
|
accessibilityState,
|
|
119
125
|
webAccessibilityProps,
|
|
126
|
+
disableTruncation,
|
|
120
127
|
...rest
|
|
121
128
|
}: AccordionProps) {
|
|
122
129
|
const [internalExpanded, setInternalExpanded] = useState(defaultExpanded)
|
|
@@ -253,7 +260,7 @@ function Accordion({
|
|
|
253
260
|
]}
|
|
254
261
|
{...webProps}
|
|
255
262
|
>
|
|
256
|
-
<Text style={titleStyle}
|
|
263
|
+
<Text style={titleStyle} {...resolveTruncation(disableTruncation, 1)}>
|
|
257
264
|
{title}
|
|
258
265
|
</Text>
|
|
259
266
|
<Icon
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
type TextStyle,
|
|
12
12
|
} from 'react-native'
|
|
13
13
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
14
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
14
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
15
15
|
import Checkbox from '../Checkbox/Checkbox'
|
|
16
16
|
import Divider from '../Divider/Divider'
|
|
17
17
|
import Icon from '../../icons/Icon'
|
|
@@ -52,6 +52,12 @@ export type AccordionCheckboxProps = {
|
|
|
52
52
|
style?: StyleProp<ViewStyle>
|
|
53
53
|
/** Accessibility label for the header press target. Defaults to `title`. */
|
|
54
54
|
accessibilityLabel?: string
|
|
55
|
+
/**
|
|
56
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
57
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
58
|
+
* lines as it needs even when horizontal space is tight.
|
|
59
|
+
*/
|
|
60
|
+
disableTruncation?: boolean
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
/**
|
|
@@ -102,6 +108,7 @@ function AccordionCheckbox({
|
|
|
102
108
|
modes = EMPTY_MODES,
|
|
103
109
|
style,
|
|
104
110
|
accessibilityLabel,
|
|
111
|
+
disableTruncation,
|
|
105
112
|
}: AccordionCheckboxProps) {
|
|
106
113
|
const isExpandedControlled = controlledExpanded !== undefined
|
|
107
114
|
const [internalExpanded, setInternalExpanded] = useState(defaultExpanded)
|
|
@@ -288,11 +295,11 @@ function AccordionCheckbox({
|
|
|
288
295
|
}
|
|
289
296
|
/>
|
|
290
297
|
<View style={textWrapStyle}>
|
|
291
|
-
<Text style={titleStyle}
|
|
298
|
+
<Text style={titleStyle} {...resolveTruncation(disableTruncation, 1)} selectable={false}>
|
|
292
299
|
{title}
|
|
293
300
|
</Text>
|
|
294
301
|
{subtitle ? (
|
|
295
|
-
<Text style={subtitleStyle}
|
|
302
|
+
<Text style={subtitleStyle} {...resolveTruncation(disableTruncation, 1)} selectable={false}>
|
|
296
303
|
{subtitle}
|
|
297
304
|
</Text>
|
|
298
305
|
) : null}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
type ViewStyle,
|
|
14
14
|
} from 'react-native'
|
|
15
15
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
16
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
16
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
17
17
|
import Icon from '../../icons/Icon'
|
|
18
18
|
import type { Modes } from '../../design-tokens'
|
|
19
19
|
|
|
@@ -88,6 +88,12 @@ export type AccountCardProps = {
|
|
|
88
88
|
accessibilityLabel?: string
|
|
89
89
|
/** Accessibility hint forwarded to the underlying `Pressable`. */
|
|
90
90
|
accessibilityHint?: string
|
|
91
|
+
/**
|
|
92
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
93
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
94
|
+
* lines as it needs even when horizontal space is tight.
|
|
95
|
+
*/
|
|
96
|
+
disableTruncation?: boolean
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
const toNumber = (value: unknown, fallback: number): number => {
|
|
@@ -148,6 +154,7 @@ function AccountCard({
|
|
|
148
154
|
style,
|
|
149
155
|
accessibilityLabel,
|
|
150
156
|
accessibilityHint,
|
|
157
|
+
disableTruncation,
|
|
151
158
|
}: AccountCardProps) {
|
|
152
159
|
const iconModes = useMemo(
|
|
153
160
|
() =>
|
|
@@ -330,12 +337,12 @@ function AccountCard({
|
|
|
330
337
|
}}
|
|
331
338
|
>
|
|
332
339
|
{title != null && title !== '' ? (
|
|
333
|
-
<Text style={titleStyle}
|
|
340
|
+
<Text style={titleStyle} {...resolveTruncation(disableTruncation, 1)}>
|
|
334
341
|
{title}
|
|
335
342
|
</Text>
|
|
336
343
|
) : null}
|
|
337
344
|
{showSubtitle ? (
|
|
338
|
-
<Text style={subtitleStyle}
|
|
345
|
+
<Text style={subtitleStyle} {...resolveTruncation(disableTruncation, 1)}>
|
|
339
346
|
{subtitle}
|
|
340
347
|
</Text>
|
|
341
348
|
) : null}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import Svg, { Line } from 'react-native-svg'
|
|
10
10
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
11
11
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
12
|
-
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
12
|
+
import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils'
|
|
13
13
|
import MetricLegendItem from '../MetricLegendItem/MetricLegendItem'
|
|
14
14
|
import type { Modes } from '../../design-tokens'
|
|
15
15
|
|
|
@@ -109,6 +109,12 @@ export type AllocationComparisonChartProps = {
|
|
|
109
109
|
legendStyle?: StyleProp<ViewStyle>
|
|
110
110
|
/** Accessibility label for the whole chart. */
|
|
111
111
|
accessibilityLabel?: string
|
|
112
|
+
/**
|
|
113
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
114
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
115
|
+
* lines as it needs even when horizontal space is tight.
|
|
116
|
+
*/
|
|
117
|
+
disableTruncation?: boolean
|
|
112
118
|
}
|
|
113
119
|
|
|
114
120
|
const DEFAULT_DATA: AllocationSegment[] = [
|
|
@@ -162,6 +168,7 @@ type SegmentBarProps = {
|
|
|
162
168
|
baselineLabel: React.ReactNode
|
|
163
169
|
showMarker: boolean
|
|
164
170
|
theme: SegmentTheme
|
|
171
|
+
disableTruncation?: boolean
|
|
165
172
|
}
|
|
166
173
|
|
|
167
174
|
/**
|
|
@@ -177,6 +184,7 @@ function SegmentBar({
|
|
|
177
184
|
baselineLabel,
|
|
178
185
|
showMarker,
|
|
179
186
|
theme,
|
|
187
|
+
disableTruncation,
|
|
180
188
|
}: SegmentBarProps) {
|
|
181
189
|
const { barWidth, pillRadius, gap, currentColor, baselineColor, lineColor, lineSize, labelStyle } =
|
|
182
190
|
theme
|
|
@@ -195,7 +203,7 @@ function SegmentBar({
|
|
|
195
203
|
accessibilityLabel={segment.accessibilityLabel}
|
|
196
204
|
>
|
|
197
205
|
{showValueLabel ? (
|
|
198
|
-
<Text
|
|
206
|
+
<Text {...resolveTruncation(disableTruncation, 1)} style={labelStyle}>
|
|
199
207
|
{segment.valueLabel}
|
|
200
208
|
</Text>
|
|
201
209
|
) : null}
|
|
@@ -247,7 +255,7 @@ function SegmentBar({
|
|
|
247
255
|
/>
|
|
248
256
|
</Svg>
|
|
249
257
|
{isShown(baselineLabel) ? (
|
|
250
|
-
<Text
|
|
258
|
+
<Text {...resolveTruncation(disableTruncation, 1)} style={[labelStyle, { marginLeft: 6 }]}>
|
|
251
259
|
{baselineLabel}
|
|
252
260
|
</Text>
|
|
253
261
|
) : null}
|
|
@@ -257,7 +265,7 @@ function SegmentBar({
|
|
|
257
265
|
) : null}
|
|
258
266
|
</View>
|
|
259
267
|
|
|
260
|
-
<Text
|
|
268
|
+
<Text {...resolveTruncation(disableTruncation, 1)} style={labelStyle}>
|
|
261
269
|
{segment.label}
|
|
262
270
|
</Text>
|
|
263
271
|
</View>
|
|
@@ -295,6 +303,7 @@ function AllocationComparisonChart({
|
|
|
295
303
|
chartStyle,
|
|
296
304
|
legendStyle,
|
|
297
305
|
accessibilityLabel,
|
|
306
|
+
disableTruncation,
|
|
298
307
|
}: AllocationComparisonChartProps) {
|
|
299
308
|
const { modes: globalModes } = useTokens()
|
|
300
309
|
const modes = React.useMemo(
|
|
@@ -440,6 +449,7 @@ function AllocationComparisonChart({
|
|
|
440
449
|
baselineLabel={baselineLabel}
|
|
441
450
|
showMarker={showMarker}
|
|
442
451
|
theme={theme}
|
|
452
|
+
disableTruncation={disableTruncation}
|
|
443
453
|
/>
|
|
444
454
|
)
|
|
445
455
|
})}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import { View, type ViewStyle } from 'react-native'
|
|
3
3
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
4
4
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
@@ -27,12 +27,12 @@ export type AmountInputProps = {
|
|
|
27
27
|
*
|
|
28
28
|
* @component
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
const AmountInput = forwardRef<View, AmountInputProps>(function AmountInput({
|
|
31
31
|
moneyValueSlot,
|
|
32
32
|
noteInputSlot,
|
|
33
33
|
modes: propModes = EMPTY_MODES,
|
|
34
34
|
style,
|
|
35
|
-
}: AmountInputProps) {
|
|
35
|
+
}: AmountInputProps, ref: React.Ref<View>) {
|
|
36
36
|
const { modes: globalModes } = useTokens()
|
|
37
37
|
const modes = { ...globalModes, ...propModes }
|
|
38
38
|
|
|
@@ -75,9 +75,11 @@ export default function AmountInput({
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
return (
|
|
78
|
-
<View style={containerStyle}>
|
|
78
|
+
<View ref={ref} style={containerStyle}>
|
|
79
79
|
{renderMoneyValueSlot()}
|
|
80
80
|
{renderNoteInputSlot()}
|
|
81
81
|
</View>
|
|
82
82
|
)
|
|
83
|
-
}
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
export default AmountInput
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
import Svg, { Circle, Line, Path } from 'react-native-svg'
|
|
24
24
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
25
25
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
26
|
-
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
26
|
+
import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils'
|
|
27
27
|
import MetricLegendItem from '../MetricLegendItem/MetricLegendItem'
|
|
28
28
|
import type { Modes } from '../../design-tokens'
|
|
29
29
|
import {
|
|
@@ -149,6 +149,12 @@ export type AreaLineChartProps = {
|
|
|
149
149
|
children?: React.ReactNode
|
|
150
150
|
/** Accessibility label for the whole chart. */
|
|
151
151
|
accessibilityLabel?: string
|
|
152
|
+
/**
|
|
153
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
154
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
155
|
+
* lines as it needs even when horizontal space is tight.
|
|
156
|
+
*/
|
|
157
|
+
disableTruncation?: boolean
|
|
152
158
|
}
|
|
153
159
|
|
|
154
160
|
// --- Internal resolved types ----------------------------------------------
|
|
@@ -184,6 +190,7 @@ type ChartContextValue = {
|
|
|
184
190
|
formatY: (value: number) => React.ReactNode
|
|
185
191
|
showDots: boolean
|
|
186
192
|
modes: Modes
|
|
193
|
+
disableTruncation?: boolean
|
|
187
194
|
}
|
|
188
195
|
|
|
189
196
|
const ChartContext = createContext<ChartContextValue | null>(null)
|
|
@@ -307,6 +314,7 @@ function AreaLineChart({
|
|
|
307
314
|
style,
|
|
308
315
|
children,
|
|
309
316
|
accessibilityLabel,
|
|
317
|
+
disableTruncation,
|
|
310
318
|
}: AreaLineChartProps) {
|
|
311
319
|
const { modes: globalModes } = useTokens()
|
|
312
320
|
const modes = useMemo(() => ({ ...globalModes, ...propModes }), [globalModes, propModes])
|
|
@@ -440,6 +448,7 @@ function AreaLineChart({
|
|
|
440
448
|
formatY,
|
|
441
449
|
showDots,
|
|
442
450
|
modes,
|
|
451
|
+
disableTruncation,
|
|
443
452
|
}),
|
|
444
453
|
[
|
|
445
454
|
plotWidth,
|
|
@@ -459,6 +468,7 @@ function AreaLineChart({
|
|
|
459
468
|
formatY,
|
|
460
469
|
showDots,
|
|
461
470
|
modes,
|
|
471
|
+
disableTruncation,
|
|
462
472
|
]
|
|
463
473
|
)
|
|
464
474
|
|
|
@@ -650,7 +660,7 @@ function ChartYAxis({
|
|
|
650
660
|
showAxisLine = false,
|
|
651
661
|
formatLabel,
|
|
652
662
|
}: ChartYAxisProps) {
|
|
653
|
-
const { height, inset, yScale, yTicks, formatY, modes } = useChart()
|
|
663
|
+
const { height, inset, yScale, yTicks, formatY, modes, disableTruncation } = useChart()
|
|
654
664
|
const typo = useAxisTypography(modes)
|
|
655
665
|
const format = formatLabel ?? formatY
|
|
656
666
|
|
|
@@ -673,7 +683,7 @@ function ChartYAxis({
|
|
|
673
683
|
}}
|
|
674
684
|
>
|
|
675
685
|
{showLabels ? (
|
|
676
|
-
<Text style={typo.style}
|
|
686
|
+
<Text style={typo.style} {...resolveTruncation(disableTruncation, 1)}>
|
|
677
687
|
{format(t)}
|
|
678
688
|
</Text>
|
|
679
689
|
) : null}
|
|
@@ -736,7 +746,7 @@ function ChartXAxis({
|
|
|
736
746
|
selectable = true,
|
|
737
747
|
formatLabel,
|
|
738
748
|
}: ChartXAxisProps) {
|
|
739
|
-
const { width, inset, xScale, indexXs, count, xLabels, formatX, modes, activeIndex, setActiveIndex } =
|
|
749
|
+
const { width, inset, xScale, indexXs, count, xLabels, formatX, modes, activeIndex, setActiveIndex, disableTruncation } =
|
|
740
750
|
useChart()
|
|
741
751
|
const typo = useAxisTypography(modes)
|
|
742
752
|
const format = formatLabel ?? formatX
|
|
@@ -787,7 +797,7 @@ function ChartXAxis({
|
|
|
787
797
|
typo.style,
|
|
788
798
|
isActive ? { color: activeColor, fontWeight: '700' } : null,
|
|
789
799
|
]}
|
|
790
|
-
|
|
800
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
791
801
|
>
|
|
792
802
|
{format(label, i)}
|
|
793
803
|
</Text>
|
|
@@ -7,14 +7,24 @@ import {
|
|
|
7
7
|
type TextStyle,
|
|
8
8
|
} from 'react-native'
|
|
9
9
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
10
|
-
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
10
|
+
import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils'
|
|
11
11
|
import Skeleton from '../../skeleton/Skeleton'
|
|
12
12
|
import { useSkeleton } from '../../skeleton/SkeletonGroup'
|
|
13
13
|
import type { Modes } from '../../design-tokens'
|
|
14
|
+
import GlassFill from '../../utils/GlassFill/GlassFill'
|
|
14
15
|
|
|
15
|
-
type
|
|
16
|
+
export type BadgeType = 'default' | 'glass'
|
|
17
|
+
|
|
18
|
+
export type BadgeProps = {
|
|
16
19
|
/** Visible label text shown inside the badge */
|
|
17
20
|
label?: string
|
|
21
|
+
/**
|
|
22
|
+
* Visual style (matches the Figma `type` property). `'default'` is a solid
|
|
23
|
+
* token-colored pill; `'glass'` is a frosted, translucent pill backed by a
|
|
24
|
+
* real background blur (`GlassFill`) — the same glass surface used at the
|
|
25
|
+
* bottom of media/merchandising cards.
|
|
26
|
+
*/
|
|
27
|
+
type?: BadgeType
|
|
18
28
|
/** Modes used to resolve design tokens (e.g. Appearance, Size) */
|
|
19
29
|
modes?: Modes
|
|
20
30
|
/** Optional press handler to make the badge interactive */
|
|
@@ -22,29 +32,66 @@ type BadgeProps = {
|
|
|
22
32
|
accessibilityLabel?: string
|
|
23
33
|
style?: ViewStyle
|
|
24
34
|
labelStyle?: TextStyle
|
|
35
|
+
/**
|
|
36
|
+
* Optional leading node (icon/image) rendered before the label, inside the
|
|
37
|
+
* badge surface. When present, the badge lays its contents out in a row.
|
|
38
|
+
*/
|
|
39
|
+
leading?: React.ReactNode
|
|
40
|
+
/**
|
|
41
|
+
* Glass-only override for the translucent overlay color painted over the live
|
|
42
|
+
* blur. Defaults to the `badge/glass/color/background` token. Ignored for the
|
|
43
|
+
* `'default'` type.
|
|
44
|
+
*/
|
|
45
|
+
glassOverlayColor?: string
|
|
46
|
+
/**
|
|
47
|
+
* Glass-only override for the blur intensity on the 0–100 scale. Defaults to
|
|
48
|
+
* the `blur/minimal` token. Ignored for the `'default'` type.
|
|
49
|
+
*/
|
|
50
|
+
glassIntensity?: number
|
|
25
51
|
/**
|
|
26
52
|
* Explicit per-instance loading override. When `true`, renders a
|
|
27
53
|
* badge-shaped skeleton placeholder instead of the badge. Defaults to
|
|
28
54
|
* inheriting from the surrounding `<SkeletonGroup>`.
|
|
29
55
|
*/
|
|
30
56
|
loading?: boolean
|
|
57
|
+
/**
|
|
58
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
59
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
60
|
+
* lines as it needs even when horizontal space is tight.
|
|
61
|
+
*/
|
|
62
|
+
disableTruncation?: boolean
|
|
31
63
|
} & Omit<React.ComponentProps<typeof View>, 'style' | 'accessibilityLabel' | 'accessibilityRole'>
|
|
32
64
|
|
|
33
65
|
function Badge({
|
|
34
66
|
label = 'Label',
|
|
67
|
+
type = 'default',
|
|
35
68
|
modes = EMPTY_MODES,
|
|
36
69
|
onPress,
|
|
37
70
|
accessibilityLabel,
|
|
38
71
|
style,
|
|
39
72
|
labelStyle,
|
|
40
73
|
loading,
|
|
74
|
+
disableTruncation,
|
|
75
|
+
leading,
|
|
76
|
+
glassOverlayColor,
|
|
77
|
+
glassIntensity,
|
|
41
78
|
...rest
|
|
42
79
|
}: BadgeProps) {
|
|
43
|
-
|
|
80
|
+
const isGlass = type === 'glass'
|
|
81
|
+
const hasLeading = leading != null
|
|
82
|
+
|
|
83
|
+
// Resolve token values (fall back to sensible defaults). The glass type
|
|
84
|
+
// swaps the solid fill for a translucent overlay + white label, matching the
|
|
85
|
+
// Figma `badge/glass/*` tokens.
|
|
44
86
|
const backgroundColor =
|
|
45
87
|
(getVariableByName('badge/color/background', modes) as string) || '#d8effe'
|
|
46
|
-
const
|
|
47
|
-
(getVariableByName('badge/color/
|
|
88
|
+
const glassBackground =
|
|
89
|
+
(getVariableByName('badge/glass/color/background', modes) as string) || '#ffffff26'
|
|
90
|
+
const glassLabelColor =
|
|
91
|
+
(getVariableByName('badge/glass/color/label', modes) as string) || '#ffffff'
|
|
92
|
+
const labelColor = isGlass
|
|
93
|
+
? glassLabelColor
|
|
94
|
+
: (getVariableByName('badge/color/label', modes) as string) || '#000000'
|
|
48
95
|
const fontSize =
|
|
49
96
|
Number(getVariableByName('badge/label/fontSize', modes) as unknown) || 12
|
|
50
97
|
const fontFamily =
|
|
@@ -60,6 +107,12 @@ function Badge({
|
|
|
60
107
|
const lineHeight =
|
|
61
108
|
Number(getVariableByName('badge/label/lineHeight', modes) as unknown) ||
|
|
62
109
|
Math.round(fontSize * 1.2)
|
|
110
|
+
// Figma `blur/minimal` (px radius) -> GlassFill's 0–100 intensity scale, the
|
|
111
|
+
// same 1:1 mapping the merchandising card footer uses.
|
|
112
|
+
const blurIntensity = Math.max(
|
|
113
|
+
0,
|
|
114
|
+
Math.min(100, Math.round(Number(getVariableByName('blur/minimal', modes) as unknown) || 29)),
|
|
115
|
+
)
|
|
63
116
|
|
|
64
117
|
// Skeleton short-circuit. Size derived from the same tokens the loaded
|
|
65
118
|
// badge would use so the placeholder occupies the same box.
|
|
@@ -82,13 +135,20 @@ function Badge({
|
|
|
82
135
|
const Container: any = onPress ? Pressable : View
|
|
83
136
|
|
|
84
137
|
const containerStyle: ViewStyle = {
|
|
85
|
-
|
|
138
|
+
// Glass keeps the container transparent so the GlassFill blur shows through;
|
|
139
|
+
// `overflow: 'hidden'` clips the native blur view to the rounded pill (the
|
|
140
|
+
// blur view does not honor borderRadius itself).
|
|
141
|
+
backgroundColor: isGlass ? 'transparent' : backgroundColor,
|
|
86
142
|
paddingHorizontal,
|
|
87
143
|
paddingVertical,
|
|
88
144
|
borderRadius,
|
|
89
145
|
alignSelf: 'flex-start',
|
|
90
146
|
alignItems: 'center',
|
|
91
147
|
justifyContent: 'center',
|
|
148
|
+
// A leading node sits in-line before the label, so switch to a row with a
|
|
149
|
+
// small gap. Consumer `style` (spread last) can still override either.
|
|
150
|
+
...(hasLeading ? { flexDirection: 'row' as const, gap: 4 } : null),
|
|
151
|
+
...(isGlass ? { overflow: 'hidden' as const } : null),
|
|
92
152
|
...((style as any) || {}),
|
|
93
153
|
}
|
|
94
154
|
|
|
@@ -112,10 +172,18 @@ function Badge({
|
|
|
112
172
|
onPress={onPress}
|
|
113
173
|
{...rest}
|
|
114
174
|
>
|
|
175
|
+
{isGlass ? (
|
|
176
|
+
<GlassFill
|
|
177
|
+
tint="light"
|
|
178
|
+
intensity={glassIntensity ?? blurIntensity}
|
|
179
|
+
overlayColor={glassOverlayColor ?? glassBackground}
|
|
180
|
+
androidTintWash={false}
|
|
181
|
+
/>
|
|
182
|
+
) : null}
|
|
183
|
+
{hasLeading ? <View style={LEADING_WRAP}>{leading}</View> : null}
|
|
115
184
|
<Text
|
|
116
185
|
style={textStyle}
|
|
117
|
-
|
|
118
|
-
ellipsizeMode="tail"
|
|
186
|
+
{...resolveTruncation(disableTruncation, 1, 'tail')}
|
|
119
187
|
accessibilityElementsHidden={false}
|
|
120
188
|
>
|
|
121
189
|
{label}
|
|
@@ -124,6 +192,8 @@ function Badge({
|
|
|
124
192
|
)
|
|
125
193
|
}
|
|
126
194
|
|
|
195
|
+
const LEADING_WRAP: ViewStyle = { justifyContent: 'center', alignItems: 'center' }
|
|
196
|
+
|
|
127
197
|
export default Badge
|
|
128
198
|
|
|
129
199
|
|