@onekeyfe/react-native-native-list 6.7.0-alpha.397 → 6.7.0-alpha.399

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.
Files changed (40) hide show
  1. package/android/src/main/java/com/onekey/nativelist/NativeListActivityRenderer.kt +23 -0
  2. package/android/src/main/java/com/onekey/nativelist/NativeListIdentityRenderer.kt +43 -15
  3. package/android/src/main/java/com/onekey/nativelist/NativeListLeadingVisual.kt +88 -19
  4. package/android/src/main/java/com/onekey/nativelist/NativeListModels.kt +94 -1
  5. package/android/src/main/java/com/onekey/nativelist/NativeListPrimitives.kt +29 -0
  6. package/android/src/test/java/com/margelo/nitro/nativelist/NativeListActivityHostClipPolicyTest.kt +29 -0
  7. package/android/src/test/java/com/margelo/nitro/nativelist/NativeListIdentityTrailingAxisTest.kt +36 -0
  8. package/android/src/test/java/com/margelo/nitro/nativelist/NativeListLeadingSlotFrameTest.kt +68 -0
  9. package/docs/ROW_TEMPLATES.md +4 -0
  10. package/docs/SPEC.md +180 -37
  11. package/ios/NativeListDesignAssets.swift +6 -0
  12. package/ios/NativeListIdentityRenderer.swift +76 -4
  13. package/ios/NativeListLeadingVisual.swift +70 -8
  14. package/ios/RNCNativeListView.swift +6 -1
  15. package/ios/Resources/NativeListIcons.xcassets/onekey_document2.imageset/Contents.json +1 -0
  16. package/ios/Resources/NativeListIcons.xcassets/onekey_document2.imageset/icon.svg +1 -0
  17. package/ios/Resources/NativeListIcons.xcassets/onekey_dot_ver_solid.imageset/Contents.json +1 -0
  18. package/ios/Resources/NativeListIcons.xcassets/onekey_dot_ver_solid.imageset/icon.svg +1 -0
  19. package/ios/Resources/NativeListIcons.xcassets/onekey_plus_large.imageset/Contents.json +1 -0
  20. package/ios/Resources/NativeListIcons.xcassets/onekey_plus_large.imageset/icon.svg +1 -0
  21. package/ios/Resources/NativeListIcons.xcassets/onekey_ticket.imageset/Contents.json +1 -0
  22. package/ios/Resources/NativeListIcons.xcassets/onekey_ticket.imageset/icon.svg +1 -0
  23. package/ios/Resources/NativeListIcons.xcassets/onekey_wallet.imageset/Contents.json +1 -0
  24. package/ios/Resources/NativeListIcons.xcassets/onekey_wallet.imageset/icon.svg +1 -0
  25. package/ios/tests/NativeListIdentityTitleIconLayoutTests.swift +81 -0
  26. package/ios/tests/NativeListLeadingVisualPairBackdropTests.swift +50 -0
  27. package/ios/tests/NativeListLifecycleTests.swift +60 -0
  28. package/lib/module/NativeList.web.js +9 -12
  29. package/lib/module/models.js +2 -0
  30. package/lib/module/validation.js +627 -114
  31. package/lib/module/web/NativeListWebEngine.js +49 -9
  32. package/lib/module/web/templates/IdentityRowRenderer.js +58 -4
  33. package/lib/typescript/src/models.d.ts +25 -14
  34. package/lib/typescript/src/validation.d.ts +7 -2
  35. package/package.json +3 -3
  36. package/src/NativeList.web.tsx +10 -14
  37. package/src/models.ts +144 -153
  38. package/src/validation.ts +1617 -167
  39. package/src/web/NativeListWebEngine.ts +62 -10
  40. package/src/web/templates/IdentityRowRenderer.ts +70 -4
@@ -61,10 +61,9 @@ import {
61
61
  type NormalizedPositionScroll,
62
62
  } from '../scrolling';
63
63
  import {
64
- applyRowPatches,
64
+ applyValidatedRowPatches,
65
65
  containNativeListInput,
66
66
  emptyNativeListSnapshot,
67
- validatePatches,
68
67
  validateSnapshot,
69
68
  } from '../validation';
70
69
  import { avatarPrefetchWindow } from '../avatarPrefetch';
@@ -1206,6 +1205,62 @@ const selectorIcons: Readonly<
1206
1205
  },
1207
1206
  ],
1208
1207
  },
1208
+ DotVerSolid: {
1209
+ viewBox: '0 0 24 24',
1210
+ paths: [
1211
+ {
1212
+ d: 'M14 18v4h-4v-4zm0-4h-4v-4h4zm0-8h-4V2h4z',
1213
+ fill: 'currentColor',
1214
+ fillRule: 'nonzero',
1215
+ opacity: 1,
1216
+ },
1217
+ ],
1218
+ },
1219
+ Document2Outline: {
1220
+ viewBox: '0 0 24 24',
1221
+ paths: [
1222
+ {
1223
+ d: 'M12 16H8v-2h4zm4-4H8v-2h8zm0-4H8V6h8z',
1224
+ fill: 'currentColor',
1225
+ fillRule: 'nonzero',
1226
+ opacity: 1,
1227
+ },
1228
+ {
1229
+ d: 'M20 22H4V2h16zM6 20h12V4H6z',
1230
+ fill: 'currentColor',
1231
+ fillRule: 'evenodd',
1232
+ opacity: 1,
1233
+ },
1234
+ ],
1235
+ },
1236
+ WalletOutline: {
1237
+ viewBox: '0 0 24 24',
1238
+ paths: [
1239
+ {
1240
+ d: 'M15.5 13.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5',
1241
+ fill: 'currentColor',
1242
+ fillRule: 'nonzero',
1243
+ opacity: 1,
1244
+ },
1245
+ {
1246
+ d: 'M17 8h4v13H7a4 4 0 0 1-4-4V6.5A3.5 3.5 0 0 1 6.5 3H17zM5 17a2 2 0 0 0 2 2h12v-9H6.5c-.537 0-1.045-.12-1.5-.337zM6.5 5a1.5 1.5 0 1 0 0 3H15V5z',
1247
+ fill: 'currentColor',
1248
+ fillRule: 'evenodd',
1249
+ opacity: 1,
1250
+ },
1251
+ ],
1252
+ },
1253
+ PlusLargeOutline: {
1254
+ viewBox: '0 0 24 24',
1255
+ paths: [
1256
+ {
1257
+ d: 'M13 11h8v2h-8v8h-2v-8H3v-2h8V3h2z',
1258
+ fill: 'currentColor',
1259
+ fillRule: 'nonzero',
1260
+ opacity: 1,
1261
+ },
1262
+ ],
1263
+ },
1209
1264
  TicketOutline: {
1210
1265
  viewBox: '0 0 24 24',
1211
1266
  paths: [
@@ -3143,13 +3198,9 @@ export class NativeListWebEngine {
3143
3198
  }
3144
3199
 
3145
3200
  applyPatches(patches: readonly RowPatch[]) {
3146
- const accepted = containNativeListInput(() => {
3147
- const normalized = validatePatches(patches);
3148
- return {
3149
- patches: normalized,
3150
- snapshot: applyRowPatches(this.snapshot, normalized),
3151
- };
3152
- });
3201
+ const accepted = containNativeListInput(() =>
3202
+ applyValidatedRowPatches(this.snapshot, patches)
3203
+ );
3153
3204
  if (!accepted || accepted.patches.length === 0) return;
3154
3205
  patches = accepted.patches;
3155
3206
  const next = accepted.snapshot;
@@ -3158,7 +3209,8 @@ export class NativeListWebEngine {
3158
3209
  const selected =
3159
3210
  'selected' in patch.changes ? patch.changes.selected : undefined;
3160
3211
  if (selected === true) selection.add(patch.key);
3161
- else if (selected === false) selection.delete(patch.key);
3212
+ else if (selected === false || selected === null)
3213
+ selection.delete(patch.key);
3162
3214
  });
3163
3215
  const tableValuesOnly = patches.every((patch) => {
3164
3216
  const index = this.rows.findIndex((row) => row.key === patch.key);
@@ -226,7 +226,7 @@ function createIdentityRow(
226
226
  });
227
227
  column.insertBefore(segments, titleElement.nextSibling);
228
228
  }
229
- if (row.titleIcon || row.secondaryTitleIcon) {
229
+ if (row.titleIcon || row.secondaryTitleIcon || row.titleImage) {
230
230
  const badgeLine = titleElement.querySelector<HTMLElement>(
231
231
  ':scope > .ok-native-list-badges'
232
232
  );
@@ -258,6 +258,45 @@ function createIdentityRow(
258
258
  else icon.setAttribute('aria-hidden', 'true');
259
259
  return icon;
260
260
  });
261
+ if (row.titleImage) {
262
+ const descriptor = row.titleImage;
263
+ const holder = createElement(
264
+ document,
265
+ 'span',
266
+ 'ok-native-list-identity-title-image'
267
+ );
268
+ Object.assign(holder.style, {
269
+ flex: `0 0 ${descriptor.image.width}px`,
270
+ width: `${descriptor.image.width}px`,
271
+ height: `${descriptor.image.height}px`,
272
+ borderRadius: '50%',
273
+ overflow: 'hidden',
274
+ });
275
+ const image = primitives.thumbnail(descriptor.image);
276
+ if (image) {
277
+ Object.assign(image.style, {
278
+ width: '100%',
279
+ height: '100%',
280
+ borderRadius: 'inherit',
281
+ objectFit:
282
+ descriptor.image.contentFit === 'center'
283
+ ? 'none'
284
+ : descriptor.image.contentFit ?? 'cover',
285
+ });
286
+ image.setAttribute('alt', '');
287
+ holder.appendChild(image);
288
+ }
289
+ if (descriptor.hoverActionKey) {
290
+ setData(holder, 'nativeListHoverAction', descriptor.hoverActionKey);
291
+ setData(holder, 'nativeListIconHelp', true);
292
+ markActionAnchorSource(holder, 'leadingAction');
293
+ }
294
+ if (descriptor.accessibilityLabel) {
295
+ holder.setAttribute('role', 'img');
296
+ holder.setAttribute('aria-label', descriptor.accessibilityLabel);
297
+ } else holder.setAttribute('aria-hidden', 'true');
298
+ icons.push(holder);
299
+ }
261
300
  titleText.after(...icons);
262
301
  titleElement.style.display = 'flex';
263
302
  titleElement.style.alignItems = 'center';
@@ -300,7 +339,9 @@ function createIdentityRow(
300
339
  label.style.flex = '0 1 auto';
301
340
  label.style.minWidth = '0';
302
341
  label.style.marginInlineStart =
303
- row.titleIcon || row.secondaryTitleIcon ? '4px' : '8px';
342
+ row.titleIcon || row.secondaryTitleIcon || row.titleImage
343
+ ? '4px'
344
+ : '8px';
304
345
  label.style.maxWidth =
305
346
  suffix.maxWidth === undefined ? '' : `${suffix.maxWidth}px`;
306
347
  label.style.overflow = 'hidden';
@@ -317,7 +358,12 @@ function createIdentityRow(
317
358
  titleElement.insertBefore(label, badges);
318
359
  });
319
360
  }
320
- if (row.badges?.length && !row.titleIcon && !row.secondaryTitleIcon) {
361
+ if (
362
+ row.badges?.length &&
363
+ !row.titleIcon &&
364
+ !row.secondaryTitleIcon &&
365
+ !row.titleImage
366
+ ) {
321
367
  const titleText = titleElement.querySelector<HTMLElement>(
322
368
  ':scope > [data-nl-slot="title"]'
323
369
  );
@@ -513,6 +559,7 @@ type Views = {
513
559
  node: HTMLElement;
514
560
  defaults: RowVisualStyle;
515
561
  };
562
+ titleImage?: { key: string; node: HTMLElement };
516
563
  primitives: RowPrimitives;
517
564
  };
518
565
  const views = new WeakMap<HTMLElement, Views>();
@@ -520,10 +567,21 @@ function bind(body: HTMLElement, row: IdentityRow, primitives: RowPrimitives) {
520
567
  const v = views.get(body)!;
521
568
  v.primitives = primitives;
522
569
  let used = false;
570
+ let usedTitleImage = false;
523
571
  const next = createIdentityRow(
524
572
  body.ownerDocument,
525
573
  {
526
574
  ...primitives,
575
+ thumbnail: (source) => {
576
+ usedTitleImage = true;
577
+ const key = JSON.stringify([row.key, source]);
578
+ if (v.titleImage?.key !== key) {
579
+ if (v.titleImage) primitives.dispose(v.titleImage.node);
580
+ const node = primitives.thumbnail(source);
581
+ v.titleImage = node ? { key, node } : undefined;
582
+ }
583
+ return v.titleImage?.node;
584
+ },
527
585
  visual: (source, presentation) => {
528
586
  used = true;
529
587
  const key = JSON.stringify([row.key, source, presentation]);
@@ -550,6 +608,10 @@ function bind(body: HTMLElement, row: IdentityRow, primitives: RowPrimitives) {
550
608
  primitives.dispose(v.visual.node);
551
609
  v.visual = undefined;
552
610
  }
611
+ if (!usedTitleImage && v.titleImage) {
612
+ primitives.dispose(v.titleImage.node);
613
+ v.titleImage = undefined;
614
+ }
553
615
  body.replaceChildren(...Array.from(next.childNodes));
554
616
  body.className = next.className;
555
617
  body.style.cssText = next.style.cssText;
@@ -640,7 +702,11 @@ function create(
640
702
  function recycle(body: HTMLElement) {
641
703
  const v = views.get(body);
642
704
  if (v?.visual) v.primitives.dispose(v.visual.node);
643
- if (v) v.visual = undefined;
705
+ if (v?.titleImage) v.primitives.dispose(v.titleImage.node);
706
+ if (v) {
707
+ v.visual = undefined;
708
+ v.titleImage = undefined;
709
+ }
644
710
  body.replaceChildren();
645
711
  }
646
712
  export const identityRowRenderer = {