@onekeyfe/react-native-native-list 6.7.0-alpha.401 → 6.7.0-alpha.403
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/android/src/main/java/com/onekey/nativelist/NativeListIdentityRenderer.kt +82 -3
- package/android/src/main/java/com/onekey/nativelist/NativeListPrimitives.kt +6 -3
- package/android/src/main/java/com/onekey/nativelist/NativeListTitleSegmentLayout.kt +38 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListTitleSegmentsView.kt +105 -0
- package/android/src/test/java/com/margelo/nitro/nativelist/NativeListTitleSegmentLayoutTest.kt +65 -0
- package/docs/ROW_TEMPLATES.md +8 -1
- package/docs/SPEC.md +84 -0
- package/ios/NativeListIdentityRenderer.swift +86 -6
- package/ios/NativeListTitleSegmentLayout.swift +32 -0
- package/ios/NativeListTitleSegmentsLabel.swift +80 -0
- package/lib/module/models.js +2 -0
- package/lib/module/validation.js +70 -4
- package/lib/module/web/NativeListWebEngine.js +1 -1
- package/lib/module/web/templates/IdentityRowRenderer.js +91 -0
- package/lib/typescript/src/models.d.ts +21 -1
- package/package.json +3 -3
- package/src/models.ts +23 -0
- package/src/validation.ts +120 -1
- package/src/web/NativeListWebEngine.ts +1 -1
- package/src/web/templates/IdentityRowRenderer.ts +138 -0
|
@@ -845,7 +845,7 @@ export const WEB_LIST_CSS = `
|
|
|
845
845
|
.ok-native-list-trailing-button{appearance:none;box-sizing:border-box;flex:0 0 auto;padding:4px 10px;border:1px solid transparent;border-radius:9999px;background:var(--nl-button-bg,var(--nl-strong));color:var(--nl-button-text,var(--nl-primary));font:500 14px/20px var(--nl-font-medium);white-space:nowrap;cursor:pointer}.ok-native-list-trailing-button:hover:not(:disabled){background:var(--nl-button-hover,var(--nl-strong))}.ok-native-list-trailing-button:active:not(:disabled){background:var(--nl-button-pressed,var(--nl-pressed))}.ok-native-list-trailing-button:focus-visible{outline:2px solid var(--nl-button-focus,var(--nl-accent))}.ok-native-list-trailing-button:disabled{opacity:.4;cursor:default}
|
|
846
846
|
.ok-native-list-icon-button.ok-native-list-tertiary-icon{box-sizing:border-box;flex:0 0 38px;width:38px;height:38px;margin:-7px;padding:6px;border:1px solid transparent;border-radius:9999px;color:var(--nl-icon-subdued);background:transparent}.ok-native-list-icon-button.ok-native-list-tertiary-icon:hover:not(:disabled){background:var(--nl-hover)}.ok-native-list-icon-button.ok-native-list-tertiary-icon:active:not(:disabled){background:var(--nl-pressed)}.ok-native-list-icon-button.ok-native-list-tertiary-icon:disabled{opacity:.4;cursor:default}
|
|
847
847
|
.ok-native-list-icon-button.ok-native-list-tertiary-icon:focus-visible:not(:disabled){outline:2px solid var(--nl-accent)}
|
|
848
|
-
.ok-native-list-identity-title-icon{flex:0 0 20px;width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;color:var(--nl-icon);font-size:20px}.ok-native-list-identity-title-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
848
|
+
.ok-native-list-identity-title-icon{flex:0 0 20px;width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;color:var(--nl-icon);font-size:20px}.ok-native-list-identity-title-leading-icon{flex:0 0 16px;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;color:var(--nl-icon-subdued);font-size:16px}.ok-native-list-identity-title-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
849
849
|
.ok-native-list-account-row .ok-native-list-visual,.ok-native-list-account-action-row .ok-native-list-visual{width:32px;height:32px;flex-basis:32px}.ok-native-list-account-row .ok-native-list-visual>img,.ok-native-list-account-row .ok-native-list-visual-main,.ok-native-list-account-action-row .ok-native-list-visual>img,.ok-native-list-account-action-row .ok-native-list-visual-main{width:32px;height:32px}.ok-native-list-account-row .ok-native-list-visual>.ok-native-list-visual-corner{width:20px;height:20px;padding:2px}.ok-native-list-account-action-row .ok-native-list-visual{border-radius:8px!important}.ok-native-list-wallet-row .ok-native-list-title{color:var(--nl-secondary);font-size:12px;line-height:16px;font-weight:400;font-family:var(--nl-font-regular)}.ok-native-list-item[data-native-list-selected="true"]>.ok-native-list-wallet-row .ok-native-list-title{color:var(--nl-primary)}.ok-native-list-account-row .ok-native-list-title{font-size:16px;line-height:20px;font-weight:400;font-family:var(--nl-font-regular)}.ok-native-list-account-row .ok-native-list-secondary{font-size:14px;line-height:20px;font-weight:400;font-family:var(--nl-font-regular)}
|
|
850
850
|
.ok-native-list-flex{display:flex;flex:1;min-width:0;flex-direction:column;justify-content:center}.ok-native-list-title{font-size:15px;line-height:20px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:var(--nl-font-semibold)}.ok-native-list-secondary{font-size:13px;line-height:18px;color:var(--nl-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ok-native-list-tertiary{color:var(--nl-secondary)}.ok-native-list-info{color:var(--nl-info)}
|
|
851
851
|
.ok-native-list-identity-row .ok-native-list-title,.ok-native-list-identity-row .ok-native-list-amounts>span:first-child{font-size:16px;line-height:20px}.ok-native-list-identity-row .ok-native-list-secondary{font-size:14px;line-height:20px}
|
|
@@ -30,6 +30,79 @@ function toneColor(
|
|
|
30
30
|
if (tone === 'secondary') return 'var(--nl-secondary)';
|
|
31
31
|
return fallback === 'secondary' ? 'var(--nl-secondary)' : 'var(--nl-primary)';
|
|
32
32
|
}
|
|
33
|
+
// Hidden from sight, still read: the runs themselves are hidden from
|
|
34
|
+
// assistive technology in favor of `title`.
|
|
35
|
+
const VISUALLY_HIDDEN: Partial<CSSStyleDeclaration> = {
|
|
36
|
+
position: 'absolute',
|
|
37
|
+
width: '1px',
|
|
38
|
+
height: '1px',
|
|
39
|
+
overflow: 'hidden',
|
|
40
|
+
clip: 'rect(0 0 0 0)',
|
|
41
|
+
whiteSpace: 'nowrap',
|
|
42
|
+
};
|
|
43
|
+
function appendTitleRuns(
|
|
44
|
+
document: Document,
|
|
45
|
+
target: HTMLElement,
|
|
46
|
+
row: IdentityRow
|
|
47
|
+
): void {
|
|
48
|
+
const runs = createElement(
|
|
49
|
+
document,
|
|
50
|
+
'span',
|
|
51
|
+
'ok-native-list-identity-title-runs'
|
|
52
|
+
);
|
|
53
|
+
runs.setAttribute('aria-hidden', 'true');
|
|
54
|
+
Object.assign(runs.style, {
|
|
55
|
+
display: 'flex',
|
|
56
|
+
flex: '1 1 auto',
|
|
57
|
+
minWidth: '0',
|
|
58
|
+
maxWidth: '100%',
|
|
59
|
+
overflow: 'hidden',
|
|
60
|
+
});
|
|
61
|
+
row.titleSegments?.forEach((segment) => {
|
|
62
|
+
const run = createElement(
|
|
63
|
+
document,
|
|
64
|
+
'span',
|
|
65
|
+
'ok-native-list-identity-title-run',
|
|
66
|
+
segment.text
|
|
67
|
+
);
|
|
68
|
+
// Only the shrinking run gives up width; a cap is a share of the line.
|
|
69
|
+
Object.assign(run.style, {
|
|
70
|
+
flex: segment.shrink ? '0 1 auto' : '0 0 auto',
|
|
71
|
+
minWidth: segment.shrink ? '0' : '',
|
|
72
|
+
maxWidth:
|
|
73
|
+
segment.maxWidthRatio === undefined
|
|
74
|
+
? ''
|
|
75
|
+
: `${segment.maxWidthRatio * 100}%`,
|
|
76
|
+
overflow: 'hidden',
|
|
77
|
+
textOverflow: 'ellipsis',
|
|
78
|
+
whiteSpace: 'pre',
|
|
79
|
+
});
|
|
80
|
+
if (segment.tone)
|
|
81
|
+
run.style.color =
|
|
82
|
+
segment.tone === 'secondary'
|
|
83
|
+
? 'var(--nl-secondary)'
|
|
84
|
+
: 'var(--nl-primary)';
|
|
85
|
+
if (segment.fontWeight === 'medium') {
|
|
86
|
+
run.style.fontWeight = '500';
|
|
87
|
+
run.style.fontFamily = 'var(--nl-font-medium)';
|
|
88
|
+
} else if (segment.fontWeight === 'regular') {
|
|
89
|
+
run.style.fontWeight = '400';
|
|
90
|
+
run.style.fontFamily = 'var(--nl-font-regular)';
|
|
91
|
+
}
|
|
92
|
+
setData(run, 'tone', segment.tone);
|
|
93
|
+
runs.appendChild(run);
|
|
94
|
+
});
|
|
95
|
+
const spoken = createElement(
|
|
96
|
+
document,
|
|
97
|
+
'span',
|
|
98
|
+
'ok-native-list-identity-title-spoken',
|
|
99
|
+
row.title
|
|
100
|
+
);
|
|
101
|
+
Object.assign(spoken.style, VISUALLY_HIDDEN);
|
|
102
|
+
target.replaceChildren(runs, spoken);
|
|
103
|
+
target.style.display = 'flex';
|
|
104
|
+
target.style.minWidth = '0';
|
|
105
|
+
}
|
|
33
106
|
function appendAccessories(
|
|
34
107
|
parent: HTMLElement,
|
|
35
108
|
document: Document,
|
|
@@ -195,6 +268,18 @@ function createIdentityRow(
|
|
|
195
268
|
fragment.appendChild(document.createTextNode(row.title.slice(offset)));
|
|
196
269
|
textTarget.prepend(fragment);
|
|
197
270
|
}
|
|
271
|
+
// The runs replace the plain title, except where `title` itself is
|
|
272
|
+
// highlighted or shown in the wallet sidebar.
|
|
273
|
+
const hasTitleRuns =
|
|
274
|
+
!!row.titleSegments?.length &&
|
|
275
|
+
presentation !== 'walletSidebar' &&
|
|
276
|
+
!row.titleMatch?.length;
|
|
277
|
+
if (hasTitleRuns) {
|
|
278
|
+
const textTarget =
|
|
279
|
+
titleElement.querySelector<HTMLElement>('[data-nl-slot="title"]') ??
|
|
280
|
+
titleElement;
|
|
281
|
+
appendTitleRuns(document, textTarget, row);
|
|
282
|
+
}
|
|
198
283
|
if (row.subtitleSegments?.length) {
|
|
199
284
|
column.querySelector('.ok-native-list-secondary')?.remove();
|
|
200
285
|
const segments = createElement(
|
|
@@ -383,6 +468,58 @@ function createIdentityRow(
|
|
|
383
468
|
badges.style.minWidth = '0';
|
|
384
469
|
}
|
|
385
470
|
}
|
|
471
|
+
if (hasTitleRuns) {
|
|
472
|
+
// The runs fill what the title line leaves, so a ratio is a share of
|
|
473
|
+
// that width and title accessories sit at the line's end.
|
|
474
|
+
const runs = titleElement.querySelector<HTMLElement>(
|
|
475
|
+
'.ok-native-list-identity-title-runs'
|
|
476
|
+
);
|
|
477
|
+
for (
|
|
478
|
+
let node = runs?.parentElement;
|
|
479
|
+
node && node !== titleElement;
|
|
480
|
+
node = node.parentElement
|
|
481
|
+
) {
|
|
482
|
+
node.style.display = 'flex';
|
|
483
|
+
node.style.flex = '1 1 auto';
|
|
484
|
+
node.style.minWidth = '0';
|
|
485
|
+
}
|
|
486
|
+
titleElement.style.display = 'flex';
|
|
487
|
+
titleElement.style.alignItems = 'center';
|
|
488
|
+
}
|
|
489
|
+
if (row.titleLeadingIcon && presentation !== 'walletSidebar') {
|
|
490
|
+
const descriptor = row.titleLeadingIcon;
|
|
491
|
+
if (titleElement.hasAttribute('data-nl-slot')) {
|
|
492
|
+
// Keep the glyph out of the title slot that text styles apply to.
|
|
493
|
+
const titleText = tagSlot(
|
|
494
|
+
createElement(document, 'span', 'ok-native-list-identity-title-text'),
|
|
495
|
+
'title'
|
|
496
|
+
);
|
|
497
|
+
while (titleElement.firstChild)
|
|
498
|
+
titleText.appendChild(titleElement.firstChild);
|
|
499
|
+
if (hasTitleRuns) {
|
|
500
|
+
titleText.style.display = 'flex';
|
|
501
|
+
titleText.style.minWidth = '0';
|
|
502
|
+
}
|
|
503
|
+
titleElement.removeAttribute('data-nl-slot');
|
|
504
|
+
titleElement.appendChild(titleText);
|
|
505
|
+
}
|
|
506
|
+
const icon = primitives.iconAction(
|
|
507
|
+
descriptor.name,
|
|
508
|
+
undefined,
|
|
509
|
+
undefined,
|
|
510
|
+
descriptor.tintColor
|
|
511
|
+
);
|
|
512
|
+
icon.className = 'ok-native-list-identity-title-leading-icon';
|
|
513
|
+
if (descriptor.accessibilityLabel)
|
|
514
|
+
icon.setAttribute('aria-label', descriptor.accessibilityLabel);
|
|
515
|
+
else icon.setAttribute('aria-hidden', 'true');
|
|
516
|
+
titleElement.style.display = 'flex';
|
|
517
|
+
titleElement.style.alignItems = 'center';
|
|
518
|
+
// 6px to the title, whatever gap the title line already has.
|
|
519
|
+
const lineGap = Number.parseFloat(titleElement.style.gap || '0') || 0;
|
|
520
|
+
icon.style.marginInlineEnd = `${Math.max(0, 6 - lineGap)}px`;
|
|
521
|
+
titleElement.prepend(icon);
|
|
522
|
+
}
|
|
386
523
|
if (presentation === 'walletSidebar' && row.badges?.length) {
|
|
387
524
|
const badges = createElement(
|
|
388
525
|
document,
|
|
@@ -395,6 +532,7 @@ function createIdentityRow(
|
|
|
395
532
|
column.appendChild(badges);
|
|
396
533
|
}
|
|
397
534
|
for (const key of ['title', 'subtitle'] as const) {
|
|
535
|
+
if (key === 'title' && hasTitleRuns) continue;
|
|
398
536
|
const lines = row.style?.[key]?.lines ?? row[`${key}Lines`];
|
|
399
537
|
if (lines !== undefined)
|
|
400
538
|
column
|