@onekeyfe/react-native-native-list 6.7.0-alpha.426 → 6.7.0-alpha.428
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(
|
|
@@ -391,6 +476,58 @@ function createIdentityRow(
|
|
|
391
476
|
badges.style.minWidth = '0';
|
|
392
477
|
}
|
|
393
478
|
}
|
|
479
|
+
if (hasTitleRuns) {
|
|
480
|
+
// The runs fill what the title line leaves, so a ratio is a share of
|
|
481
|
+
// that width and title accessories sit at the line's end.
|
|
482
|
+
const runs = titleElement.querySelector<HTMLElement>(
|
|
483
|
+
'.ok-native-list-identity-title-runs'
|
|
484
|
+
);
|
|
485
|
+
for (
|
|
486
|
+
let node = runs?.parentElement;
|
|
487
|
+
node && node !== titleElement;
|
|
488
|
+
node = node.parentElement
|
|
489
|
+
) {
|
|
490
|
+
node.style.display = 'flex';
|
|
491
|
+
node.style.flex = '1 1 auto';
|
|
492
|
+
node.style.minWidth = '0';
|
|
493
|
+
}
|
|
494
|
+
titleElement.style.display = 'flex';
|
|
495
|
+
titleElement.style.alignItems = 'center';
|
|
496
|
+
}
|
|
497
|
+
if (row.titleLeadingIcon && presentation !== 'walletSidebar') {
|
|
498
|
+
const descriptor = row.titleLeadingIcon;
|
|
499
|
+
if (titleElement.hasAttribute('data-nl-slot')) {
|
|
500
|
+
// Keep the glyph out of the title slot that text styles apply to.
|
|
501
|
+
const titleText = tagSlot(
|
|
502
|
+
createElement(document, 'span', 'ok-native-list-identity-title-text'),
|
|
503
|
+
'title'
|
|
504
|
+
);
|
|
505
|
+
while (titleElement.firstChild)
|
|
506
|
+
titleText.appendChild(titleElement.firstChild);
|
|
507
|
+
if (hasTitleRuns) {
|
|
508
|
+
titleText.style.display = 'flex';
|
|
509
|
+
titleText.style.minWidth = '0';
|
|
510
|
+
}
|
|
511
|
+
titleElement.removeAttribute('data-nl-slot');
|
|
512
|
+
titleElement.appendChild(titleText);
|
|
513
|
+
}
|
|
514
|
+
const icon = primitives.iconAction(
|
|
515
|
+
descriptor.name,
|
|
516
|
+
undefined,
|
|
517
|
+
undefined,
|
|
518
|
+
descriptor.tintColor
|
|
519
|
+
);
|
|
520
|
+
icon.className = 'ok-native-list-identity-title-leading-icon';
|
|
521
|
+
if (descriptor.accessibilityLabel)
|
|
522
|
+
icon.setAttribute('aria-label', descriptor.accessibilityLabel);
|
|
523
|
+
else icon.setAttribute('aria-hidden', 'true');
|
|
524
|
+
titleElement.style.display = 'flex';
|
|
525
|
+
titleElement.style.alignItems = 'center';
|
|
526
|
+
// 6px to the title, whatever gap the title line already has.
|
|
527
|
+
const lineGap = Number.parseFloat(titleElement.style.gap || '0') || 0;
|
|
528
|
+
icon.style.marginInlineEnd = `${Math.max(0, 6 - lineGap)}px`;
|
|
529
|
+
titleElement.prepend(icon);
|
|
530
|
+
}
|
|
394
531
|
if (presentation === 'walletSidebar' && row.badges?.length) {
|
|
395
532
|
const badges = createElement(
|
|
396
533
|
document,
|
|
@@ -403,6 +540,7 @@ function createIdentityRow(
|
|
|
403
540
|
column.appendChild(badges);
|
|
404
541
|
}
|
|
405
542
|
for (const key of ['title', 'subtitle'] as const) {
|
|
543
|
+
if (key === 'title' && hasTitleRuns) continue;
|
|
406
544
|
const lines = row.style?.[key]?.lines ?? row[`${key}Lines`];
|
|
407
545
|
if (lines !== undefined)
|
|
408
546
|
column
|