@onekeyfe/react-native-native-list 3.0.114 → 3.0.115

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.
@@ -10,6 +10,7 @@ const MAX_IMAGE_HEADERS = 32;
10
10
  const MAX_HEADER_LENGTH = 4096;
11
11
  const MAX_SPACER_HEIGHT = 512;
12
12
  const MAX_SECTION_INDEX_TITLE_LENGTH = 8;
13
+ const MAX_MARKET_BADGES = 3;
13
14
  function fail(path, message) {
14
15
  throw new Error(`NativeList ${path}: ${message}`);
15
16
  }
@@ -62,6 +63,105 @@ function assertTextTone(tone, path) {
62
63
  fail(path, 'must be primary, secondary, positive, or negative');
63
64
  }
64
65
  }
66
+ function assertBoundedStyleNumber(value, path, min, max) {
67
+ if (value !== undefined && (!Number.isFinite(value) || value < min || value > max)) {
68
+ fail(path, `must be within ${min}...${max}`);
69
+ }
70
+ }
71
+ function assertMarketTextStyle(style, path) {
72
+ if (!style) return;
73
+ assertBoundedStyleNumber(style.fontSize, `${path}.fontSize`, 8, 48);
74
+ assertBoundedStyleNumber(style.lineHeight, `${path}.lineHeight`, 8, 64);
75
+ if (style.fontWeight !== undefined && !['regular', 'medium', 'semibold', 'bold'].includes(style.fontWeight)) {
76
+ fail(`${path}.fontWeight`, 'must be regular, medium, semibold, or bold');
77
+ }
78
+ if (style.alignment !== undefined && !['start', 'center', 'end'].includes(style.alignment)) {
79
+ fail(`${path}.alignment`, 'must be start, center, or end');
80
+ }
81
+ if (style.lines !== undefined && ![1, 2].includes(style.lines)) {
82
+ fail(`${path}.lines`, 'must be 1 or 2');
83
+ }
84
+ }
85
+ function assertMarketStyle(style, path) {
86
+ if (!style) return;
87
+ for (const field of ['horizontalPadding', 'verticalPadding', 'leadingGap', 'titleBadgeGap', 'trailingGap']) {
88
+ assertBoundedStyleNumber(style[field], `${path}.${field}`, 0, 64);
89
+ }
90
+ assertBoundedStyleNumber(style.lineGap, `${path}.lineGap`, 0, 16);
91
+ assertBoundedStyleNumber(style.changeWidth, `${path}.changeWidth`, 1, 160);
92
+ assertBoundedStyleNumber(style.changeHeight, `${path}.changeHeight`, 1, 160);
93
+ assertBoundedStyleNumber(style.changeCornerRadius, `${path}.changeCornerRadius`, 0, 80);
94
+ if (style.image) {
95
+ assertBoundedStyleNumber(style.image.width, `${path}.image.width`, 1, 160);
96
+ assertBoundedStyleNumber(style.image.height, `${path}.image.height`, 1, 160);
97
+ assertBoundedStyleNumber(style.image.cornerRadius, `${path}.image.cornerRadius`, 0, 80);
98
+ assertVisualShape(style.image.shape, `${path}.image.shape`);
99
+ if (style.image.contentFit !== undefined && !['cover', 'contain', 'fill', 'center'].includes(style.image.contentFit)) {
100
+ fail(`${path}.image.contentFit`, 'must be cover, contain, fill, or center');
101
+ }
102
+ }
103
+ assertMarketTextStyle(style.title, `${path}.title`);
104
+ assertMarketTextStyle(style.subtitle, `${path}.subtitle`);
105
+ assertMarketTextStyle(style.price, `${path}.price`);
106
+ assertMarketTextStyle(style.change, `${path}.change`);
107
+ }
108
+ function assertMarketRow(row, path) {
109
+ if (!['token', 'stock', 'perp'].includes(row.variant)) {
110
+ fail(`${path}.variant`, 'must be token, stock, or perp');
111
+ }
112
+ assertText(row.title, `${path}.title`);
113
+ assertText(row.subtitle, `${path}.subtitle`);
114
+ assertText(row.price, `${path}.price`);
115
+ assertText(row.change.text, `${path}.change.text`);
116
+ assertLeadingVisual(row.leading, `${path}.leading`);
117
+ const assertSegments = (segments, segmentPath) => {
118
+ segments?.forEach((segment, index) => {
119
+ assertText(segment.text, `${segmentPath}[${index}].text`);
120
+ if (segment.style !== undefined && segment.style !== 'subscript') {
121
+ fail(`${segmentPath}[${index}].style`, 'must be subscript when provided');
122
+ }
123
+ });
124
+ };
125
+ assertSegments(row.subtitleSegments, `${path}.subtitleSegments`);
126
+ assertSegments(row.priceSegments, `${path}.priceSegments`);
127
+ assertSegments(row.change.textSegments, `${path}.change.textSegments`);
128
+ if (!['positive', 'negative', 'neutral'].includes(row.change.tone)) {
129
+ fail(`${path}.change.tone`, 'must be positive, negative, or neutral');
130
+ }
131
+ if ((row.badges?.length ?? 0) > MAX_MARKET_BADGES) {
132
+ fail(`${path}.badges`, `supports at most ${MAX_MARKET_BADGES} badges`);
133
+ }
134
+ const badgeKeys = new Set();
135
+ row.badges?.forEach((badge, index) => {
136
+ const badgePath = `${path}.badges[${index}]`;
137
+ assertKey(badge.key, `${badgePath}.key`);
138
+ if (badgeKeys.has(badge.key)) {
139
+ fail(`${path}.badges`, `duplicate badge key "${badge.key}"`);
140
+ }
141
+ badgeKeys.add(badge.key);
142
+ assertText(badge.text, `${badgePath}.text`);
143
+ if (badge.iconName !== undefined && badge.iconName !== 'verified') {
144
+ fail(`${badgePath}.iconName`, 'must be verified when provided');
145
+ }
146
+ if (badge.iconName !== undefined && badge.icon !== undefined) {
147
+ fail(`${badgePath}.icon`, 'cannot be combined with iconName');
148
+ }
149
+ assertImage(badge.icon, `${badgePath}.icon`);
150
+ if (badge.tone !== undefined && !['neutral', 'info', 'success', 'warning', 'danger'].includes(badge.tone)) {
151
+ fail(`${badgePath}.tone`, 'must be neutral, info, success, warning, or danger');
152
+ }
153
+ if (!badge.text && !badge.icon && !badge.iconName) {
154
+ fail(badgePath, 'requires text, icon, or iconName');
155
+ }
156
+ if (badge.actionKey !== undefined) {
157
+ assertKey(badge.actionKey, `${badgePath}.actionKey`);
158
+ }
159
+ });
160
+ for (const [key, value] of [['pressActionKey', row.pressActionKey], ['pressInActionKey', row.pressInActionKey], ['longPressActionKey', row.longPressActionKey], ['diagnostics.imageBindActionKey', row.diagnostics?.imageBindActionKey]]) {
161
+ if (value !== undefined) assertKey(value, `${path}.${key}`);
162
+ }
163
+ assertMarketStyle(row.style, `${path}.style`);
164
+ }
65
165
  function assertSectionHeaderVariant(variant, path) {
66
166
  if (variant !== undefined && !['summary', 'gallery', 'history'].includes(variant)) {
67
167
  fail(path, 'must be summary, gallery, or history when provided');
@@ -150,7 +250,7 @@ function assertLeadingVisual(visual, path) {
150
250
  }
151
251
  }
152
252
  function assertVisual(row, path) {
153
- const visuals = row.type === 'identity' ? [row.leading] : row.type === 'rail' ? [row.visual] : row.type === 'activity' ? [row.leading, row.secondaryLeading] : row.type === 'message' ? [row.leading] : row.type === 'dataRow' ? [row.leading] : row.type === 'metricCard' ? [row.visual] : [];
253
+ const visuals = row.type === 'identity' ? [row.leading] : row.type === 'rail' ? [row.visual] : row.type === 'activity' ? [row.leading, row.secondaryLeading] : row.type === 'message' ? [row.leading] : row.type === 'dataRow' ? [row.leading] : row.type === 'market' ? [row.leading] : row.type === 'metricCard' ? [row.visual] : [];
154
254
  visuals.forEach((visual, index) => {
155
255
  assertLeadingVisual(visual, `${path}.visual[${index}]`);
156
256
  });
@@ -262,6 +362,9 @@ function assertRow(row, index, path = `rows[${index}]`) {
262
362
  fail(`${path}.badges`, `supports at most ${MAX_BADGES} badges`);
263
363
  }
264
364
  break;
365
+ case 'market':
366
+ assertMarketRow(row, path);
367
+ break;
265
368
  case 'mediaTile':
266
369
  assertImage(row.image, `${path}.image`);
267
370
  if (row.imageState !== undefined && !['empty', 'error'].includes(row.imageState)) {
@@ -327,12 +430,19 @@ function assertRow(row, index, path = `rows[${index}]`) {
327
430
  assertTrailingAccessories(row.trailing, `${path}.trailing`);
328
431
  break;
329
432
  case 'system':
433
+ const presentation = 'presentation' in row ? row.presentation : undefined;
434
+ if (presentation !== undefined && presentation !== 'market') {
435
+ fail(`${path}.presentation`, 'must be market when provided');
436
+ }
330
437
  if (
331
438
  // OneKey patch: deprecated-wallet warnings retain the original scrolling semantics.
332
439
  !['loading', 'retry', 'noMatch', 'end', 'spacer', 'warning'].includes(row.variant)) {
333
440
  fail(`${path}.variant`, 'must be loading, retry, noMatch, end, spacer, or warning');
334
441
  }
335
442
  if (row.variant === 'warning') assertText(row.title, `${path}.title`);
443
+ if (row.variant === 'loading' && row.loadingStyle !== undefined && row.loadingStyle !== 'skeleton' && row.loadingStyle !== 'spinner') {
444
+ fail(`${path}.loadingStyle`, 'must be skeleton or spinner when provided');
445
+ }
336
446
  if (row.variant !== 'spacer') {
337
447
  assertText(row.message, `${path}.message`);
338
448
  }
@@ -503,6 +613,24 @@ function assertPatchChanges(patch, index) {
503
613
  fail(`${path}.badges`, `supports at most ${MAX_BADGES} badges`);
504
614
  }
505
615
  break;
616
+ case 'market':
617
+ assertMarketRow({
618
+ type: 'market',
619
+ key: patch.key,
620
+ variant: 'token',
621
+ leading: {
622
+ kind: 'icon',
623
+ name: 'placeholder'
624
+ },
625
+ title: '',
626
+ price: '',
627
+ change: {
628
+ text: '',
629
+ tone: 'neutral'
630
+ },
631
+ ...patch.changes
632
+ }, path);
633
+ break;
506
634
  case 'mediaTile':
507
635
  assertImage(patch.changes.image, `${path}.image`);
508
636
  if (patch.changes.imageState !== undefined && !['empty', 'error'].includes(patch.changes.imageState)) {