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
|
@@ -10,8 +10,9 @@ import {
|
|
|
10
10
|
type TextStyle,
|
|
11
11
|
} from 'react-native'
|
|
12
12
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
13
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
13
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
14
14
|
import Accordion from '../Accordion/Accordion'
|
|
15
|
+
import Table from '../Table/Table'
|
|
15
16
|
import Image from '../Image/Image'
|
|
16
17
|
import IconButton from '../IconButton/IconButton'
|
|
17
18
|
import Icon from '../../icons/Icon'
|
|
@@ -133,6 +134,12 @@ export type CompareTableProps = {
|
|
|
133
134
|
modes?: Modes;
|
|
134
135
|
/** Override the outer container style. */
|
|
135
136
|
style?: StyleProp<ViewStyle>;
|
|
137
|
+
/**
|
|
138
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
139
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
140
|
+
* lines as it needs even when horizontal space is tight.
|
|
141
|
+
*/
|
|
142
|
+
disableTruncation?: boolean;
|
|
136
143
|
};
|
|
137
144
|
|
|
138
145
|
const DEFAULT_COLUMNS: CompareTableColumn[] = [
|
|
@@ -173,6 +180,7 @@ function CompareTable({
|
|
|
173
180
|
maxColumns = 4,
|
|
174
181
|
modes = EMPTY_MODES,
|
|
175
182
|
style,
|
|
183
|
+
disableTruncation,
|
|
176
184
|
}: CompareTableProps) {
|
|
177
185
|
// --- selection card tokens ------------------------------------------------
|
|
178
186
|
const cardBg = (getVariableByName('selectionCard/background/color', modes) as string) ?? '#ffffff'
|
|
@@ -186,6 +194,11 @@ function CompareTable({
|
|
|
186
194
|
const cardLabelFontFamily = (getVariableByName('selectionCard/label/fontfamily', modes) as string) ?? 'JioType Var'
|
|
187
195
|
const cardLabelFontWeight = (getVariableByName('selectionCard/label/fontweight', modes) as number | string) ?? 700
|
|
188
196
|
const imageRadius = (getVariableByName('image/radius', modes) as number) ?? 8
|
|
197
|
+
// `selectionCard/radius` (Figma node 5568:3487) rounds the card corners.
|
|
198
|
+
// The published token store is still out of sync (the variable resolves to
|
|
199
|
+
// `0` in the design), so the read falls back to `0` and will pick up a
|
|
200
|
+
// rounded value automatically once the store syncs.
|
|
201
|
+
const cardRadius = (getVariableByName('selectionCard/radius', modes) as number) ?? 0
|
|
189
202
|
|
|
190
203
|
// --- add-a-card icon button tokens ---------------------------------------
|
|
191
204
|
// padding/size/border come from the shared iconButton tokens; the filled
|
|
@@ -195,6 +208,9 @@ function CompareTable({
|
|
|
195
208
|
const addBorderSize = (getVariableByName('iconButton/border/size', modes) as number) ?? 1
|
|
196
209
|
const addPadding = (getVariableByName('iconButton/padding', modes) as number) ?? 11
|
|
197
210
|
const addIconSize = (getVariableByName('iconButton/icon/size', modes) as number) ?? 18
|
|
211
|
+
// `iconButton/radius` is the design-token sentinel `9999` ("perfect
|
|
212
|
+
// circle"), mirroring IconButton's own resolution.
|
|
213
|
+
const addRadius = (getVariableByName('iconButton/radius', modes) as number) ?? 9999
|
|
198
214
|
const addBg = ADD_BUTTON_BG
|
|
199
215
|
const addIconColor = ADD_BUTTON_ICON_COLOR
|
|
200
216
|
|
|
@@ -220,6 +236,8 @@ function CompareTable({
|
|
|
220
236
|
|
|
221
237
|
const columnCount = columns.length
|
|
222
238
|
const showAddCard = onAddColumn != null && columnCount < maxColumns
|
|
239
|
+
/** Grid columns shared by the selection-card row and every table row. */
|
|
240
|
+
const gridColumnCount = columnCount + (showAddCard ? 1 : 0)
|
|
223
241
|
|
|
224
242
|
const cardLabelStyle: TextStyle = {
|
|
225
243
|
...NO_WRAP_TEXT,
|
|
@@ -259,6 +277,7 @@ function CompareTable({
|
|
|
259
277
|
minWidth: 0,
|
|
260
278
|
minHeight: 147,
|
|
261
279
|
backgroundColor: cardBg,
|
|
280
|
+
borderRadius: cardRadius,
|
|
262
281
|
alignItems: 'center',
|
|
263
282
|
justifyContent: 'center',
|
|
264
283
|
gap: cardGap,
|
|
@@ -292,7 +311,7 @@ function CompareTable({
|
|
|
292
311
|
/>
|
|
293
312
|
)}
|
|
294
313
|
{column.label != null && (
|
|
295
|
-
<Text style={cardLabelStyle}
|
|
314
|
+
<Text style={cardLabelStyle} {...resolveTruncation(disableTruncation, 2)}>
|
|
296
315
|
{column.label}
|
|
297
316
|
</Text>
|
|
298
317
|
)}
|
|
@@ -334,7 +353,7 @@ function CompareTable({
|
|
|
334
353
|
style={{
|
|
335
354
|
width: addPadding * 2 + addIconSize,
|
|
336
355
|
height: addPadding * 2 + addIconSize,
|
|
337
|
-
borderRadius:
|
|
356
|
+
borderRadius: addRadius,
|
|
338
357
|
borderWidth: addBorderSize,
|
|
339
358
|
borderColor: addBorderColor,
|
|
340
359
|
backgroundColor: addBg,
|
|
@@ -350,7 +369,7 @@ function CompareTable({
|
|
|
350
369
|
importantForAccessibility="no"
|
|
351
370
|
/>
|
|
352
371
|
</View>
|
|
353
|
-
<Text style={cardLabelStyle}
|
|
372
|
+
<Text style={cardLabelStyle} {...resolveTruncation(disableTruncation, 1)}>
|
|
354
373
|
{addColumnLabel}
|
|
355
374
|
</Text>
|
|
356
375
|
</Pressable>
|
|
@@ -380,61 +399,91 @@ function CompareTable({
|
|
|
380
399
|
return cloneChildrenWithModes(value, modes)
|
|
381
400
|
}
|
|
382
401
|
|
|
402
|
+
// Renders a section's comparison grid using the shared `Table` component.
|
|
403
|
+
// CompareTable keeps ownership of token resolution and passes the resolved
|
|
404
|
+
// values as style overrides so the appearance is byte-identical to the
|
|
405
|
+
// previous hand-rolled grid (full outer border + suppressed last-edge
|
|
406
|
+
// dividers), while reusing Table's structure and `modes` cascade.
|
|
407
|
+
//
|
|
408
|
+
// When the "Add a card" tile is visible, each table row appends an empty
|
|
409
|
+
// trailing cell with the same flex weight so data columns stay 1:1 beneath
|
|
410
|
+
// their selection card.
|
|
411
|
+
const renderTableCell = (
|
|
412
|
+
content: React.ReactNode,
|
|
413
|
+
colIndex: number,
|
|
414
|
+
isLastRow: boolean,
|
|
415
|
+
key: React.Key,
|
|
416
|
+
) => {
|
|
417
|
+
const isLastCol = colIndex === gridColumnCount - 1
|
|
418
|
+
return (
|
|
419
|
+
<Table.Cell
|
|
420
|
+
key={key}
|
|
421
|
+
modes={modes}
|
|
422
|
+
flex={1}
|
|
423
|
+
align="left"
|
|
424
|
+
isLastColumn={isLastCol}
|
|
425
|
+
isLastRow={isLastRow}
|
|
426
|
+
style={{
|
|
427
|
+
backgroundColor: cellBg,
|
|
428
|
+
borderColor: cellBorderColor,
|
|
429
|
+
borderRightWidth: isLastCol ? 0 : cellBorderSize,
|
|
430
|
+
borderBottomWidth: isLastRow ? 0 : cellBorderSize,
|
|
431
|
+
paddingHorizontal: cellPaddingH,
|
|
432
|
+
paddingVertical: cellPaddingV,
|
|
433
|
+
}}
|
|
434
|
+
>
|
|
435
|
+
{content}
|
|
436
|
+
</Table.Cell>
|
|
437
|
+
)
|
|
438
|
+
}
|
|
439
|
+
|
|
383
440
|
const renderTable = (section: CompareTableSection) => (
|
|
384
|
-
<
|
|
441
|
+
<Table
|
|
442
|
+
modes={modes}
|
|
385
443
|
style={{
|
|
386
444
|
width: '100%',
|
|
387
445
|
borderWidth: cellBorderSize,
|
|
388
446
|
borderColor: cellBorderColor,
|
|
389
|
-
overflow: 'hidden',
|
|
390
447
|
}}
|
|
391
448
|
>
|
|
392
449
|
{section.header != null && (
|
|
393
|
-
<
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
paddingHorizontal: headerPaddingH,
|
|
397
|
-
paddingVertical: headerPaddingV,
|
|
398
|
-
borderBottomWidth: cellBorderSize,
|
|
399
|
-
borderBottomColor: cellBorderColor,
|
|
400
|
-
}}
|
|
450
|
+
<Table.Header
|
|
451
|
+
modes={modes}
|
|
452
|
+
style={{ borderBottomWidth: cellBorderSize, borderBottomColor: cellBorderColor }}
|
|
401
453
|
>
|
|
402
|
-
<
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
style={{ flexDirection: 'row', width: '100%' }}
|
|
454
|
+
<Table.HeaderCell
|
|
455
|
+
modes={modes}
|
|
456
|
+
flex={1}
|
|
457
|
+
style={{
|
|
458
|
+
backgroundColor: headerBg,
|
|
459
|
+
paddingHorizontal: headerPaddingH,
|
|
460
|
+
paddingVertical: headerPaddingV,
|
|
461
|
+
}}
|
|
411
462
|
>
|
|
412
|
-
{
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
})}
|
|
437
|
-
</View>
|
|
463
|
+
<Text style={headerTextStyle}>{section.header}</Text>
|
|
464
|
+
</Table.HeaderCell>
|
|
465
|
+
</Table.Header>
|
|
466
|
+
)}
|
|
467
|
+
<Table.Body modes={modes}>
|
|
468
|
+
{section.rows.map((row, rowIndex) => {
|
|
469
|
+
const isLastRow = rowIndex === section.rows.length - 1
|
|
470
|
+
return (
|
|
471
|
+
<Table.Row key={row.key ?? rowIndex} modes={modes}>
|
|
472
|
+
{Array.from({ length: columnCount }).map((_, colIndex) =>
|
|
473
|
+
renderTableCell(
|
|
474
|
+
renderCellContent(row.values?.[colIndex], `${rowIndex}-${colIndex}`),
|
|
475
|
+
colIndex,
|
|
476
|
+
isLastRow,
|
|
477
|
+
colIndex,
|
|
478
|
+
),
|
|
479
|
+
)}
|
|
480
|
+
{showAddCard &&
|
|
481
|
+
renderTableCell(null, gridColumnCount - 1, isLastRow, '__add_spacer__')}
|
|
482
|
+
</Table.Row>
|
|
483
|
+
)
|
|
484
|
+
})}
|
|
485
|
+
</Table.Body>
|
|
486
|
+
</Table>
|
|
438
487
|
)
|
|
439
488
|
|
|
440
489
|
return (
|
|
@@ -464,7 +513,6 @@ function CompareTable({
|
|
|
464
513
|
title={section.title}
|
|
465
514
|
defaultExpanded={section.defaultExpanded ?? index === 0}
|
|
466
515
|
modes={modes}
|
|
467
|
-
style={{ paddingHorizontal: headerPaddingH }}
|
|
468
516
|
>
|
|
469
517
|
{renderTable(section)}
|
|
470
518
|
</Accordion>
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import Svg, { Rect } from 'react-native-svg'
|
|
11
11
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
12
12
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
13
|
-
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
13
|
+
import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils'
|
|
14
14
|
import MetricLegendItem from '../MetricLegendItem/MetricLegendItem'
|
|
15
15
|
import type { Modes } from '../../design-tokens'
|
|
16
16
|
|
|
@@ -97,6 +97,12 @@ export type CoverageBarComparisonProps = {
|
|
|
97
97
|
labelStyle?: StyleProp<TextStyle>
|
|
98
98
|
/** Accessibility label for the entire component. */
|
|
99
99
|
accessibilityLabel?: string
|
|
100
|
+
/**
|
|
101
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
102
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
103
|
+
* lines as it needs even when horizontal space is tight.
|
|
104
|
+
*/
|
|
105
|
+
disableTruncation?: boolean
|
|
100
106
|
}
|
|
101
107
|
|
|
102
108
|
/**
|
|
@@ -221,6 +227,7 @@ function CoverageBarComparison({
|
|
|
221
227
|
legendStyle,
|
|
222
228
|
labelStyle,
|
|
223
229
|
accessibilityLabel,
|
|
230
|
+
disableTruncation,
|
|
224
231
|
}: CoverageBarComparisonProps) {
|
|
225
232
|
const { modes: globalModes } = useTokens()
|
|
226
233
|
const modes = React.useMemo(
|
|
@@ -331,7 +338,7 @@ function CoverageBarComparison({
|
|
|
331
338
|
>
|
|
332
339
|
{hasLabel ? (
|
|
333
340
|
<Text
|
|
334
|
-
|
|
341
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
335
342
|
style={[computedLabelStyle, labelStyle]}
|
|
336
343
|
>
|
|
337
344
|
{original.label}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import Svg, { Circle } from 'react-native-svg'
|
|
11
11
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
12
12
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
13
|
-
import { EMPTY_MODES, flattenChildren } from '../../utils/react-utils'
|
|
13
|
+
import { EMPTY_MODES, flattenChildren, resolveTruncation } from '../../utils/react-utils'
|
|
14
14
|
import type { Modes } from '../../design-tokens'
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -83,6 +83,12 @@ export type DonutChartProps = {
|
|
|
83
83
|
labelStyle?: StyleProp<TextStyle>
|
|
84
84
|
/** Accessibility label announced for the whole donut chart. */
|
|
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_APPEARANCE_CYCLE = [
|
|
@@ -222,6 +228,7 @@ function DonutChart({
|
|
|
222
228
|
valueStyle,
|
|
223
229
|
labelStyle,
|
|
224
230
|
accessibilityLabel,
|
|
231
|
+
disableTruncation,
|
|
225
232
|
}: DonutChartProps) {
|
|
226
233
|
const { modes: globalModes } = useTokens()
|
|
227
234
|
const modes = { ...globalModes, ...propModes }
|
|
@@ -388,7 +395,7 @@ function DonutChart({
|
|
|
388
395
|
},
|
|
389
396
|
valueStyle,
|
|
390
397
|
]}
|
|
391
|
-
|
|
398
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
392
399
|
>
|
|
393
400
|
{value}
|
|
394
401
|
</Text>
|
|
@@ -406,7 +413,7 @@ function DonutChart({
|
|
|
406
413
|
},
|
|
407
414
|
labelStyle,
|
|
408
415
|
]}
|
|
409
|
-
|
|
416
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
410
417
|
>
|
|
411
418
|
{label}
|
|
412
419
|
</Text>
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from 'react-native'
|
|
14
14
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
15
15
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
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
|
|
|
@@ -57,6 +57,12 @@ export type DropdownItemProps = {
|
|
|
57
57
|
accessibilityLabel?: string
|
|
58
58
|
/** Accessibility hint. */
|
|
59
59
|
accessibilityHint?: string
|
|
60
|
+
/**
|
|
61
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
62
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
63
|
+
* lines as it needs even when horizontal space is tight.
|
|
64
|
+
*/
|
|
65
|
+
disableTruncation?: boolean
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
function useDropdownItemTokens(modes: Modes) {
|
|
@@ -128,6 +134,7 @@ export function DropdownItem({
|
|
|
128
134
|
labelStyle,
|
|
129
135
|
accessibilityLabel,
|
|
130
136
|
accessibilityHint,
|
|
137
|
+
disableTruncation,
|
|
131
138
|
}: DropdownItemProps) {
|
|
132
139
|
const { modes: globalModes } = useTokens()
|
|
133
140
|
const modes = useMemo(
|
|
@@ -226,7 +233,7 @@ export function DropdownItem({
|
|
|
226
233
|
{children != null ? (
|
|
227
234
|
children
|
|
228
235
|
) : (
|
|
229
|
-
<Text style={[textStyle, labelStyle]}
|
|
236
|
+
<Text style={[textStyle, labelStyle]} {...resolveTruncation(disableTruncation, 1)}>
|
|
230
237
|
{label}
|
|
231
238
|
</Text>
|
|
232
239
|
)}
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
25
25
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
26
26
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
27
|
-
import { EMPTY_MODES, flattenChildren } from '../../utils/react-utils'
|
|
27
|
+
import { EMPTY_MODES, flattenChildren, resolveTruncation } from '../../utils/react-utils'
|
|
28
28
|
import Icon from '../../icons/Icon'
|
|
29
29
|
import SupportText from '../SupportText/SupportText'
|
|
30
30
|
import type { SupportTextStatus } from '../SupportText/SupportTextIcon'
|
|
@@ -171,6 +171,12 @@ export type DropdownInputProps = {
|
|
|
171
171
|
onFocus?: (e: any) => void
|
|
172
172
|
/** Called when the trigger loses focus (web only). */
|
|
173
173
|
onBlur?: (e: any) => void
|
|
174
|
+
/**
|
|
175
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
176
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
177
|
+
* lines as it needs even when horizontal space is tight.
|
|
178
|
+
*/
|
|
179
|
+
disableTruncation?: boolean
|
|
174
180
|
}
|
|
175
181
|
|
|
176
182
|
// ---------------------------------------------------------------------------
|
|
@@ -362,6 +368,7 @@ const DropdownInput = forwardRef<DropdownInputHandle, DropdownInputProps>(functi
|
|
|
362
368
|
accessibilityHint,
|
|
363
369
|
onFocus,
|
|
364
370
|
onBlur,
|
|
371
|
+
disableTruncation,
|
|
365
372
|
}: DropdownInputProps, ref: React.Ref<DropdownInputHandle>) {
|
|
366
373
|
// ---------------- Modes ----------------
|
|
367
374
|
const { modes: globalModes } = useTokens()
|
|
@@ -829,7 +836,7 @@ const DropdownInput = forwardRef<DropdownInputHandle, DropdownInputProps>(functi
|
|
|
829
836
|
valueTextStyle,
|
|
830
837
|
!hasValue && { color: placeholderColor },
|
|
831
838
|
]}
|
|
832
|
-
|
|
839
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
833
840
|
>
|
|
834
841
|
{displayLabel}
|
|
835
842
|
</Text>
|
|
@@ -35,6 +35,12 @@ export type ExpandableCheckboxProps = {
|
|
|
35
35
|
readLessLabel?: string
|
|
36
36
|
/** Number of lines to show when collapsed. Defaults to `1`. */
|
|
37
37
|
collapsedLines?: number
|
|
38
|
+
/**
|
|
39
|
+
* When `true`, disables truncation of the collapsed label: the trailing
|
|
40
|
+
* ellipsis (`…`) is never shown and the `collapsedLines` clamp is ignored, so
|
|
41
|
+
* the label wraps fully even when horizontal space is tight.
|
|
42
|
+
*/
|
|
43
|
+
disableTruncation?: boolean
|
|
38
44
|
/** Design token modes for theming (e.g. `{ 'Color Mode': 'Light' }`). */
|
|
39
45
|
modes?: Modes
|
|
40
46
|
/** Override outer container styles. */
|
|
@@ -96,6 +102,7 @@ function ExpandableCheckbox({
|
|
|
96
102
|
readMoreLabel = 'Read more',
|
|
97
103
|
readLessLabel = 'Read less',
|
|
98
104
|
collapsedLines = 1,
|
|
105
|
+
disableTruncation = false,
|
|
99
106
|
modes = EMPTY_MODES,
|
|
100
107
|
style,
|
|
101
108
|
labelStyle,
|
|
@@ -205,7 +212,7 @@ function ExpandableCheckbox({
|
|
|
205
212
|
const buttonLabel = isExpanded ? readLessLabel : readMoreLabel
|
|
206
213
|
|
|
207
214
|
const labelNumberOfLinesProps =
|
|
208
|
-
!isExpanded && collapsedLines > 0
|
|
215
|
+
!disableTruncation && !isExpanded && collapsedLines > 0
|
|
209
216
|
? { numberOfLines: collapsedLines, ellipsizeMode: 'tail' as const }
|
|
210
217
|
: null
|
|
211
218
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import React, { forwardRef, useCallback, useMemo, useState } from 'react'
|
|
1
|
+
import React, { forwardRef, useCallback, useMemo, useRef, useState } from 'react'
|
|
2
2
|
import {
|
|
3
|
+
Platform,
|
|
3
4
|
View,
|
|
4
5
|
Text,
|
|
5
6
|
TextInput as RNTextInput,
|
|
@@ -10,7 +11,8 @@ import {
|
|
|
10
11
|
} from 'react-native'
|
|
11
12
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
12
13
|
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
13
|
-
import { EMPTY_MODES, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
14
|
+
import { EMPTY_MODES, cloneChildrenWithModes, mergeRefs } from '../../utils/react-utils'
|
|
15
|
+
import { useWebOutsidePress } from '../../utils/web-platform-utils'
|
|
14
16
|
import SupportText from '../SupportText/SupportText'
|
|
15
17
|
import type { SupportTextStatus } from '../SupportText/SupportTextIcon'
|
|
16
18
|
import Icon from '../../icons/Icon'
|
|
@@ -347,6 +349,25 @@ const FormField = forwardRef<RNTextInput, FormFieldProps>(function FormField({
|
|
|
347
349
|
const [isFocused, setIsFocused] = useState(false)
|
|
348
350
|
const interactive = !isDisabled && !isReadOnly
|
|
349
351
|
|
|
352
|
+
// Internal handles so we can (a) imperatively blur the input and (b) detect
|
|
353
|
+
// outside presses. The forwarded `ref` is merged in below, so the public
|
|
354
|
+
// ref API (focus/blur/clear/isFocused) is unchanged for consumers.
|
|
355
|
+
const inputRef = useRef<RNTextInput>(null)
|
|
356
|
+
const rootRef = useRef<View>(null)
|
|
357
|
+
// Stable merged ref so React doesn't detach/reattach (and momentarily null
|
|
358
|
+
// `inputRef.current`) on every render.
|
|
359
|
+
const mergedInputRef = useMemo(() => mergeRefs(inputRef, ref), [ref])
|
|
360
|
+
|
|
361
|
+
// Web: pressing an INTERACTIVE element outside the field (Button, link,
|
|
362
|
+
// another pressable) often does not move DOM focus, so the native `blur`
|
|
363
|
+
// never fires and the field stays visually "Active". Force a blur on any
|
|
364
|
+
// outside pointer press while focused. No-op on native.
|
|
365
|
+
useWebOutsidePress(
|
|
366
|
+
rootRef,
|
|
367
|
+
useCallback(() => inputRef.current?.blur(), []),
|
|
368
|
+
isFocused,
|
|
369
|
+
)
|
|
370
|
+
|
|
350
371
|
// FormField States cascade — error > read only/disabled > active (focused) > idle.
|
|
351
372
|
// Disabled maps to "Read Only" since there is no dedicated disabled mode and
|
|
352
373
|
// the visual treatment is closest. This is only the DEFAULT — an explicit
|
|
@@ -478,7 +499,30 @@ const FormField = forwardRef<RNTextInput, FormFieldProps>(function FormField({
|
|
|
478
499
|
color: tokens.inputTextColor,
|
|
479
500
|
fontFamily: tokens.inputFontFamily,
|
|
480
501
|
fontSize: tokens.inputFontSize,
|
|
481
|
-
lineHeight: tokens.inputLineHeight
|
|
502
|
+
// ⚠️ DO NOT change to an unconditional `lineHeight: tokens.inputLineHeight`.
|
|
503
|
+
// This has regressed twice — read this before "simplifying" it.
|
|
504
|
+
//
|
|
505
|
+
// `inputLineHeight` comes from the Figma token `formField/input/label`
|
|
506
|
+
// ("16/45"), which is a 16px font inside a 45px ROW, i.e. it is the row
|
|
507
|
+
// HEIGHT, not the text leading. The row height is already applied via
|
|
508
|
+
// `inputRowStyle.minHeight` + `alignItems: 'center'`, so the text never
|
|
509
|
+
// needs this value as its own `lineHeight`.
|
|
510
|
+
//
|
|
511
|
+
// Passing a `lineHeight` (45) that is much larger than `fontSize` (16)
|
|
512
|
+
// onto a single-line RNTextInput breaks ONLY iOS: iOS puts ALL the extra
|
|
513
|
+
// vertical space ABOVE the glyphs, so the text/placeholder sinks to the
|
|
514
|
+
// bottom of the box instead of centering. Android and Web distribute the
|
|
515
|
+
// space evenly and look correct. This is a long-standing iOS native
|
|
516
|
+
// font-metrics bug in UITextField — see facebook/react-native#39145 and
|
|
517
|
+
// #28012; the documented workaround is exactly "drop lineHeight on the
|
|
518
|
+
// single-line input and let a wrapper center it". A single-line UITextField
|
|
519
|
+
// with no lineHeight centers its text natively (see react-native#56774).
|
|
520
|
+
//
|
|
521
|
+
// So: omit lineHeight on iOS (native centering via the row), and keep the
|
|
522
|
+
// token value on Android/Web where it already renders correctly.
|
|
523
|
+
...(Platform.OS === 'ios'
|
|
524
|
+
? null
|
|
525
|
+
: { lineHeight: tokens.inputLineHeight }),
|
|
482
526
|
fontWeight: tokens.inputFontWeight,
|
|
483
527
|
padding: 0,
|
|
484
528
|
margin: 0,
|
|
@@ -530,6 +574,7 @@ const FormField = forwardRef<RNTextInput, FormFieldProps>(function FormField({
|
|
|
530
574
|
|
|
531
575
|
return (
|
|
532
576
|
<View
|
|
577
|
+
ref={rootRef}
|
|
533
578
|
style={[wrapperStyle, style]}
|
|
534
579
|
pointerEvents={isDisabled ? 'none' : 'auto'}
|
|
535
580
|
testID={testID}
|
|
@@ -552,7 +597,7 @@ const FormField = forwardRef<RNTextInput, FormFieldProps>(function FormField({
|
|
|
552
597
|
</View>
|
|
553
598
|
)}
|
|
554
599
|
<RNTextInput
|
|
555
|
-
ref={
|
|
600
|
+
ref={mergedInputRef}
|
|
556
601
|
style={[inputTextStyles, inputTextStyle]}
|
|
557
602
|
value={value ?? ''}
|
|
558
603
|
onChangeText={handleChangeText}
|
|
@@ -91,7 +91,7 @@ const toFontWeight = (value: unknown, fallback: TextStyle['fontWeight']) => {
|
|
|
91
91
|
|
|
92
92
|
const getStrokeColor = (style: StyleProp<ViewStyle>, fallback: string) => {
|
|
93
93
|
const flattened = StyleSheet.flatten(style)
|
|
94
|
-
return typeof flattened.backgroundColor === 'string'
|
|
94
|
+
return flattened && typeof flattened.backgroundColor === 'string'
|
|
95
95
|
? flattened.backgroundColor
|
|
96
96
|
: fallback
|
|
97
97
|
}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from 'react-native'
|
|
11
11
|
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
12
12
|
import Radio from '../Radio/Radio'
|
|
13
|
-
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
13
|
+
import { EMPTY_MODES, resolveTruncation } from '../../utils/react-utils'
|
|
14
14
|
import type { Modes } from '../../design-tokens'
|
|
15
15
|
|
|
16
16
|
export interface HoldingsCardDetailItem {
|
|
@@ -39,6 +39,12 @@ export interface HoldingsCardProps {
|
|
|
39
39
|
style?: StyleProp<ViewStyle>
|
|
40
40
|
/** Test ID for testing. */
|
|
41
41
|
testID?: string
|
|
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
|
const GRID_COLUMNS = 3
|
|
@@ -62,6 +68,7 @@ export default function HoldingsCard({
|
|
|
62
68
|
modes = EMPTY_MODES,
|
|
63
69
|
style,
|
|
64
70
|
testID,
|
|
71
|
+
disableTruncation,
|
|
65
72
|
}: HoldingsCardProps) {
|
|
66
73
|
// ---- Container tokens ----
|
|
67
74
|
const containerFill = getVariableByName('holdingsCard/container/fill', modes) || '#fef4e5'
|
|
@@ -268,7 +275,7 @@ export default function HoldingsCard({
|
|
|
268
275
|
lineHeight: detailValueLineHeight,
|
|
269
276
|
fontWeight: detailValueFontWeight as any,
|
|
270
277
|
}}
|
|
271
|
-
|
|
278
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
272
279
|
>
|
|
273
280
|
{item.value}
|
|
274
281
|
</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, cloneChildrenWithModes } from '../../utils/react-utils'
|
|
11
|
+
import { EMPTY_MODES, cloneChildrenWithModes, resolveTruncation } from '../../utils/react-utils'
|
|
12
12
|
import MediaSource, { type UnifiedSource } from '../../utils/MediaSource'
|
|
13
13
|
import type { Modes } from '../../design-tokens'
|
|
14
14
|
|
|
@@ -43,6 +43,12 @@ export type InstitutionBadgeProps = InstitutionBadgeBaseProps & {
|
|
|
43
43
|
labelStyle?: StyleProp<TextStyle>
|
|
44
44
|
/** Accessibility label. Defaults to `label`. */
|
|
45
45
|
accessibilityLabel?: string
|
|
46
|
+
/**
|
|
47
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
48
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
49
|
+
* lines as it needs even when horizontal space is tight.
|
|
50
|
+
*/
|
|
51
|
+
disableTruncation?: boolean
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
interface InstitutionBadgeTokens {
|
|
@@ -155,6 +161,7 @@ function InstitutionBadge({
|
|
|
155
161
|
style,
|
|
156
162
|
labelStyle,
|
|
157
163
|
accessibilityLabel,
|
|
164
|
+
disableTruncation,
|
|
158
165
|
...rest
|
|
159
166
|
}: InstitutionBadgeProps) {
|
|
160
167
|
const { modes: globalModes } = useTokens()
|
|
@@ -207,7 +214,7 @@ function InstitutionBadge({
|
|
|
207
214
|
/>
|
|
208
215
|
</View>
|
|
209
216
|
)}
|
|
210
|
-
<Text style={[tokens.labelStyle, labelStyle]}
|
|
217
|
+
<Text style={[tokens.labelStyle, labelStyle]} {...resolveTruncation(disableTruncation, 1)}>
|
|
211
218
|
{label}
|
|
212
219
|
</Text>
|
|
213
220
|
</View>
|
|
@@ -6,7 +6,7 @@ import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
|
6
6
|
* Helper function to recursively clone children and pass modes prop to components that accept it.
|
|
7
7
|
* This ensures that all child components in slots receive the modes prop from the parent.
|
|
8
8
|
*/
|
|
9
|
-
import { EMPTY_MODES, cloneChildrenWithModes, flattenChildren } from '../../utils/react-utils'
|
|
9
|
+
import { EMPTY_MODES, cloneChildrenWithModes, flattenChildren, resolveTruncation } from '../../utils/react-utils'
|
|
10
10
|
import type { Modes } from '../../design-tokens'
|
|
11
11
|
|
|
12
12
|
type ListGroupProps = {
|
|
@@ -17,6 +17,12 @@ type ListGroupProps = {
|
|
|
17
17
|
style?: StyleProp<ViewStyle>;
|
|
18
18
|
accessibilityLabel?: string;
|
|
19
19
|
accessibilityHint?: string;
|
|
20
|
+
/**
|
|
21
|
+
* When `true`, disables text truncation: the trailing ellipsis (`…`) is never
|
|
22
|
+
* shown and any `numberOfLines` clamp is ignored, so the text wraps to as many
|
|
23
|
+
* lines as it needs even when horizontal space is tight.
|
|
24
|
+
*/
|
|
25
|
+
disableTruncation?: boolean;
|
|
20
26
|
} & Omit<React.ComponentProps<typeof View>, 'children'>;
|
|
21
27
|
|
|
22
28
|
/**
|
|
@@ -52,6 +58,7 @@ function ListGroup({
|
|
|
52
58
|
style,
|
|
53
59
|
accessibilityLabel,
|
|
54
60
|
accessibilityHint,
|
|
61
|
+
disableTruncation,
|
|
55
62
|
...rest
|
|
56
63
|
}: ListGroupProps) {
|
|
57
64
|
// Resolve container tokens
|
|
@@ -113,7 +120,7 @@ function ListGroup({
|
|
|
113
120
|
{label ? (
|
|
114
121
|
<Text
|
|
115
122
|
style={[labelStyle, processedSlot && { marginBottom: gap }]}
|
|
116
|
-
|
|
123
|
+
{...resolveTruncation(disableTruncation, 1)}
|
|
117
124
|
accessibilityElementsHidden={true}
|
|
118
125
|
importantForAccessibility="no"
|
|
119
126
|
>
|