@onekeyfe/react-native-native-list 3.0.116 → 3.0.117

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.
@@ -1367,6 +1367,8 @@ internal class NativeListRowView(
1367
1367
  leadingActionIcon.iconName = ""
1368
1368
  leadingActionIcon.glyphSizeDp = 24
1369
1369
  leadingActionIcon.setOnClickListener(null)
1370
+ leadingActionIcon.setTag(com.facebook.react.R.id.react_test_id, null)
1371
+ leadingActionIcon.contentDescription = null
1370
1372
  mainColumn.visibility = VISIBLE
1371
1373
  dataContainer.visibility = GONE
1372
1374
  dataColumns.forEach { it.visibility = GONE }
@@ -2106,6 +2108,33 @@ internal class NativeListRowView(
2106
2108
  ?: if (variant == "perp") 8 else 14
2107
2109
  setPadding(dp(horizontalPadding), dp(verticalPadding), dp(horizontalPadding), dp(verticalPadding))
2108
2110
 
2111
+ item.json.optJSONObject("leadingAction")?.let { action ->
2112
+ leadingActionIcon.visibility = VISIBLE
2113
+ leadingActionIcon.iconName = action.optString("name")
2114
+ leadingActionIcon.glyphSizeDp = 24
2115
+ leadingActionIcon.tintColor = safeColor(
2116
+ action.optString("tintColor"),
2117
+ color(theme, "icon", "#0000009B"),
2118
+ )
2119
+ leadingActionIcon.isEnabled = !action.optBoolean("disabled", false)
2120
+ leadingActionIcon.alpha = if (leadingActionIcon.isEnabled) 1f else 0.4f
2121
+ leadingActionIcon.setTag(
2122
+ com.facebook.react.R.id.react_test_id,
2123
+ action.optString("testID").takeIf(String::isNotEmpty),
2124
+ )
2125
+ leadingActionIcon.contentDescription = action.optString("accessibilityLabel")
2126
+ leadingActionIcon.setOnClickListener {
2127
+ emitAction(
2128
+ item,
2129
+ action.optString("actionKey"),
2130
+ null,
2131
+ leadingActionIcon,
2132
+ "leadingAction",
2133
+ )
2134
+ }
2135
+ addView(leadingActionIcon, LayoutParams(dp(36), dp(36)).apply { marginEnd = dp(5) })
2136
+ }
2137
+
2109
2138
  val leading = JSONObject(item.json.getJSONObject("leading").toString())
2110
2139
  imageStyle?.optString("shape")?.takeIf(String::isNotEmpty)?.let { leading.put("shape", it) }
2111
2140
  imageStyle?.optString("contentFit")?.takeIf(String::isNotEmpty)?.let { contentFit ->
@@ -1276,6 +1276,8 @@ final class NativeListCell: UICollectionViewCell {
1276
1276
  leadingActionButton.isHidden = true
1277
1277
  leadingActionButton.setImage(nil, for: .normal)
1278
1278
  leadingActionButton.setImage(nil, for: .disabled)
1279
+ leadingActionButton.accessibilityIdentifier = nil
1280
+ leadingActionButton.accessibilityLabel = nil
1279
1281
  unreadDot.isHidden = true
1280
1282
  mediaBadgeLabel.isHidden = true
1281
1283
  mediaBadgeLabel.text = nil
@@ -2312,6 +2314,28 @@ final class NativeListCell: UICollectionViewCell {
2312
2314
  rootTopConstraint.constant = verticalPadding
2313
2315
  rootBottomConstraint.constant = -verticalPadding
2314
2316
  rootStack.spacing = CGFloat(style?.double("leadingGap", default: variant == "perp" ? 8 : 14) ?? (variant == "perp" ? 8 : 14))
2317
+ if let leadingAction = item.data.dictionary("leadingAction") {
2318
+ leadingActionButton.isHidden = false
2319
+ let tintColor = UIColor(
2320
+ nativeListHex: leadingAction.string("tintColor", default: "#646464"),
2321
+ fallback: .darkGray
2322
+ )
2323
+ leadingActionButton.tintColor = tintColor
2324
+ if let image = nativeListIcon(named: leadingAction.string("name")) {
2325
+ leadingActionButton.setImage(image, for: .normal)
2326
+ leadingActionButton.setImage(
2327
+ image.withTintColor(tintColor, renderingMode: .alwaysOriginal),
2328
+ for: .disabled
2329
+ )
2330
+ }
2331
+ leadingActionButton.isEnabled = !leadingAction.bool("disabled")
2332
+ leadingActionButton.alpha = leadingActionButton.isEnabled ? 1 : 0.4
2333
+ leadingActionButton.accessibilityIdentifier = leadingAction["testID"] as? String
2334
+ leadingActionButton.accessibilityLabel = leadingAction["accessibilityLabel"] as? String
2335
+ leadingActionKey = leadingAction.string("actionKey")
2336
+ rootStack.addArrangedSubview(leadingActionButton)
2337
+ rootStack.setCustomSpacing(5, after: leadingActionButton)
2338
+ }
2315
2339
  leadingWidth.constant = imageWidth
2316
2340
  leadingHeight.constant = imageHeight
2317
2341
  if let visual = marketLeading(item, style: style) {
@@ -124,6 +124,13 @@ function assertMarketRow(row, path) {
124
124
  }
125
125
  assertText(row.price, `${path}.price`);
126
126
  assertText(row.change.text, `${path}.change.text`);
127
+ assertTrailingAccessories(row.leadingAction ? [row.leadingAction] : undefined, `${path}.leadingAction`);
128
+ if (row.leadingAction) {
129
+ assertText(row.leadingAction.name, `${path}.leadingAction.name`);
130
+ if (row.leadingAction.actionKey !== undefined) {
131
+ assertKey(row.leadingAction.actionKey, `${path}.leadingAction.actionKey`);
132
+ }
133
+ }
127
134
  assertLeadingVisual(row.leading, `${path}.leading`);
128
135
  const assertSegments = (segments, segmentPath) => {
129
136
  segments?.forEach((segment, index) => {
@@ -1747,6 +1747,17 @@ function createMarketRow(context, row) {
1747
1747
  const layoutStyle = resolveWebMarketLayoutStyle(row);
1748
1748
  body.style.padding = String(layoutStyle.verticalPadding) + 'px ' + String(layoutStyle.horizontalPadding) + 'px';
1749
1749
  body.style.gap = '0px';
1750
+ if (row.leadingAction) {
1751
+ const action = createIconAction(context, row.leadingAction.name, row.leadingAction.actionKey, row.leadingAction.disabled, row.leadingAction.tintColor);
1752
+ action.style.flex = '0 0 36px';
1753
+ action.style.width = '36px';
1754
+ action.style.height = '36px';
1755
+ action.style.marginRight = '5px';
1756
+ setData(action, 'testid', row.leadingAction.testID);
1757
+ if (row.leadingAction.accessibilityLabel) action.setAttribute('aria-label', row.leadingAction.accessibilityLabel);
1758
+ markActionAnchorSource(action, 'leadingAction');
1759
+ body.appendChild(action);
1760
+ }
1750
1761
  const visual = createVisual(context, row.leading);
1751
1762
  if (visual) {
1752
1763
  const width = layoutStyle.imageWidth;
@@ -329,6 +329,9 @@ export type DataRow = RowBase & Readonly<{
329
329
  export type MarketRow = RowBase & Readonly<{
330
330
  type: 'market';
331
331
  variant: 'token' | 'stock' | 'perp';
332
+ leadingAction?: Extract<TrailingAccessory, {
333
+ kind: 'icon';
334
+ }>;
332
335
  leading: LeadingVisual;
333
336
  title: string;
334
337
  subtitle?: string;
@@ -545,7 +548,7 @@ export type RowPatch = Readonly<{
545
548
  }> | Readonly<{
546
549
  type: 'market';
547
550
  key: string;
548
- changes: Partial<Pick<MarketRow, CommonPatchFields | 'leading' | 'title' | 'subtitle' | 'subtitleSegments' | 'price' | 'priceSegments' | 'change' | 'badges' | 'pressActionKey' | 'pressInActionKey' | 'longPressActionKey' | 'diagnostics' | 'style'>>;
551
+ changes: Partial<Pick<MarketRow, CommonPatchFields | 'leadingAction' | 'leading' | 'title' | 'subtitle' | 'subtitleSegments' | 'price' | 'priceSegments' | 'change' | 'badges' | 'pressActionKey' | 'pressInActionKey' | 'longPressActionKey' | 'diagnostics' | 'style'>>;
549
552
  }> | Readonly<{
550
553
  type: 'mediaTile';
551
554
  key: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-native-list",
3
- "version": "3.0.116",
3
+ "version": "3.0.117",
4
4
  "description": "Template-driven native RecyclerView and UICollectionView for React Native",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/module/index.js",
@@ -83,8 +83,8 @@
83
83
  "typescript": "^5.9.2"
84
84
  },
85
85
  "peerDependencies": {
86
- "@onekeyfe/react-native-image": "3.0.116",
87
- "@onekeyfe/react-native-native-logger": "3.0.116",
86
+ "@onekeyfe/react-native-image": "3.0.117",
87
+ "@onekeyfe/react-native-native-logger": "3.0.117",
88
88
  "react": "*",
89
89
  "react-native": "*",
90
90
  "react-native-nitro-modules": "0.37.0"
package/src/models.ts CHANGED
@@ -346,6 +346,7 @@ export type MarketRow = RowBase &
346
346
  Readonly<{
347
347
  type: 'market';
348
348
  variant: 'token' | 'stock' | 'perp';
349
+ leadingAction?: Extract<TrailingAccessory, { kind: 'icon' }>;
349
350
  leading: LeadingVisual;
350
351
  title: string;
351
352
  subtitle?: string;
@@ -667,6 +668,7 @@ export type RowPatch =
667
668
  Pick<
668
669
  MarketRow,
669
670
  | CommonPatchFields
671
+ | 'leadingAction'
670
672
  | 'leading'
671
673
  | 'title'
672
674
  | 'subtitle'
package/src/validation.ts CHANGED
@@ -242,6 +242,16 @@ function assertMarketRow(row: MarketRow, path: string): void {
242
242
  }
243
243
  assertText(row.price, `${path}.price`);
244
244
  assertText(row.change.text, `${path}.change.text`);
245
+ assertTrailingAccessories(
246
+ row.leadingAction ? [row.leadingAction] : undefined,
247
+ `${path}.leadingAction`
248
+ );
249
+ if (row.leadingAction) {
250
+ assertText(row.leadingAction.name, `${path}.leadingAction.name`);
251
+ if (row.leadingAction.actionKey !== undefined) {
252
+ assertKey(row.leadingAction.actionKey, `${path}.leadingAction.actionKey`);
253
+ }
254
+ }
245
255
  assertLeadingVisual(row.leading, `${path}.leading`);
246
256
  const assertSegments = (
247
257
  segments: MarketRow['priceSegments'],
@@ -3123,6 +3123,24 @@ function createMarketRow(context: RenderContext, row: MarketRow): HTMLElement {
3123
3123
  String(layoutStyle.horizontalPadding) +
3124
3124
  'px';
3125
3125
  body.style.gap = '0px';
3126
+ if (row.leadingAction) {
3127
+ const action = createIconAction(
3128
+ context,
3129
+ row.leadingAction.name,
3130
+ row.leadingAction.actionKey,
3131
+ row.leadingAction.disabled,
3132
+ row.leadingAction.tintColor
3133
+ );
3134
+ action.style.flex = '0 0 36px';
3135
+ action.style.width = '36px';
3136
+ action.style.height = '36px';
3137
+ action.style.marginRight = '5px';
3138
+ setData(action, 'testid', row.leadingAction.testID);
3139
+ if (row.leadingAction.accessibilityLabel)
3140
+ action.setAttribute('aria-label', row.leadingAction.accessibilityLabel);
3141
+ markActionAnchorSource(action, 'leadingAction');
3142
+ body.appendChild(action);
3143
+ }
3126
3144
  const visual = createVisual(context, row.leading);
3127
3145
  if (visual) {
3128
3146
  const width = layoutStyle.imageWidth;