jfs-components 0.1.8 → 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 +16 -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/AreaLineChart/AreaLineChart.js +11 -7
- package/lib/commonjs/components/Badge/Badge.js +47 -8
- 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/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 +72 -43
- 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 +3 -2
- package/lib/commonjs/components/ExpandableCheckbox/ExpandableCheckbox.js +2 -1
- package/lib/commonjs/components/FormField/FormField.js +42 -2
- package/lib/commonjs/components/Gauge/Gauge.js +1 -1
- package/lib/commonjs/components/HoldingsCard/HoldingsCard.js +3 -2
- 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/PoweredByLabel/PoweredByLabel.js +3 -2
- package/lib/commonjs/components/ProductMerchandisingCard/ProductMerchandisingCard.js +107 -33
- 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 +3 -2
- package/lib/commonjs/components/Section/Section.js +3 -2
- package/lib/commonjs/components/Slider/Slider.js +3 -2
- 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 +9 -1
- package/lib/commonjs/components/TextSegment/TextSegment.js +2 -1
- 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 +44 -0
- package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/commonjs/design-tokens/figma-modes.generated.js +1 -0
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/commonjs/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.js +11 -3
- package/lib/commonjs/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.web.js +8 -4
- package/lib/commonjs/utils/react-utils.js +56 -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/AreaLineChart/AreaLineChart.js +12 -8
- package/lib/module/components/Badge/Badge.js +49 -10
- 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/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 +73 -44
- 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 +4 -3
- package/lib/module/components/ExpandableCheckbox/ExpandableCheckbox.js +2 -1
- package/lib/module/components/FormField/FormField.js +45 -5
- package/lib/module/components/Gauge/Gauge.js +1 -1
- package/lib/module/components/HoldingsCard/HoldingsCard.js +4 -3
- 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/PoweredByLabel/PoweredByLabel.js +4 -3
- package/lib/module/components/ProductMerchandisingCard/ProductMerchandisingCard.js +109 -35
- 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 +4 -3
- package/lib/module/components/Section/Section.js +4 -3
- package/lib/module/components/Slider/Slider.js +4 -3
- 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 +9 -1
- package/lib/module/components/TextSegment/TextSegment.js +3 -2
- 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 +2 -0
- package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/module/design-tokens/figma-modes.generated.js +1 -0
- package/lib/module/icons/registry.js +1 -1
- package/lib/module/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.js +11 -3
- package/lib/module/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.web.js +8 -4
- package/lib/module/utils/react-utils.js +54 -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/AreaLineChart/AreaLineChart.d.ts +8 -1
- package/lib/typescript/src/components/Badge/Badge.d.ts +32 -2
- 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/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 +7 -1
- 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 +6 -0
- package/lib/typescript/src/components/ExpandableCheckbox/ExpandableCheckbox.d.ts +7 -1
- package/lib/typescript/src/components/HoldingsCard/HoldingsCard.d.ts +7 -1
- 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/PoweredByLabel/PoweredByLabel.d.ts +7 -1
- package/lib/typescript/src/components/ProductMerchandisingCard/ProductMerchandisingCard.d.ts +7 -1
- 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 +7 -1
- package/lib/typescript/src/components/Section/Section.d.ts +7 -1
- package/lib/typescript/src/components/Slider/Slider.d.ts +6 -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/TextSegment/TextSegment.d.ts +7 -1
- 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 +4 -2
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/lib/typescript/src/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.d.ts +31 -3
- package/lib/typescript/src/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.web.d.ts +18 -2
- package/lib/typescript/src/utils/react-utils.d.ts +37 -0
- package/lib/typescript/src/utils/web-platform-utils.d.ts +36 -0
- package/package.json +1 -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/AreaLineChart/AreaLineChart.tsx +15 -5
- package/src/components/Badge/Badge.tsx +78 -8
- 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/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 +98 -50
- 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 +9 -2
- package/src/components/ExpandableCheckbox/ExpandableCheckbox.tsx +8 -1
- package/src/components/FormField/FormField.tsx +49 -4
- package/src/components/Gauge/Gauge.tsx +1 -1
- package/src/components/HoldingsCard/HoldingsCard.tsx +9 -2
- 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/PoweredByLabel/PoweredByLabel.tsx +9 -2
- package/src/components/ProductMerchandisingCard/ProductMerchandisingCard.tsx +104 -37
- package/src/components/ProductOverview/ProductOverview.tsx +10 -3
- package/src/components/ProgressBadge/ProgressBadge.tsx +9 -3
- package/src/components/ProjectionMarker/ProjectionMarker.tsx +9 -2
- package/src/components/Section/Section.tsx +10 -3
- package/src/components/Slider/Slider.tsx +9 -2
- 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 +7 -1
- package/src/components/TextSegment/TextSegment.tsx +9 -2
- 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 +23 -2
- package/src/design-tokens/Coin Variables-variables-full.json +1 -1
- package/src/design-tokens/figma-modes.generated.ts +1 -0
- package/src/icons/registry.ts +1 -1
- package/src/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.tsx +32 -3
- package/src/{components/ProductMerchandisingCard → utils/GlassFill}/GlassFill.web.tsx +25 -4
- package/src/utils/react-utils.ts +61 -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/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
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
14
14
|
import NavArrow from '../NavArrow/NavArrow'
|
|
15
15
|
import { usePressableWebSupport, type WebAccessibilityProps } from '../../utils/web-platform-utils'
|
|
16
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
16
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
17
17
|
import type { Modes } from '../../design-tokens'
|
|
18
18
|
|
|
19
19
|
type ListItemProps = {
|
|
@@ -45,6 +45,12 @@ type ListItemProps = {
|
|
|
45
45
|
* Web-specific accessibility props (only used on web platform)
|
|
46
46
|
*/
|
|
47
47
|
webAccessibilityProps?: WebAccessibilityProps;
|
|
48
|
+
/**
|
|
49
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
50
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
51
|
+
* lines as it needs even when horizontal space is tight.
|
|
52
|
+
*/
|
|
53
|
+
disableTruncation?: boolean;
|
|
48
54
|
} & React.ComponentProps<typeof View>;
|
|
49
55
|
|
|
50
56
|
// ---------------------------------------------------------------------------
|
|
@@ -230,6 +236,7 @@ function ListItemImpl({
|
|
|
230
236
|
accessibilityHint,
|
|
231
237
|
accessibilityState,
|
|
232
238
|
webAccessibilityProps,
|
|
239
|
+
disableTruncation,
|
|
233
240
|
...rest
|
|
234
241
|
}: ListItemProps) {
|
|
235
242
|
const tokens = useMemo(() => resolveListItemTokens(modes), [modes])
|
|
@@ -314,7 +321,7 @@ function ListItemImpl({
|
|
|
314
321
|
? [tokens.supportTextStyle, verticalSupportTextOverride]
|
|
315
322
|
: tokens.supportTextStyle
|
|
316
323
|
}
|
|
317
|
-
|
|
324
|
+
{...resolveTruncation(disableTruncation, layout === 'Horizontal' ? 2 : undefined)}
|
|
318
325
|
>
|
|
319
326
|
{displayText}
|
|
320
327
|
</Text>
|
|
@@ -382,7 +389,7 @@ function ListItemImpl({
|
|
|
382
389
|
>
|
|
383
390
|
<Text
|
|
384
391
|
style={tokens.titleTextStyle}
|
|
385
|
-
|
|
392
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
386
393
|
>
|
|
387
394
|
{title}
|
|
388
395
|
</Text>
|
|
@@ -2,7 +2,7 @@ import React, { createContext, useContext } from 'react'
|
|
|
2
2
|
import { View, Text, StyleSheet, type ViewStyle, type TextStyle, type StyleProp, type ImageSourcePropType } from 'react-native'
|
|
3
3
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
4
4
|
import Image from '../Image/Image'
|
|
5
|
-
import GlassFill, { type GlassTint } from '
|
|
5
|
+
import GlassFill, { type GlassTint } from '../../utils/GlassFill/GlassFill'
|
|
6
6
|
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
7
7
|
import type { Modes } from '../../design-tokens'
|
|
8
8
|
|
|
@@ -225,7 +225,7 @@ export function Footer({ children, style, modes: propModes }: { children?: React
|
|
|
225
225
|
]}
|
|
226
226
|
pointerEvents="box-none"
|
|
227
227
|
>
|
|
228
|
-
<GlassFill tint={tint} intensity={intensity} overlayColor={glassBgColor} />
|
|
228
|
+
<GlassFill tint={tint} intensity={intensity} overlayColor={glassBgColor} webBlurScale={0.3} webBlurMaxPx={30} />
|
|
229
229
|
|
|
230
230
|
<View
|
|
231
231
|
style={{
|
|
@@ -7,7 +7,7 @@ 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 type { Modes } from '../../design-tokens'
|
|
12
12
|
|
|
13
13
|
export type MetricLegendItemProps = {
|
|
@@ -39,6 +39,12 @@ export type MetricLegendItemProps = {
|
|
|
39
39
|
labelStyle?: StyleProp<TextStyle>
|
|
40
40
|
/** Override the value text styles. */
|
|
41
41
|
valueStyle?: StyleProp<TextStyle>
|
|
42
|
+
/**
|
|
43
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
44
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
45
|
+
* lines as it needs even when horizontal space is tight.
|
|
46
|
+
*/
|
|
47
|
+
disableTruncation?: boolean
|
|
42
48
|
}
|
|
43
49
|
|
|
44
50
|
/**
|
|
@@ -59,6 +65,7 @@ function MetricLegendItem({
|
|
|
59
65
|
indicatorStyle,
|
|
60
66
|
labelStyle,
|
|
61
67
|
valueStyle,
|
|
68
|
+
disableTruncation,
|
|
62
69
|
}: MetricLegendItemProps) {
|
|
63
70
|
const gap = (getVariableByName('metricLegendItem/gap', modes) as number | null) ?? 4
|
|
64
71
|
const textWrapGap =
|
|
@@ -169,7 +176,7 @@ function MetricLegendItem({
|
|
|
169
176
|
},
|
|
170
177
|
valueStyle,
|
|
171
178
|
]}
|
|
172
|
-
|
|
179
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
173
180
|
>
|
|
174
181
|
{value}
|
|
175
182
|
</Text>
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from 'react-native'
|
|
9
9
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
10
10
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
11
|
-
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
11
|
+
import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils'
|
|
12
12
|
import MetricLegendItem from '../MetricLegendItem/MetricLegendItem'
|
|
13
13
|
import type { Modes } from '../../design-tokens'
|
|
14
14
|
|
|
@@ -83,6 +83,12 @@ export type MonthlyStatusGridProps = {
|
|
|
83
83
|
legendStyle?: StyleProp<ViewStyle>
|
|
84
84
|
/** Accessibility label for the entire component. */
|
|
85
85
|
accessibilityLabel?: string
|
|
86
|
+
/**
|
|
87
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
88
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
89
|
+
* lines as it needs even when horizontal space is tight.
|
|
90
|
+
*/
|
|
91
|
+
disableTruncation?: boolean
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
const DEFAULT_MONTH_LABELS: readonly string[] = [
|
|
@@ -170,6 +176,12 @@ export type CalendarGlyphProps = {
|
|
|
170
176
|
labelStyle?: StyleProp<TextStyle>
|
|
171
177
|
/** Accessibility label. Defaults to `"{label}, {status}"`. */
|
|
172
178
|
accessibilityLabel?: string
|
|
179
|
+
/**
|
|
180
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
181
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
182
|
+
* lines as it needs even when horizontal space is tight.
|
|
183
|
+
*/
|
|
184
|
+
disableTruncation?: boolean
|
|
173
185
|
}
|
|
174
186
|
|
|
175
187
|
/**
|
|
@@ -186,6 +198,7 @@ function CalendarGlyph({
|
|
|
186
198
|
style,
|
|
187
199
|
labelStyle,
|
|
188
200
|
accessibilityLabel,
|
|
201
|
+
disableTruncation,
|
|
189
202
|
}: CalendarGlyphProps) {
|
|
190
203
|
const { modes: globalModes } = useTokens()
|
|
191
204
|
const modes = React.useMemo(
|
|
@@ -244,7 +257,7 @@ function CalendarGlyph({
|
|
|
244
257
|
]}
|
|
245
258
|
>
|
|
246
259
|
<Text
|
|
247
|
-
|
|
260
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
248
261
|
style={[
|
|
249
262
|
{
|
|
250
263
|
color: foreground,
|
|
@@ -312,6 +325,7 @@ function MonthlyStatusGrid({
|
|
|
312
325
|
labelStyle,
|
|
313
326
|
legendStyle,
|
|
314
327
|
accessibilityLabel,
|
|
328
|
+
disableTruncation,
|
|
315
329
|
}: MonthlyStatusGridProps) {
|
|
316
330
|
const { modes: globalModes } = useTokens()
|
|
317
331
|
const modes = React.useMemo(
|
|
@@ -391,6 +405,7 @@ function MonthlyStatusGrid({
|
|
|
391
405
|
label={label}
|
|
392
406
|
status={month.status}
|
|
393
407
|
modes={glyphModes}
|
|
408
|
+
disableTruncation={disableTruncation}
|
|
394
409
|
{...(glyphStyle !== undefined ? { style: glyphStyle } : {})}
|
|
395
410
|
{...(labelStyle !== undefined ? { labelStyle } : {})}
|
|
396
411
|
{...(month.accessibilityLabel !== undefined
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from 'react-native'
|
|
10
10
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
11
11
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
12
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
12
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
13
13
|
import MediaSource, { type UnifiedSource } from '../../utils/MediaSource'
|
|
14
14
|
import type { Modes } from '../../design-tokens'
|
|
15
15
|
|
|
@@ -65,6 +65,12 @@ export type PoweredByLabelProps = {
|
|
|
65
65
|
* (which is decorative) does not need to be announced separately.
|
|
66
66
|
*/
|
|
67
67
|
accessibilityLabel?: string
|
|
68
|
+
/**
|
|
69
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
70
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
71
|
+
* lines as it needs even when horizontal space is tight.
|
|
72
|
+
*/
|
|
73
|
+
disableTruncation?: boolean
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
const toNumber = (value: unknown, fallback: number): number => {
|
|
@@ -115,6 +121,7 @@ function PoweredByLabel({
|
|
|
115
121
|
textStyle,
|
|
116
122
|
imageStyle,
|
|
117
123
|
accessibilityLabel,
|
|
124
|
+
disableTruncation,
|
|
118
125
|
}: PoweredByLabelProps) {
|
|
119
126
|
const { modes: globalModes } = useTokens()
|
|
120
127
|
const modes = useMemo(
|
|
@@ -210,7 +217,7 @@ function PoweredByLabel({
|
|
|
210
217
|
style={[labelTextStyle, textStyle]}
|
|
211
218
|
accessibilityElementsHidden={true}
|
|
212
219
|
importantForAccessibility="no"
|
|
213
|
-
|
|
220
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
214
221
|
>
|
|
215
222
|
{label}
|
|
216
223
|
</Text>
|
|
@@ -4,21 +4,31 @@ import {
|
|
|
4
4
|
Text,
|
|
5
5
|
Pressable,
|
|
6
6
|
StyleSheet,
|
|
7
|
+
Platform,
|
|
8
|
+
Image as RNImage,
|
|
7
9
|
type ViewStyle,
|
|
8
10
|
type TextStyle,
|
|
9
11
|
type StyleProp,
|
|
10
12
|
type ImageSourcePropType,
|
|
11
13
|
} from 'react-native'
|
|
14
|
+
import MaskedView from '@react-native-masked-view/masked-view'
|
|
12
15
|
import Svg, { Defs, LinearGradient, Stop, Rect } from 'react-native-svg'
|
|
13
16
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
14
|
-
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
17
|
+
import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils'
|
|
15
18
|
import Avatar from '../Avatar/Avatar'
|
|
16
19
|
import Badge from '../Badge/Badge'
|
|
17
20
|
import Button from '../Button/Button'
|
|
18
21
|
import Image from '../Image/Image'
|
|
19
|
-
import GlassFill from '
|
|
22
|
+
import GlassFill from '../../utils/GlassFill/GlassFill'
|
|
20
23
|
import type { Modes } from '../../design-tokens'
|
|
21
24
|
|
|
25
|
+
function normalizeImageSource(
|
|
26
|
+
src: ImageSourcePropType | string | undefined
|
|
27
|
+
): ImageSourcePropType | undefined {
|
|
28
|
+
if (src == null) return undefined
|
|
29
|
+
return typeof src === 'string' ? { uri: src } : src
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
export interface ProductMerchandisingCardProps {
|
|
23
33
|
/**
|
|
24
34
|
* Background media for the card. Accepts a URL string or any RN
|
|
@@ -73,6 +83,12 @@ export interface ProductMerchandisingCardProps {
|
|
|
73
83
|
style?: StyleProp<ViewStyle>
|
|
74
84
|
/** Accessibility label for the card. */
|
|
75
85
|
accessibilityLabel?: string
|
|
86
|
+
/**
|
|
87
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
88
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
89
|
+
* lines as it needs even when horizontal space is tight.
|
|
90
|
+
*/
|
|
91
|
+
disableTruncation?: boolean
|
|
76
92
|
}
|
|
77
93
|
|
|
78
94
|
/**
|
|
@@ -116,10 +132,15 @@ function ProductMerchandisingCard({
|
|
|
116
132
|
modes = EMPTY_MODES,
|
|
117
133
|
style,
|
|
118
134
|
accessibilityLabel,
|
|
135
|
+
disableTruncation,
|
|
119
136
|
}: ProductMerchandisingCardProps) {
|
|
120
|
-
// Unique gradient
|
|
137
|
+
// Unique gradient ids so multiple cards on one (web) document never collide.
|
|
121
138
|
const rawId = useId()
|
|
122
|
-
const
|
|
139
|
+
const safeId = rawId.replace(/[^a-zA-Z0-9_-]/g, '')
|
|
140
|
+
const scrimId = `pmc-footer-scrim-${safeId}`
|
|
141
|
+
const blurMaskId = `pmc-footer-blurmask-${safeId}`
|
|
142
|
+
|
|
143
|
+
const normalizedImageSource = useMemo(() => normalizeImageSource(imageSource), [imageSource])
|
|
123
144
|
|
|
124
145
|
const tokens = useMemo(() => resolveTokens(modes), [modes])
|
|
125
146
|
|
|
@@ -159,23 +180,26 @@ function ProductMerchandisingCard({
|
|
|
159
180
|
)
|
|
160
181
|
: null
|
|
161
182
|
|
|
183
|
+
// The footer "special badge" is now the shared <Badge type="glass">. The
|
|
184
|
+
// hardcoded literals that defined its look (warm frosted overlay, gentle
|
|
185
|
+
// 5px blur, 6/2 padding, 4px radius, weight-500 white label) are preserved
|
|
186
|
+
// 1:1 via the glass overrides + `style`/`labelStyle`, and the optional
|
|
187
|
+
// `specialBadgeIcon` maps to Badge's `leading` slot — so every existing
|
|
188
|
+
// instantiation renders byte-for-byte the same as before.
|
|
162
189
|
const footerSpecialBadge =
|
|
163
190
|
specialBadge ??
|
|
164
191
|
(specialBadgeLabel != null ? (
|
|
165
|
-
<
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
{
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
{specialBadgeLabel}
|
|
177
|
-
</Text>
|
|
178
|
-
</View>
|
|
192
|
+
<Badge
|
|
193
|
+
type="glass"
|
|
194
|
+
label={specialBadgeLabel}
|
|
195
|
+
leading={specialBadgeIcon}
|
|
196
|
+
glassOverlayColor={SPECIAL_BADGE_BG}
|
|
197
|
+
glassIntensity={SPECIAL_BADGE_INTENSITY}
|
|
198
|
+
modes={modes}
|
|
199
|
+
style={styles.specialBadge}
|
|
200
|
+
labelStyle={tokens.specialBadgeText}
|
|
201
|
+
{...(disableTruncation != null ? { disableTruncation } : null)}
|
|
202
|
+
/>
|
|
179
203
|
) : null)
|
|
180
204
|
|
|
181
205
|
// The Figma CTA uses the brand "Secondary" appearance (purple fill, white
|
|
@@ -209,11 +233,49 @@ function ProductMerchandisingCard({
|
|
|
209
233
|
</View>
|
|
210
234
|
|
|
211
235
|
<View style={tokens.footer} pointerEvents="box-none">
|
|
212
|
-
{/* Progressive
|
|
213
|
-
soft blur at the bottom
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
236
|
+
{/* Progressive blur — clear at the top of the footer, ramping to
|
|
237
|
+
a soft blur at the bottom. Rather than the unmaintained native
|
|
238
|
+
BlurView (which renders as a flat black tint on Android +
|
|
239
|
+
Fabric and can hide the image on iOS), we reveal a *blurred
|
|
240
|
+
copy of the card's own image* through a vertical gradient
|
|
241
|
+
mask. `Image.blurRadius` is a built-in RN prop with a real
|
|
242
|
+
Gaussian blur on BOTH iOS and Android and needs no native
|
|
243
|
+
module. The blurred copy is pinned to the card's bottom at the
|
|
244
|
+
full card height so it lines up pixel-for-pixel with the
|
|
245
|
+
full-bleed background, and the mask makes the blur swell in
|
|
246
|
+
smoothly toward the bottom (true progressive blur). */}
|
|
247
|
+
{normalizedImageSource != null ? (
|
|
248
|
+
<View style={StyleSheet.absoluteFill} pointerEvents="none">
|
|
249
|
+
<MaskedView
|
|
250
|
+
style={StyleSheet.absoluteFill}
|
|
251
|
+
maskElement={
|
|
252
|
+
<Svg width="100%" height="100%">
|
|
253
|
+
<Defs>
|
|
254
|
+
<LinearGradient id={blurMaskId} x1="0" y1="0" x2="0" y2="1">
|
|
255
|
+
<Stop offset="0" stopColor="#000000" stopOpacity={0} />
|
|
256
|
+
<Stop offset="0.35" stopColor="#000000" stopOpacity={0.5} />
|
|
257
|
+
<Stop offset="0.7" stopColor="#000000" stopOpacity={0.92} />
|
|
258
|
+
<Stop offset="1" stopColor="#000000" stopOpacity={1} />
|
|
259
|
+
</LinearGradient>
|
|
260
|
+
</Defs>
|
|
261
|
+
<Rect x="0" y="0" width="100%" height="100%" fill={`url(#${blurMaskId})`} />
|
|
262
|
+
</Svg>
|
|
263
|
+
}
|
|
264
|
+
>
|
|
265
|
+
<RNImage
|
|
266
|
+
source={normalizedImageSource}
|
|
267
|
+
blurRadius={tokens.imageBlurRadius}
|
|
268
|
+
resizeMode="cover"
|
|
269
|
+
style={{ position: 'absolute', left: 0, right: 0, bottom: 0, width: '100%', height }}
|
|
270
|
+
/>
|
|
271
|
+
</MaskedView>
|
|
272
|
+
</View>
|
|
273
|
+
) : (
|
|
274
|
+
<GlassFill tint="dark" intensity={tokens.blurIntensity} progressive />
|
|
275
|
+
)}
|
|
276
|
+
{/* Transparent -> black gradient scrim for text legibility,
|
|
277
|
+
identical on all platforms. Kept lighter than a solid fill so
|
|
278
|
+
the blurred image stays visible behind the footer text. */}
|
|
217
279
|
<View style={[StyleSheet.absoluteFill, styles.scrim]} pointerEvents="none">
|
|
218
280
|
<Svg width="100%" height="100%">
|
|
219
281
|
<Defs>
|
|
@@ -230,11 +292,11 @@ function ProductMerchandisingCard({
|
|
|
230
292
|
|
|
231
293
|
<View style={styles.footerRow}>
|
|
232
294
|
<View style={tokens.textWrap}>
|
|
233
|
-
<Text style={tokens.title}
|
|
295
|
+
<Text style={tokens.title} {...resolveTruncation(disableTruncation, 1)}>
|
|
234
296
|
{title}
|
|
235
297
|
</Text>
|
|
236
298
|
{subtitle != null ? (
|
|
237
|
-
<Text style={tokens.subtitle}
|
|
299
|
+
<Text style={tokens.subtitle} {...resolveTruncation(disableTruncation, 1)}>
|
|
238
300
|
{subtitle}
|
|
239
301
|
</Text>
|
|
240
302
|
) : null}
|
|
@@ -286,6 +348,7 @@ const SPECIAL_BADGE_INTENSITY = 17 // ~5px CSS blur / ~2 native blurAmount
|
|
|
286
348
|
interface ResolvedTokens {
|
|
287
349
|
radius: number
|
|
288
350
|
blurIntensity: number
|
|
351
|
+
imageBlurRadius: number
|
|
289
352
|
header: ViewStyle
|
|
290
353
|
footer: ViewStyle
|
|
291
354
|
textWrap: ViewStyle
|
|
@@ -331,9 +394,20 @@ function resolveTokens(modes: Modes): ResolvedTokens {
|
|
|
331
394
|
const sbFamily = asStr(getVariableByName('productMerchandisingcard/specialbadge/text/fontfamily', modes), 'JioType Var')
|
|
332
395
|
const sbWeight = asStr(getVariableByName('productMerchandisingcard/specialbadge/text/fontweight', modes), '500')
|
|
333
396
|
|
|
397
|
+
// `Image.blurRadius` is interpreted differently per platform — iOS applies a
|
|
398
|
+
// strong Gaussian while Android's IterativeBoxBlur is gentler at the same
|
|
399
|
+
// numeric radius — so we tune each platform to land on the same perceived
|
|
400
|
+
// "minimal" frosted strength as the Figma design.
|
|
401
|
+
const imageBlurRadius = Platform.select({
|
|
402
|
+
ios: Math.max(6, Math.round(blurRadius * 0.5)),
|
|
403
|
+
android: Math.max(12, Math.round(blurRadius * 0.95)),
|
|
404
|
+
default: Math.max(8, Math.round(blurRadius * 0.6)),
|
|
405
|
+
}) as number
|
|
406
|
+
|
|
334
407
|
return {
|
|
335
408
|
radius,
|
|
336
409
|
blurIntensity: Math.max(0, Math.min(100, Math.round(blurRadius * BLUR_INTENSITY_FACTOR))),
|
|
410
|
+
imageBlurRadius,
|
|
337
411
|
header: {
|
|
338
412
|
flexDirection: 'row',
|
|
339
413
|
alignItems: 'flex-start',
|
|
@@ -398,22 +472,15 @@ const styles = StyleSheet.create({
|
|
|
398
472
|
// the intended fade strength.
|
|
399
473
|
opacity: 0.9,
|
|
400
474
|
},
|
|
475
|
+
// Overrides layered on top of <Badge type="glass">. Badge already supplies
|
|
476
|
+
// the row layout + 4px gap (when a leading icon is present), `overflow:
|
|
477
|
+
// 'hidden'`, `alignSelf: 'flex-start'` and `alignItems: 'center'`; these
|
|
478
|
+
// pin the special badge's literal Figma box (6/2 padding, 4px radius)
|
|
479
|
+
// regardless of the badge size tokens resolved by the active modes.
|
|
401
480
|
specialBadge: {
|
|
402
|
-
flexDirection: 'row',
|
|
403
|
-
alignItems: 'center',
|
|
404
|
-
gap: 4,
|
|
405
481
|
paddingHorizontal: 6,
|
|
406
482
|
paddingVertical: 2,
|
|
407
483
|
borderRadius: 4,
|
|
408
|
-
overflow: 'hidden',
|
|
409
|
-
alignSelf: 'flex-start',
|
|
410
|
-
},
|
|
411
|
-
specialBadgeFill: {
|
|
412
|
-
borderRadius: 4,
|
|
413
|
-
},
|
|
414
|
-
specialBadgeIcon: {
|
|
415
|
-
justifyContent: 'center',
|
|
416
|
-
alignItems: 'center',
|
|
417
484
|
},
|
|
418
485
|
pressed: {
|
|
419
486
|
opacity: 0.92,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type ImageSourcePropType,
|
|
9
9
|
} from 'react-native'
|
|
10
10
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
11
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
11
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
12
12
|
import Image from '../Image/Image'
|
|
13
13
|
import ProductLabel from '../ProductLabel/ProductLabel'
|
|
14
14
|
import type { Modes } from '../../design-tokens'
|
|
@@ -47,6 +47,12 @@ export type ProductOverviewProps = {
|
|
|
47
47
|
* for badges, callouts, etc. Receives the same `modes` as the parent.
|
|
48
48
|
*/
|
|
49
49
|
children?: React.ReactNode
|
|
50
|
+
/**
|
|
51
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
52
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
53
|
+
* lines as it needs even when horizontal space is tight.
|
|
54
|
+
*/
|
|
55
|
+
disableTruncation?: boolean
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
const DEFAULT_STATS: ProductOverviewStat[] = [
|
|
@@ -65,6 +71,7 @@ const ProductOverview = ({
|
|
|
65
71
|
modes = EMPTY_MODES,
|
|
66
72
|
style,
|
|
67
73
|
children,
|
|
74
|
+
disableTruncation,
|
|
68
75
|
}: ProductOverviewProps) => {
|
|
69
76
|
const padding = (getVariableByName('productOverview/padding', modes) as number | null) ?? 24
|
|
70
77
|
const gap = (getVariableByName('productOverview/gap', modes) as number | null) ?? 12
|
|
@@ -220,10 +227,10 @@ const ProductOverview = ({
|
|
|
220
227
|
overflow: 'hidden',
|
|
221
228
|
}}
|
|
222
229
|
>
|
|
223
|
-
<Text style={statValueStyle}
|
|
230
|
+
<Text style={statValueStyle} {...resolveTruncation(disableTruncation, 1)}>
|
|
224
231
|
{stat.value}
|
|
225
232
|
</Text>
|
|
226
|
-
<Text style={statLabelStyle}
|
|
233
|
+
<Text style={statLabelStyle} {...resolveTruncation(disableTruncation, 1)}>
|
|
227
234
|
{stat.label}
|
|
228
235
|
</Text>
|
|
229
236
|
</View>
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from 'react-native'
|
|
9
9
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
10
10
|
import Icon from '../../icons/Icon'
|
|
11
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
11
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
12
12
|
import type { Modes } from '../../design-tokens'
|
|
13
13
|
|
|
14
14
|
export type ProgressBadgeProps = {
|
|
@@ -26,6 +26,12 @@ export type ProgressBadgeProps = {
|
|
|
26
26
|
textStyle?: StyleProp<TextStyle>
|
|
27
27
|
/** Accessibility label for screen readers */
|
|
28
28
|
accessibilityLabel?: string
|
|
29
|
+
/**
|
|
30
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
31
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
32
|
+
* lines as it needs even when horizontal space is tight.
|
|
33
|
+
*/
|
|
34
|
+
disableTruncation?: boolean
|
|
29
35
|
} & React.ComponentProps<typeof View>
|
|
30
36
|
|
|
31
37
|
/**
|
|
@@ -51,6 +57,7 @@ function ProgressBadge({
|
|
|
51
57
|
style,
|
|
52
58
|
textStyle: textStyleOverride,
|
|
53
59
|
accessibilityLabel,
|
|
60
|
+
disableTruncation,
|
|
54
61
|
...rest
|
|
55
62
|
}: ProgressBadgeProps) {
|
|
56
63
|
// Resolve layout tokens
|
|
@@ -158,8 +165,7 @@ function ProgressBadge({
|
|
|
158
165
|
) : null}
|
|
159
166
|
<Text
|
|
160
167
|
style={[textStyle, textStyleOverride]}
|
|
161
|
-
|
|
162
|
-
ellipsizeMode="tail"
|
|
168
|
+
{...resolveTruncation(disableTruncation, 1, 'tail')}
|
|
163
169
|
accessibilityElementsHidden={true}
|
|
164
170
|
importantForAccessibility="no"
|
|
165
171
|
>
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type TextStyle,
|
|
8
8
|
} from 'react-native'
|
|
9
9
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
10
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
10
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
11
11
|
import type { Modes } from '../../design-tokens'
|
|
12
12
|
import Divider from '../Divider/Divider'
|
|
13
13
|
|
|
@@ -61,6 +61,12 @@ export type ProjectionMarkerProps = {
|
|
|
61
61
|
rateStyle?: StyleProp<TextStyle>
|
|
62
62
|
/** Accessibility label for the whole marker. */
|
|
63
63
|
accessibilityLabel?: string
|
|
64
|
+
/**
|
|
65
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
66
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
67
|
+
* lines as it needs even when horizontal space is tight.
|
|
68
|
+
*/
|
|
69
|
+
disableTruncation?: boolean
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
const isTextValue = (value: React.ReactNode): value is string | number =>
|
|
@@ -106,6 +112,7 @@ function ProjectionMarker({
|
|
|
106
112
|
durationStyle,
|
|
107
113
|
rateStyle,
|
|
108
114
|
accessibilityLabel,
|
|
115
|
+
disableTruncation,
|
|
109
116
|
}: ProjectionMarkerProps) {
|
|
110
117
|
const titleColor =
|
|
111
118
|
(getVariableByName('projectionMarker/title/color', modes) as string | null) ?? '#000000'
|
|
@@ -169,7 +176,7 @@ function ProjectionMarker({
|
|
|
169
176
|
if (value === null || value === undefined) return null
|
|
170
177
|
if (isTextValue(value)) {
|
|
171
178
|
return (
|
|
172
|
-
<Text style={[titleTextStyle, overrideStyle]}
|
|
179
|
+
<Text style={[titleTextStyle, overrideStyle]} {...resolveTruncation(disableTruncation, 1)}>
|
|
173
180
|
{value}
|
|
174
181
|
</Text>
|
|
175
182
|
)
|
|
@@ -14,7 +14,7 @@ import NavArrow from '../NavArrow/NavArrow'
|
|
|
14
14
|
import IconCapsule from '../IconCapsule/IconCapsule'
|
|
15
15
|
import ListItem from '../ListItem/ListItem'
|
|
16
16
|
import { usePressableWebSupport, type WebAccessibilityProps } from '../../utils/web-platform-utils'
|
|
17
|
-
import { EMPTY_MODES, cloneChildrenWithModes, flattenChildren } from '../../utils/react-utils'
|
|
17
|
+
import { EMPTY_MODES, cloneChildrenWithModes, flattenChildren, resolveTruncation } from '../../utils/react-utils'
|
|
18
18
|
import type { Modes } from '../../design-tokens'
|
|
19
19
|
|
|
20
20
|
// Match Button: delay the press visual on iOS so a scroll-cancelled touch
|
|
@@ -366,6 +366,12 @@ type SectionProps = {
|
|
|
366
366
|
* Web-specific accessibility props (only used on web platform)
|
|
367
367
|
*/
|
|
368
368
|
webAccessibilityProps?: WebAccessibilityProps;
|
|
369
|
+
/**
|
|
370
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
371
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
372
|
+
* lines as it needs even when horizontal space is tight.
|
|
373
|
+
*/
|
|
374
|
+
disableTruncation?: boolean;
|
|
369
375
|
} & React.ComponentProps<typeof View>;
|
|
370
376
|
|
|
371
377
|
/**
|
|
@@ -483,6 +489,7 @@ function Section({
|
|
|
483
489
|
accessibilityLabel: _accessibilityLabel,
|
|
484
490
|
accessibilityHint,
|
|
485
491
|
webAccessibilityProps,
|
|
492
|
+
disableTruncation,
|
|
486
493
|
...rest
|
|
487
494
|
}: SectionProps) {
|
|
488
495
|
// Focus and hover are still mirrored in React because they are visible,
|
|
@@ -527,7 +534,7 @@ function Section({
|
|
|
527
534
|
<View style={headerWrapStyle}>
|
|
528
535
|
<Text
|
|
529
536
|
style={tokens.titleStyle}
|
|
530
|
-
|
|
537
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
531
538
|
accessibilityElementsHidden={true}
|
|
532
539
|
importantForAccessibility="no"
|
|
533
540
|
>
|
|
@@ -540,7 +547,7 @@ function Section({
|
|
|
540
547
|
{showSupportText && (
|
|
541
548
|
<Text
|
|
542
549
|
style={tokens.supportTextStyle}
|
|
543
|
-
|
|
550
|
+
{...resolveTruncation(disableTruncation, 2)}
|
|
544
551
|
accessibilityElementsHidden={true}
|
|
545
552
|
importantForAccessibility="no"
|
|
546
553
|
>
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from 'react-native'
|
|
20
20
|
import Svg, { Path } from 'react-native-svg'
|
|
21
21
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
22
|
-
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
22
|
+
import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils'
|
|
23
23
|
import type { Modes } from '../../design-tokens'
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -100,6 +100,12 @@ export interface SliderProps {
|
|
|
100
100
|
style?: StyleProp<ViewStyle>
|
|
101
101
|
/** Accessibility label for screen readers. */
|
|
102
102
|
accessibilityLabel?: string
|
|
103
|
+
/**
|
|
104
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
105
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
106
|
+
* lines as it needs even when horizontal space is tight.
|
|
107
|
+
*/
|
|
108
|
+
disableTruncation?: boolean
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
const clamp = (n: number, min: number, max: number) => Math.min(Math.max(n, min), max)
|
|
@@ -151,6 +157,7 @@ const Slider = forwardRef<SliderHandle, SliderProps>(function Slider(
|
|
|
151
157
|
modes = EMPTY_MODES,
|
|
152
158
|
style,
|
|
153
159
|
accessibilityLabel,
|
|
160
|
+
disableTruncation,
|
|
154
161
|
},
|
|
155
162
|
ref
|
|
156
163
|
) {
|
|
@@ -365,7 +372,7 @@ const Slider = forwardRef<SliderHandle, SliderProps>(function Slider(
|
|
|
365
372
|
{renderTooltip ? (
|
|
366
373
|
renderTooltip(currentValue)
|
|
367
374
|
) : (
|
|
368
|
-
<Text style={tokens.tooltipLabel}
|
|
375
|
+
<Text style={tokens.tooltipLabel} {...resolveTruncation(disableTruncation, 1)}>
|
|
369
376
|
{valueText}
|
|
370
377
|
</Text>
|
|
371
378
|
)}
|