@onekeyfe/react-native-native-list 3.0.157-alpha.248 → 3.0.157-alpha.250
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/README.md +21 -5
- package/android/src/main/java/com/onekey/nativelist/NativeListAccessoryStack.kt +711 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListActionRenderer.kt +169 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListActivityRenderer.kt +243 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListAdapter.kt +20 -6
- package/android/src/main/java/com/onekey/nativelist/NativeListDataRowRenderer.kt +487 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListIdentityRenderer.kt +820 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListImageSlot.kt +147 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListLeadingVisual.kt +453 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListMarketRenderer.kt +997 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListMediaTileRenderer.kt +234 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListMessageRenderer.kt +232 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListMetricCardRenderer.kt +551 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListModels.kt +24 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListPrimitives.kt +475 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListRailRenderer.kt +143 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListRendererRegistry.kt +42 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListRendererRowView.kt +415 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListResolvedText.kt +163 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListRowHost.kt +70 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListSectionHeaderRenderer.kt +748 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListSystemRenderer.kt +464 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListTextView.kt +25 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListView.kt +174 -104
- package/android/src/main/java/com/onekey/nativelist/NativeListWalletGroupRenderer.kt +407 -0
- package/android/src/test/java/com/margelo/nitro/nativelist/NativeListSelectorBackgroundColorTest.kt +34 -0
- package/docs/DESIGN.md +518 -9
- package/docs/MIGRATION_BASELINE.md +117 -0
- package/docs/ROW_TEMPLATES.md +359 -0
- package/docs/SPEC.md +358 -0
- package/docs/STYLE_SPEC.md +978 -0
- package/docs/images/list-capabilities.svg +39 -0
- package/docs/images/row-action.svg +17 -0
- package/docs/images/row-activity.svg +24 -0
- package/docs/images/row-data.svg +24 -0
- package/docs/images/row-identity.svg +25 -0
- package/docs/images/row-market.svg +23 -0
- package/docs/images/row-media-tile.svg +26 -0
- package/docs/images/row-message.svg +20 -0
- package/docs/images/row-metric-card.svg +33 -0
- package/docs/images/row-rail.svg +18 -0
- package/docs/images/row-section-header.svg +19 -0
- package/docs/images/row-style-regions.svg +30 -0
- package/docs/images/row-system.svg +30 -0
- package/docs/images/row-wallet-group.svg +26 -0
- package/ios/NativeListAccessoryStack.swift +680 -0
- package/ios/NativeListActionRenderer.swift +108 -0
- package/ios/NativeListActivityRenderer.swift +179 -0
- package/ios/NativeListDataRowRenderer.swift +444 -0
- package/ios/NativeListIdentityRenderer.swift +685 -0
- package/ios/NativeListImageSlot.swift +140 -0
- package/ios/NativeListLeadingVisual.swift +372 -0
- package/ios/NativeListMarketRenderer.swift +698 -0
- package/ios/NativeListMediaTileRenderer.swift +184 -0
- package/ios/NativeListMessageRenderer.swift +168 -0
- package/ios/NativeListMetricCardRenderer.swift +420 -0
- package/ios/NativeListModels.swift +32 -0
- package/ios/NativeListRailRenderer.swift +152 -0
- package/ios/NativeListRendererCell.swift +311 -0
- package/ios/NativeListRendererRegistry.swift +50 -0
- package/ios/NativeListResolvedText.swift +122 -0
- package/ios/NativeListRowHost.swift +63 -0
- package/ios/NativeListSectionHeaderRenderer.swift +708 -0
- package/ios/NativeListSystemRenderer.swift +568 -0
- package/ios/NativeListTextLabel.swift +42 -0
- package/ios/NativeListTextStyles.swift +236 -0
- package/ios/NativeListWalletGroupRenderer.swift +255 -0
- package/ios/RNCNativeListView.swift +111 -180
- package/lib/module/models.js +54 -0
- package/lib/module/validation.js +324 -26
- package/lib/module/web/NativeListWebEngine.js +148 -936
- package/lib/module/web/templates/ActionRowRenderer.js +97 -0
- package/lib/module/web/templates/ActivityRowRenderer.js +95 -0
- package/lib/module/web/templates/DataRowRenderer.js +145 -0
- package/lib/module/web/templates/IdentityRowRenderer.js +289 -0
- package/lib/module/web/templates/MarketRowRenderer.js +310 -0
- package/lib/module/web/templates/MediaTileRowRenderer.js +132 -0
- package/lib/module/web/templates/MessageRowRenderer.js +165 -0
- package/lib/module/web/templates/MetricCardRowRenderer.js +172 -0
- package/lib/module/web/templates/RailRowRenderer.js +98 -0
- package/lib/module/web/templates/RowContainerStyle.js +100 -0
- package/lib/module/web/templates/RowElements.js +93 -0
- package/lib/module/web/templates/RowRendererRegistry.js +70 -0
- package/lib/module/web/templates/RowText.js +121 -0
- package/lib/module/web/templates/RowVisual.js +43 -0
- package/lib/module/web/templates/SectionHeaderRowRenderer.js +146 -0
- package/lib/module/web/templates/SystemRowRenderer.js +161 -0
- package/lib/module/web/templates/WalletGroupRowRenderer.js +96 -0
- package/lib/typescript/src/models.d.ts +166 -13
- package/lib/typescript/src/web/NativeListWebEngine.d.ts +18 -16
- package/lib/typescript/src/web/templates/ActionRowRenderer.d.ts +15 -0
- package/lib/typescript/src/web/templates/ActivityRowRenderer.d.ts +15 -0
- package/lib/typescript/src/web/templates/DataRowRenderer.d.ts +15 -0
- package/lib/typescript/src/web/templates/IdentityRowRenderer.d.ts +16 -0
- package/lib/typescript/src/web/templates/MarketRowRenderer.d.ts +30 -0
- package/lib/typescript/src/web/templates/MediaTileRowRenderer.d.ts +15 -0
- package/lib/typescript/src/web/templates/MessageRowRenderer.d.ts +44 -0
- package/lib/typescript/src/web/templates/MetricCardRowRenderer.d.ts +15 -0
- package/lib/typescript/src/web/templates/RailRowRenderer.d.ts +28 -0
- package/lib/typescript/src/web/templates/RowContainerStyle.d.ts +9 -0
- package/lib/typescript/src/web/templates/RowElements.d.ts +38 -0
- package/lib/typescript/src/web/templates/RowRendererRegistry.d.ts +83 -0
- package/lib/typescript/src/web/templates/RowText.d.ts +9 -0
- package/lib/typescript/src/web/templates/RowVisual.d.ts +20 -0
- package/lib/typescript/src/web/templates/SectionHeaderRowRenderer.d.ts +15 -0
- package/lib/typescript/src/web/templates/SystemRowRenderer.d.ts +16 -0
- package/lib/typescript/src/web/templates/WalletGroupRowRenderer.d.ts +20 -0
- package/package.json +3 -3
- package/src/models.ts +281 -19
- package/src/validation.ts +501 -46
- package/src/web/NativeListWebEngine.ts +361 -1932
- package/src/web/templates/ActionRowRenderer.ts +123 -0
- package/src/web/templates/ActivityRowRenderer.ts +159 -0
- package/src/web/templates/DataRowRenderer.ts +212 -0
- package/src/web/templates/IdentityRowRenderer.ts +527 -0
- package/src/web/templates/MarketRowRenderer.ts +467 -0
- package/src/web/templates/MediaTileRowRenderer.ts +182 -0
- package/src/web/templates/MessageRowRenderer.ts +306 -0
- package/src/web/templates/MetricCardRowRenderer.ts +337 -0
- package/src/web/templates/RailRowRenderer.ts +136 -0
- package/src/web/templates/RowContainerStyle.ts +131 -0
- package/src/web/templates/RowElements.ts +160 -0
- package/src/web/templates/RowRendererRegistry.ts +111 -0
- package/src/web/templates/RowText.ts +181 -0
- package/src/web/templates/RowVisual.ts +115 -0
- package/src/web/templates/SectionHeaderRowRenderer.ts +243 -0
- package/src/web/templates/SystemRowRenderer.ts +282 -0
- package/src/web/templates/WalletGroupRowRenderer.ts +131 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt +0 -4538
- package/ios/NativeListCell.swift +0 -4300
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { captureInlineStyles, createElement, restoreInlineStyles, setData, tagSlot } from "./RowElements.js";
|
|
4
|
+
import { RowVisualStyle } from "./RowVisual.js";
|
|
5
|
+
const toneColor = (tone, fallback) => tone === 'positive' ? 'var(--nl-positive)' : tone === 'negative' ? 'var(--nl-negative)' : tone === 'secondary' ? 'var(--nl-secondary)' : `var(--nl-${fallback})`;
|
|
6
|
+
function createBadge(document, badge) {
|
|
7
|
+
const label = tagSlot(createElement(document, 'span', 'ok-native-list-badge', badge.text), 'badge');
|
|
8
|
+
label.dataset.tone = badge.tone ?? '';
|
|
9
|
+
return label;
|
|
10
|
+
}
|
|
11
|
+
function createMetricCell(document, primitives, metric, shaded) {
|
|
12
|
+
const cell = createElement(document, 'div', 'ok-native-list-composite-cell');
|
|
13
|
+
setData(cell, 'shaded', shaded);
|
|
14
|
+
cell.appendChild(createElement(document, 'div', 'ok-native-list-secondary', metric.label));
|
|
15
|
+
const valueLine = createElement(document, 'div');
|
|
16
|
+
valueLine.style.display = 'flex';
|
|
17
|
+
valueLine.style.alignItems = 'center';
|
|
18
|
+
valueLine.style.gap = '6px';
|
|
19
|
+
if (metric.visual) {
|
|
20
|
+
const visual = primitives.visual(metric.visual);
|
|
21
|
+
if (visual) {
|
|
22
|
+
visual.style.width = '16px';
|
|
23
|
+
visual.style.height = '16px';
|
|
24
|
+
visual.style.flexBasis = '16px';
|
|
25
|
+
const image = visual.querySelector('img');
|
|
26
|
+
if (image) {
|
|
27
|
+
image.style.width = '16px';
|
|
28
|
+
image.style.height = '16px';
|
|
29
|
+
}
|
|
30
|
+
valueLine.appendChild(visual);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const value = createElement(document, 'span', 'ok-native-list-composite-value', metric.value);
|
|
34
|
+
value.style.color = toneColor(metric.tone, 'primary');
|
|
35
|
+
valueLine.appendChild(value);
|
|
36
|
+
cell.appendChild(valueLine);
|
|
37
|
+
return cell;
|
|
38
|
+
}
|
|
39
|
+
function createMetricRow(document, primitives, row) {
|
|
40
|
+
if (row.variant === 'activity' || row.variant === 'performance') {
|
|
41
|
+
const body = createElement(document, 'div', 'ok-native-list-row ok-native-list-composite');
|
|
42
|
+
body.appendChild(tagSlot(createElement(document, 'div', 'ok-native-list-composite-heading', row.title), 'title'));
|
|
43
|
+
const metrics = row.metrics ?? [];
|
|
44
|
+
const firstLine = createElement(document, 'div', 'ok-native-list-composite-row');
|
|
45
|
+
metrics.slice(0, 2).forEach(metric => firstLine.appendChild(createMetricCell(document, primitives, metric, false)));
|
|
46
|
+
body.appendChild(firstLine);
|
|
47
|
+
if (row.variant === 'activity') {
|
|
48
|
+
body.appendChild(createElement(document, 'div', 'ok-native-list-divider'));
|
|
49
|
+
} else {
|
|
50
|
+
const progress = createElement(document, 'div', 'ok-native-list-progress');
|
|
51
|
+
const fill = createElement(document, 'span');
|
|
52
|
+
fill.style.width = String(Math.round((row.progress ?? 0) * 100)) + '%';
|
|
53
|
+
progress.appendChild(fill);
|
|
54
|
+
body.appendChild(progress);
|
|
55
|
+
}
|
|
56
|
+
const secondLine = createElement(document, 'div', 'ok-native-list-composite-row');
|
|
57
|
+
metrics.slice(2).forEach(metric => secondLine.appendChild(createMetricCell(document, primitives, metric, row.variant === 'performance')));
|
|
58
|
+
body.appendChild(secondLine);
|
|
59
|
+
return body;
|
|
60
|
+
}
|
|
61
|
+
const body = createElement(document, 'div', 'ok-native-list-row ok-native-list-metric');
|
|
62
|
+
if (row.visual) {
|
|
63
|
+
const visual = primitives.visual(row.visual);
|
|
64
|
+
if (visual) body.appendChild(visual);
|
|
65
|
+
}
|
|
66
|
+
body.appendChild(tagSlot(createElement(document, 'div', 'ok-native-list-secondary', row.title), 'title'));
|
|
67
|
+
body.appendChild(tagSlot(createElement(document, 'div', 'ok-native-list-metric-value', row.value), 'value'));
|
|
68
|
+
if (row.trend) {
|
|
69
|
+
const trend = tagSlot(createElement(document, 'div', 'ok-native-list-secondary', row.trend), 'trend');
|
|
70
|
+
trend.style.color = row.trendTone === 'positive' ? 'var(--nl-positive)' : row.trendTone === 'negative' ? 'var(--nl-negative)' : 'var(--nl-secondary)';
|
|
71
|
+
body.appendChild(trend);
|
|
72
|
+
}
|
|
73
|
+
if (row.subtitle) body.appendChild(tagSlot(createElement(document, 'div', 'ok-native-list-secondary', row.subtitle), 'subtitle'));
|
|
74
|
+
if (row.badge) body.appendChild(createBadge(document, row.badge));
|
|
75
|
+
return body;
|
|
76
|
+
}
|
|
77
|
+
const views = new WeakMap();
|
|
78
|
+
function bind(body, row, primitives) {
|
|
79
|
+
const v = views.get(body);
|
|
80
|
+
v.primitives = primitives;
|
|
81
|
+
// Text styles are part of the key: applyTextLayout inserts wrappers and
|
|
82
|
+
// rewrites text (lines: 1), which restoring inline styles cannot undo.
|
|
83
|
+
// Rebuilding reuses equal visual slots, so images never restart.
|
|
84
|
+
const contentKey = JSON.stringify({
|
|
85
|
+
...row,
|
|
86
|
+
style: {
|
|
87
|
+
title: row.style?.title,
|
|
88
|
+
value: row.style?.value,
|
|
89
|
+
trend: row.style?.trend,
|
|
90
|
+
subtitle: row.style?.subtitle
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
if (contentKey !== v.contentKey) {
|
|
94
|
+
let index = 0;
|
|
95
|
+
restoreInlineStyles(v.defaults);
|
|
96
|
+
const next = createMetricRow(body.ownerDocument, {
|
|
97
|
+
...primitives,
|
|
98
|
+
visual: source => {
|
|
99
|
+
const slot = index++;
|
|
100
|
+
const key = JSON.stringify([row.key, row.variant ?? 'standard', source]);
|
|
101
|
+
const previous = v.visuals[slot];
|
|
102
|
+
if (previous?.key === key) return previous.node;
|
|
103
|
+
if (previous) primitives.dispose(previous.node);
|
|
104
|
+
const node = primitives.visual(source);
|
|
105
|
+
if (node) v.visuals[slot] = {
|
|
106
|
+
key,
|
|
107
|
+
node
|
|
108
|
+
};
|
|
109
|
+
return node;
|
|
110
|
+
}
|
|
111
|
+
}, row);
|
|
112
|
+
v.visuals.slice(index).forEach(slot => primitives.dispose(slot.node));
|
|
113
|
+
v.visuals.length = index;
|
|
114
|
+
body.replaceChildren(...Array.from(next.childNodes));
|
|
115
|
+
body.className = next.className;
|
|
116
|
+
body.style.cssText = next.style.cssText;
|
|
117
|
+
// Image opacity is loading state; restoring it would hide loaded images.
|
|
118
|
+
v.defaults = captureInlineStyles(body);
|
|
119
|
+
const leading = body.querySelector(':scope > .ok-native-list-visual, :scope > .ok-native-list-stacked');
|
|
120
|
+
v.visualStyle = leading ? new RowVisualStyle(leading) : undefined;
|
|
121
|
+
v.contentKey = contentKey;
|
|
122
|
+
}
|
|
123
|
+
restoreInlineStyles(v.defaults);
|
|
124
|
+
body.removeAttribute('data-nl-container-background');
|
|
125
|
+
body.removeAttribute('data-nl-container-border');
|
|
126
|
+
const style = row.style;
|
|
127
|
+
const composite = row.variant === 'activity' || row.variant === 'performance';
|
|
128
|
+
if (style?.horizontalPadding !== undefined) body.style.paddingInline = `${style.horizontalPadding}px`;
|
|
129
|
+
if (style?.verticalPadding !== undefined) body.style.paddingBlock = `${style.verticalPadding}px`;
|
|
130
|
+
if (style?.lineGap !== undefined) body.style.rowGap = `${style.lineGap}px`;
|
|
131
|
+
if (!composite && v.visualStyle) {
|
|
132
|
+
v.visualStyle.apply(style?.image, style?.image?.width ?? 40, style?.image?.height ?? 40, 0);
|
|
133
|
+
const leading = body.querySelector(':scope > .ok-native-list-visual, :scope > .ok-native-list-stacked');
|
|
134
|
+
leading.style.marginBottom = style?.leadingGap === undefined ? '' : `${style.leadingGap - (style.lineGap ?? 5)}px`;
|
|
135
|
+
}
|
|
136
|
+
const slots = composite ? ['title'] : ['title', 'value', 'trend', 'subtitle'];
|
|
137
|
+
slots.forEach(slot => {
|
|
138
|
+
const text = style?.[slot];
|
|
139
|
+
if (text) body.querySelectorAll(`[data-nl-slot="${slot}"]`).forEach(node => primitives.textStyle(node, text));
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function create(document, row, primitives) {
|
|
143
|
+
const body = document.createElement('div');
|
|
144
|
+
body.dataset.nlRenderer = 'metricCard';
|
|
145
|
+
views.set(body, {
|
|
146
|
+
contentKey: '',
|
|
147
|
+
visuals: [],
|
|
148
|
+
defaults: new Map(),
|
|
149
|
+
primitives
|
|
150
|
+
});
|
|
151
|
+
bind(body, row, primitives);
|
|
152
|
+
return body;
|
|
153
|
+
}
|
|
154
|
+
function recycle(body) {
|
|
155
|
+
const v = views.get(body);
|
|
156
|
+
if (!v) return;
|
|
157
|
+
v.visuals.forEach(slot => v.primitives.dispose(slot.node));
|
|
158
|
+
v.visuals = [];
|
|
159
|
+
v.defaults.clear();
|
|
160
|
+
v.contentKey = '';
|
|
161
|
+
v.visualStyle = undefined;
|
|
162
|
+
body.replaceChildren();
|
|
163
|
+
}
|
|
164
|
+
export const metricCardRowRenderer = {
|
|
165
|
+
key: 'metricCard',
|
|
166
|
+
create,
|
|
167
|
+
bind,
|
|
168
|
+
recycle,
|
|
169
|
+
measure: (row, _width) => row.variant === 'activity' ? 161 : row.variant === 'performance' ? 178 : 132,
|
|
170
|
+
measureRendered: (_body, _row) => undefined
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=MetricCardRowRenderer.js.map
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { RowVisualStyle } from "./RowVisual.js";
|
|
4
|
+
export function resolveRailRow(row) {
|
|
5
|
+
const style = row.style;
|
|
6
|
+
return {
|
|
7
|
+
horizontalPadding: style?.horizontalPadding ?? 4,
|
|
8
|
+
verticalPadding: style?.verticalPadding ?? 4,
|
|
9
|
+
leadingGap: style?.leadingGap ?? 6,
|
|
10
|
+
badgeGap: style?.titleBadgeGap ?? 6,
|
|
11
|
+
trailingGap: style?.trailingGap ?? 6,
|
|
12
|
+
width: style?.image?.width ?? 20,
|
|
13
|
+
height: style?.image?.height ?? 20,
|
|
14
|
+
title: row.title,
|
|
15
|
+
badge: row.badge?.text ?? '',
|
|
16
|
+
status: row.status === 'none' ? '' : row.status ?? ''
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const views = new WeakMap();
|
|
20
|
+
function bind(body, row, primitives) {
|
|
21
|
+
const v = views.get(body);
|
|
22
|
+
v.primitives = primitives;
|
|
23
|
+
const r = resolveRailRow(row);
|
|
24
|
+
body.style.cssText = '';
|
|
25
|
+
body.removeAttribute('data-nl-container-background');
|
|
26
|
+
body.removeAttribute('data-nl-container-border');
|
|
27
|
+
body.style.padding = `${r.verticalPadding}px ${r.horizontalPadding}px`;
|
|
28
|
+
const text = (view, value, style) => {
|
|
29
|
+
view.style.cssText = '';
|
|
30
|
+
view.textContent = value;
|
|
31
|
+
if (style) primitives.textStyle(view, style);
|
|
32
|
+
if (value) body.appendChild(view);else view.remove();
|
|
33
|
+
};
|
|
34
|
+
text(v.title, r.title, row.style?.title);
|
|
35
|
+
text(v.badge, r.badge, row.style?.badge);
|
|
36
|
+
if (row.badge?.tone) v.badge.dataset.tone = row.badge.tone;else delete v.badge.dataset.tone;
|
|
37
|
+
v.badge.style.marginInlineStart = `${r.badgeGap - 6}px`;
|
|
38
|
+
text(v.status, r.status, row.style?.status);
|
|
39
|
+
v.status.style.marginInlineStart = `${r.trailingGap - 6}px`;
|
|
40
|
+
const identity = JSON.stringify([row.key, row.visual]);
|
|
41
|
+
if (identity !== v.identity) {
|
|
42
|
+
if (v.visual) {
|
|
43
|
+
primitives.dispose(v.visual);
|
|
44
|
+
v.visual.remove();
|
|
45
|
+
}
|
|
46
|
+
v.visual = primitives.visual(row.visual);
|
|
47
|
+
v.visualStyle = v.visual ? new RowVisualStyle(v.visual) : undefined;
|
|
48
|
+
v.identity = identity;
|
|
49
|
+
}
|
|
50
|
+
if (v.visual) body.insertBefore(v.visual, body.firstChild);
|
|
51
|
+
v.visualStyle?.apply(row.style?.image, r.width, r.height, r.leadingGap - 6);
|
|
52
|
+
}
|
|
53
|
+
function create(document, row, primitives) {
|
|
54
|
+
const span = (className, slot) => {
|
|
55
|
+
const view = document.createElement('span');
|
|
56
|
+
view.className = className;
|
|
57
|
+
view.dataset.nlSlot = slot;
|
|
58
|
+
return view;
|
|
59
|
+
};
|
|
60
|
+
const body = document.createElement('div');
|
|
61
|
+
body.className = 'ok-native-list-row ok-native-list-rail';
|
|
62
|
+
body.dataset.nlRenderer = 'rail';
|
|
63
|
+
views.set(body, {
|
|
64
|
+
title: span('ok-native-list-rail-title', 'title'),
|
|
65
|
+
badge: span('ok-native-list-badge', 'badge'),
|
|
66
|
+
status: span('ok-native-list-secondary', 'status'),
|
|
67
|
+
identity: '',
|
|
68
|
+
primitives
|
|
69
|
+
});
|
|
70
|
+
bind(body, row, primitives);
|
|
71
|
+
return body;
|
|
72
|
+
}
|
|
73
|
+
function recycle(body) {
|
|
74
|
+
const v = views.get(body);
|
|
75
|
+
if (!v) return;
|
|
76
|
+
if (v.visual) {
|
|
77
|
+
v.primitives.dispose(v.visual);
|
|
78
|
+
v.visual.remove();
|
|
79
|
+
}
|
|
80
|
+
v.visual = undefined;
|
|
81
|
+
v.visualStyle = undefined;
|
|
82
|
+
v.identity = '';
|
|
83
|
+
}
|
|
84
|
+
export function measureRailWidth(row) {
|
|
85
|
+
const r = resolveRailRow(row);
|
|
86
|
+
const width = (value, style, size) => value.length * 7 * ((style?.fontSize ?? size) / size);
|
|
87
|
+
// Retain the historical 50px allowance and viewport limits at default values.
|
|
88
|
+
return Math.min(288, Math.max(72, 50 + width(r.title, row.style?.title, 12) + width(r.badge, row.style?.badge, 11) + width(r.status, row.style?.status, 13) + (r.horizontalPadding - 4) * 2 + r.width - 20 + r.leadingGap - 6 + (r.badge ? r.badgeGap - 6 : 0) + (r.status ? r.trailingGap - 6 : 0)));
|
|
89
|
+
}
|
|
90
|
+
export const railRowRenderer = {
|
|
91
|
+
key: 'rail',
|
|
92
|
+
create,
|
|
93
|
+
bind,
|
|
94
|
+
recycle,
|
|
95
|
+
measure: (_row, _width) => 40,
|
|
96
|
+
measureRendered: (_body, _row) => undefined
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=RailRowRenderer.js.map
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Inline properties written by the container pass, per row body. Renderers only
|
|
4
|
+
// reset the nodes they own, so the container undoes its own writes on rebind.
|
|
5
|
+
const writesByBody = new WeakMap();
|
|
6
|
+
function restoreContainerWrites(body, force) {
|
|
7
|
+
body.removeAttribute('data-nl-container-background');
|
|
8
|
+
body.removeAttribute('data-nl-container-border');
|
|
9
|
+
const writes = writesByBody.get(body);
|
|
10
|
+
if (!writes) return;
|
|
11
|
+
writesByBody.delete(body);
|
|
12
|
+
// Undo in reverse so repeated writes restore the oldest value.
|
|
13
|
+
for (let index = writes.length - 1; index >= 0; index -= 1) {
|
|
14
|
+
const write = writes[index];
|
|
15
|
+
const {
|
|
16
|
+
style
|
|
17
|
+
} = write.element;
|
|
18
|
+
// Fallback path only (no reset before the renderer bind): a renderer that
|
|
19
|
+
// already rewrote this property owns its current value. It cannot tell a
|
|
20
|
+
// renderer rewrite of the same value apart, which is why the engine and
|
|
21
|
+
// WalletGroup reset before binding instead.
|
|
22
|
+
if (!force && style.getPropertyValue(write.property) !== write.written) continue;
|
|
23
|
+
style.removeProperty(write.property);
|
|
24
|
+
if (write.previous) style.setProperty(write.property, write.previous, write.previousPriority);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Undo the previous container pass before a renderer rebinds `body`, so the
|
|
30
|
+
* renderer always writes over its own baseline and the next
|
|
31
|
+
* `applyRowContainerStyle` records that fresh value as the value to restore.
|
|
32
|
+
*/
|
|
33
|
+
export function resetRowContainerStyle(body) {
|
|
34
|
+
restoreContainerWrites(body, true);
|
|
35
|
+
}
|
|
36
|
+
function writeProperty(body, element, property, value, priority = '') {
|
|
37
|
+
const {
|
|
38
|
+
style
|
|
39
|
+
} = element;
|
|
40
|
+
const write = {
|
|
41
|
+
element,
|
|
42
|
+
property,
|
|
43
|
+
previous: style.getPropertyValue(property),
|
|
44
|
+
previousPriority: style.getPropertyPriority(property),
|
|
45
|
+
written: ''
|
|
46
|
+
};
|
|
47
|
+
style.setProperty(property, value, priority);
|
|
48
|
+
write.written = style.getPropertyValue(property);
|
|
49
|
+
let writes = writesByBody.get(body);
|
|
50
|
+
if (!writes) writesByBody.set(body, writes = []);
|
|
51
|
+
writes.push(write);
|
|
52
|
+
}
|
|
53
|
+
export function applyRowContainerStyle(body, row) {
|
|
54
|
+
restoreContainerWrites(body, false);
|
|
55
|
+
const set = (element, property, value) => writeProperty(body, element, property, value);
|
|
56
|
+
if (row.type === 'system' && row.variant === 'warning' && (row.style?.container?.height ?? row.height) !== undefined) set(body, 'height', '100%');
|
|
57
|
+
const container = row.style?.container;
|
|
58
|
+
if (!container) return;
|
|
59
|
+
if (container.backgroundColor !== undefined) {
|
|
60
|
+
set(body, '--nl-container-background', container.backgroundColor);
|
|
61
|
+
body.setAttribute('data-nl-container-background', 'true');
|
|
62
|
+
// A CSS rule allows existing hover/press feedback to override the resting fill.
|
|
63
|
+
// The template/engine re-applies its own fill on every bind, so this
|
|
64
|
+
// removal is not tracked for restoration.
|
|
65
|
+
body.style.removeProperty('background');
|
|
66
|
+
body.style.removeProperty('background-color');
|
|
67
|
+
}
|
|
68
|
+
if (container.cornerRadius !== undefined) set(body, 'border-radius', `${container.cornerRadius}px`);
|
|
69
|
+
if (container.borderWidth !== undefined) {
|
|
70
|
+
// Paint above member backgrounds without changing the content box or hit targets.
|
|
71
|
+
body.setAttribute('data-nl-container-border', 'true');
|
|
72
|
+
set(body, '--nl-container-border-width', `${container.borderWidth}px`);
|
|
73
|
+
set(body, '--nl-container-border-color', container.borderColor ?? 'transparent');
|
|
74
|
+
set(body, 'border-color', 'transparent');
|
|
75
|
+
} else if (container.borderColor !== undefined) set(body, 'border-color', container.borderColor);
|
|
76
|
+
if (container.contentVerticalAlignment !== undefined) {
|
|
77
|
+
const alignment = {
|
|
78
|
+
top: 'flex-start',
|
|
79
|
+
center: 'center',
|
|
80
|
+
bottom: 'flex-end'
|
|
81
|
+
}[container.contentVerticalAlignment];
|
|
82
|
+
const vertical = row.type === 'walletGroup' || row.type === 'mediaTile' || row.type === 'metricCard' || row.type === 'identity' && row.presentation === 'walletSidebar' || row.type === 'system' && row.variant === 'warning';
|
|
83
|
+
if (vertical) {
|
|
84
|
+
set(body, 'display', 'flex');
|
|
85
|
+
set(body, 'flex-direction', 'column');
|
|
86
|
+
if (row.type === 'mediaTile') set(body, 'gap', '0px');
|
|
87
|
+
set(body, 'justify-content', alignment);
|
|
88
|
+
Array.from(body.children).forEach(child => {
|
|
89
|
+
set(child, 'flex-shrink', '0');
|
|
90
|
+
});
|
|
91
|
+
} else {
|
|
92
|
+
set(body, 'align-items', alignment);
|
|
93
|
+
// Timestamp/accessory defaults may have their own align-self.
|
|
94
|
+
Array.from(body.children).forEach(child => {
|
|
95
|
+
set(child, 'align-self', alignment);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=RowContainerStyle.js.map
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export function createElement(document, tag, className, text) {
|
|
4
|
+
const element = document.createElement(tag);
|
|
5
|
+
if (className) element.className = className;
|
|
6
|
+
if (text !== undefined) element.textContent = text;
|
|
7
|
+
return element;
|
|
8
|
+
}
|
|
9
|
+
export function setData(element, name, value) {
|
|
10
|
+
if (value === undefined) delete element.dataset[name];else element.dataset[name] = String(value);
|
|
11
|
+
}
|
|
12
|
+
export function tagSlot(element, slot) {
|
|
13
|
+
element.dataset.nlSlot = slot;
|
|
14
|
+
return element;
|
|
15
|
+
}
|
|
16
|
+
export function markActionAnchorSource(element, source, slot) {
|
|
17
|
+
setData(element, 'nativeListAnchorSource', source);
|
|
18
|
+
if (slot !== undefined) setData(element, 'nativeListAnchorSlot', slot);
|
|
19
|
+
}
|
|
20
|
+
export function createTextColumn(document, title, subtitle, tertiary, tertiaryTone, badges, slots = {
|
|
21
|
+
title: 'title',
|
|
22
|
+
subtitle: 'subtitle',
|
|
23
|
+
tertiary: 'tertiary'
|
|
24
|
+
}) {
|
|
25
|
+
const column = createElement(document, 'span', 'ok-native-list-flex');
|
|
26
|
+
const titleLine = tagSlot(createElement(document, 'span', 'ok-native-list-title', title), slots.title);
|
|
27
|
+
if (badges?.length) {
|
|
28
|
+
titleLine.removeAttribute('data-nl-slot');
|
|
29
|
+
titleLine.replaceChildren(tagSlot(createElement(document, 'span', undefined, title), slots.title));
|
|
30
|
+
const badgeLine = createElement(document, 'span', 'ok-native-list-badges');
|
|
31
|
+
badges.forEach(badge => badgeLine.appendChild(createBadge(document, badge)));
|
|
32
|
+
titleLine.appendChild(badgeLine);
|
|
33
|
+
}
|
|
34
|
+
column.appendChild(titleLine);
|
|
35
|
+
if (subtitle) column.appendChild(tagSlot(createElement(document, 'span', 'ok-native-list-secondary', subtitle), slots.subtitle));
|
|
36
|
+
if (tertiary) {
|
|
37
|
+
const element = tagSlot(createElement(document, 'span', tertiaryTone === 'info' ? 'ok-native-list-secondary ok-native-list-info' : 'ok-native-list-secondary ok-native-list-tertiary', tertiary), slots.tertiary);
|
|
38
|
+
column.appendChild(element);
|
|
39
|
+
}
|
|
40
|
+
return column;
|
|
41
|
+
}
|
|
42
|
+
export function createBadge(document, badge) {
|
|
43
|
+
const element = tagSlot(createElement(document, 'span', 'ok-native-list-badge', badge.text), 'badge');
|
|
44
|
+
setData(element, 'tone', badge.tone);
|
|
45
|
+
return element;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Selector digits retain their font family, including explicit button fonts.
|
|
49
|
+
export function applyTabularNumbers(body) {
|
|
50
|
+
body.style.fontVariantNumeric = 'tabular-nums';
|
|
51
|
+
body.querySelectorAll('span,button').forEach(text => {
|
|
52
|
+
text.style.fontVariantNumeric = 'tabular-nums';
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Selector presentations use their explicit-height geometry whenever the row
|
|
58
|
+
* has a resolved explicit height: the legacy `row.height` or the preferred
|
|
59
|
+
* `style.container.height`.
|
|
60
|
+
*/
|
|
61
|
+
export function hasExplicitRowHeight(row) {
|
|
62
|
+
return (row.style?.container?.height ?? row.height) !== undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Legacy `size` preset adjustment, applied by templates that opt in. */
|
|
66
|
+
export function rowSizeModifier(size) {
|
|
67
|
+
if (size === 'small') return -8;
|
|
68
|
+
if (size === 'large') return 12;
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Async image reveal state is owned by the image lifecycle, not by template
|
|
73
|
+
// defaults: a reused image that already fired `load` never fires it again.
|
|
74
|
+
const isImageLoadingNode = node => node.tagName === 'IMG' || node.classList.contains('ok-native-list-selector-image-background');
|
|
75
|
+
|
|
76
|
+
/** Captures factory inline styles of a template subtree. */
|
|
77
|
+
export function captureInlineStyles(root) {
|
|
78
|
+
return new Map([root, ...root.querySelectorAll('*')].map(node => [node, node.style.cssText]));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Restores captured factory styles while keeping image loading visibility. */
|
|
82
|
+
export function restoreInlineStyles(defaults) {
|
|
83
|
+
defaults.forEach((css, node) => {
|
|
84
|
+
if (!isImageLoadingNode(node)) {
|
|
85
|
+
node.style.cssText = css;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const opacity = node.style.opacity;
|
|
89
|
+
node.style.cssText = css;
|
|
90
|
+
node.style.opacity = opacity;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=RowElements.js.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { walletGroupRowRenderer } from "./WalletGroupRowRenderer.js";
|
|
4
|
+
import { identityRowRenderer } from "./IdentityRowRenderer.js";
|
|
5
|
+
import { sectionHeaderRowRenderer } from "./SectionHeaderRowRenderer.js";
|
|
6
|
+
import { marketRowRenderer } from "./MarketRowRenderer.js";
|
|
7
|
+
import { metricCardRowRenderer } from "./MetricCardRowRenderer.js";
|
|
8
|
+
import { dataRowRenderer } from "./DataRowRenderer.js";
|
|
9
|
+
import { activityRowRenderer } from "./ActivityRowRenderer.js";
|
|
10
|
+
import { systemRowRenderer } from "./SystemRowRenderer.js";
|
|
11
|
+
import { actionRowRenderer } from "./ActionRowRenderer.js";
|
|
12
|
+
import { mediaTileRowRenderer } from "./MediaTileRowRenderer.js";
|
|
13
|
+
import { messageRowRenderer } from "./MessageRowRenderer.js";
|
|
14
|
+
import { railRowRenderer } from "./RailRowRenderer.js";
|
|
15
|
+
function registration(renderer, row) {
|
|
16
|
+
return {
|
|
17
|
+
key: renderer.key,
|
|
18
|
+
appliesSizePreset: renderer.appliesSizePreset?.(row) ?? true,
|
|
19
|
+
create: (document, primitives) => renderer.create(document, row, primitives),
|
|
20
|
+
bind: (body, primitives) => renderer.bind(body, row, primitives),
|
|
21
|
+
measure: (width, layout) => renderer.measure(row, width, layout),
|
|
22
|
+
measureRendered: body => renderer.measureRendered(body, row),
|
|
23
|
+
reorderPreview: body => renderer.reorderPreview?.(body, row)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const factories = {
|
|
27
|
+
walletGroup: row => registration(walletGroupRowRenderer, row),
|
|
28
|
+
identity: row => registration(identityRowRenderer, row),
|
|
29
|
+
sectionHeader: row => registration(sectionHeaderRowRenderer, row),
|
|
30
|
+
market: row => registration(marketRowRenderer, row),
|
|
31
|
+
metricCard: row => registration(metricCardRowRenderer, row),
|
|
32
|
+
dataRow: row => registration(dataRowRenderer, row),
|
|
33
|
+
activity: row => registration(activityRowRenderer, row),
|
|
34
|
+
system: row => registration(systemRowRenderer, row),
|
|
35
|
+
action: row => registration(actionRowRenderer, row),
|
|
36
|
+
message: row => registration(messageRowRenderer, row),
|
|
37
|
+
rail: row => registration(railRowRenderer, row),
|
|
38
|
+
mediaTile: row => registration(mediaTileRowRenderer, row)
|
|
39
|
+
};
|
|
40
|
+
const renderers = {
|
|
41
|
+
walletGroup: walletGroupRowRenderer,
|
|
42
|
+
identity: identityRowRenderer,
|
|
43
|
+
sectionHeader: sectionHeaderRowRenderer,
|
|
44
|
+
market: marketRowRenderer,
|
|
45
|
+
metricCard: metricCardRowRenderer,
|
|
46
|
+
dataRow: dataRowRenderer,
|
|
47
|
+
activity: activityRowRenderer,
|
|
48
|
+
system: systemRowRenderer,
|
|
49
|
+
action: actionRowRenderer,
|
|
50
|
+
message: messageRowRenderer,
|
|
51
|
+
rail: railRowRenderer,
|
|
52
|
+
mediaTile: mediaTileRowRenderer
|
|
53
|
+
};
|
|
54
|
+
const isRegistered = key => Object.prototype.hasOwnProperty.call(factories, key);
|
|
55
|
+
|
|
56
|
+
// Closed registration; a row's data key, styles and placement never affect reuse.
|
|
57
|
+
export function rowRenderer(row) {
|
|
58
|
+
if (!isRegistered(row.type)) throw new Error('No renderer registered for ' + row.type);
|
|
59
|
+
return factories[row.type](row);
|
|
60
|
+
}
|
|
61
|
+
export function rowRendererKey(row) {
|
|
62
|
+
return row.type;
|
|
63
|
+
}
|
|
64
|
+
export function recycleRowBody(body) {
|
|
65
|
+
const key = body.dataset.nlRenderer ?? '';
|
|
66
|
+
if (!isRegistered(key)) return false;
|
|
67
|
+
renderers[key].recycle(body);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=RowRendererRegistry.js.map
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { createElement } from "./RowElements.js";
|
|
4
|
+
export function applyValueSegments(element, segments, fontSize = 16, lineHeight = 24, weight = 500) {
|
|
5
|
+
if (!segments?.length) return;
|
|
6
|
+
element.textContent = '';
|
|
7
|
+
element.style.fontSize = String(fontSize) + 'px';
|
|
8
|
+
element.style.lineHeight = String(lineHeight) + 'px';
|
|
9
|
+
element.style.fontWeight = String(weight);
|
|
10
|
+
segments.forEach(segment => {
|
|
11
|
+
const span = createElement(element.ownerDocument, 'span', undefined, segment.text);
|
|
12
|
+
if (segment.style === 'subscript') {
|
|
13
|
+
span.dataset.nlSegment = 'subscript';
|
|
14
|
+
applySubscriptMetrics(span, fontSize);
|
|
15
|
+
}
|
|
16
|
+
element.appendChild(span);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
// Legacy subscript metrics: 60% of the field size on a field-size line box.
|
|
20
|
+
function applySubscriptMetrics(span, fontSize) {
|
|
21
|
+
span.style.fontSize = String(Math.ceil(fontSize * 0.6)) + 'px';
|
|
22
|
+
span.style.lineHeight = String(fontSize) + 'px';
|
|
23
|
+
}
|
|
24
|
+
export function applyTextLayout(element, style, defaultLines) {
|
|
25
|
+
if (style.lines === undefined && style.truncate === undefined && style.verticalAlignment === undefined && style.offsetY === undefined && defaultLines === undefined) return;
|
|
26
|
+
let content = element.querySelector(':scope > .ok-native-list-text-content');
|
|
27
|
+
// Line clamps are only ever written inline by templates (no stylesheet rule
|
|
28
|
+
// sets them), so no computed-style read is needed; this also keeps the result
|
|
29
|
+
// identical for attached and detached rows.
|
|
30
|
+
const inheritedClamp = Number(element.style.getPropertyValue('-webkit-line-clamp'));
|
|
31
|
+
const lines = style.lines ?? defaultLines ?? (inheritedClamp || 1);
|
|
32
|
+
if (!content && (style.verticalAlignment !== undefined || style.offsetY !== undefined || element.classList.contains('ok-native-list-market-change'))) {
|
|
33
|
+
content = element.ownerDocument.createElement('span');
|
|
34
|
+
content.className = 'ok-native-list-text-content';
|
|
35
|
+
content.append(...Array.from(element.childNodes));
|
|
36
|
+
element.appendChild(content);
|
|
37
|
+
element.style.display = 'flex';
|
|
38
|
+
element.style.flexDirection = 'column';
|
|
39
|
+
element.style.removeProperty('-webkit-line-clamp');
|
|
40
|
+
element.style.removeProperty('-webkit-box-orient');
|
|
41
|
+
content.style.minWidth = '0';
|
|
42
|
+
content.style.flex = '0 1 auto';
|
|
43
|
+
content.style.width = '100%';
|
|
44
|
+
}
|
|
45
|
+
const text = content ?? element;
|
|
46
|
+
if (style.verticalAlignment !== undefined) {
|
|
47
|
+
element.style.justifyContent = {
|
|
48
|
+
top: 'flex-start',
|
|
49
|
+
center: 'center',
|
|
50
|
+
bottom: 'flex-end'
|
|
51
|
+
}[style.verticalAlignment];
|
|
52
|
+
}
|
|
53
|
+
if (style.offsetY !== undefined) text.style.transform = `translateY(${style.offsetY}px)`;
|
|
54
|
+
if (style.lines === undefined && style.truncate === undefined && defaultLines === undefined && !inheritedClamp) {
|
|
55
|
+
if (content) {
|
|
56
|
+
// Inherit the slot's resolved wrapping/truncation from CSS or inline style.
|
|
57
|
+
content.style.whiteSpace = 'inherit';
|
|
58
|
+
content.style.textOverflow = 'inherit';
|
|
59
|
+
content.style.overflow = 'hidden';
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (lines === 1) {
|
|
64
|
+
const walker = element.ownerDocument.createTreeWalker(text, 4 /* SHOW_TEXT */);
|
|
65
|
+
let previousCarriageReturn = false;
|
|
66
|
+
while (walker.nextNode()) {
|
|
67
|
+
const value = walker.currentNode.nodeValue ?? '';
|
|
68
|
+
if (!value) continue;
|
|
69
|
+
// A CRLF pair may straddle two styled runs.
|
|
70
|
+
const textValue = previousCarriageReturn && value.startsWith('\n') ? value.slice(1) : value;
|
|
71
|
+
walker.currentNode.nodeValue = textValue.replace(/\r\n|[\r\n]/g, ' ');
|
|
72
|
+
previousCarriageReturn = value.endsWith('\r');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
text.style.whiteSpace = lines === 1 ? 'nowrap' : 'pre-wrap';
|
|
76
|
+
text.style.overflow = 'hidden';
|
|
77
|
+
text.style.textOverflow = style.truncate === 'clip' ? 'clip' : 'ellipsis';
|
|
78
|
+
text.style.removeProperty('-webkit-line-clamp');
|
|
79
|
+
text.style.removeProperty('-webkit-box-orient');
|
|
80
|
+
text.style.maxHeight = '';
|
|
81
|
+
if (lines > 1 && style.truncate !== 'clip') {
|
|
82
|
+
text.style.display = '-webkit-box';
|
|
83
|
+
text.style.setProperty('-webkit-line-clamp', String(lines));
|
|
84
|
+
text.style.setProperty('-webkit-box-orient', 'vertical');
|
|
85
|
+
} else {
|
|
86
|
+
text.style.display = 'block';
|
|
87
|
+
if (lines > 1) {
|
|
88
|
+
// Rows are styled before mounting, when computed typography is unavailable.
|
|
89
|
+
// Resolve omitted line height in CSS after the template rules take effect.
|
|
90
|
+
text.style.maxHeight = style.lineHeight !== undefined ? `${lines * style.lineHeight}px` : `${lines}lh`;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export function applyTextStyleToSlot(element, style, defaultLines) {
|
|
95
|
+
if (style.fontSize !== undefined) element.style.fontSize = String(style.fontSize) + 'px';
|
|
96
|
+
if (style.lineHeight !== undefined) element.style.lineHeight = String(style.lineHeight) + 'px';
|
|
97
|
+
if (style.fontWeight !== undefined) element.style.fontWeight = String(fontWeight(style.fontWeight, 400));
|
|
98
|
+
if (style.color !== undefined) element.style.color = style.color;
|
|
99
|
+
// Explicit overrides also apply to rich text runs, but never to sibling badges.
|
|
100
|
+
// Subscript segments keep their legacy size relative to the field size.
|
|
101
|
+
element.querySelectorAll('span').forEach(run => {
|
|
102
|
+
const subscript = run.dataset.nlSegment === 'subscript';
|
|
103
|
+
if (style.color !== undefined) run.style.color = style.color;
|
|
104
|
+
if (style.fontSize !== undefined) {
|
|
105
|
+
if (subscript) applySubscriptMetrics(run, style.fontSize);else run.style.fontSize = String(style.fontSize) + 'px';
|
|
106
|
+
}
|
|
107
|
+
if (style.fontWeight !== undefined) run.style.fontWeight = String(fontWeight(style.fontWeight, 400));
|
|
108
|
+
if (style.lineHeight !== undefined && !subscript) run.style.lineHeight = String(style.lineHeight) + 'px';
|
|
109
|
+
if (style.lines !== undefined || style.truncate !== undefined) run.style.whiteSpace = 'inherit';
|
|
110
|
+
});
|
|
111
|
+
if (style.alignment !== undefined) element.style.textAlign = style.alignment;
|
|
112
|
+
applyTextLayout(element, style, defaultLines);
|
|
113
|
+
}
|
|
114
|
+
export function fontWeight(value, fallback) {
|
|
115
|
+
if (value === 'bold') return 700;
|
|
116
|
+
if (value === 'semibold') return 600;
|
|
117
|
+
if (value === 'medium') return 500;
|
|
118
|
+
if (value === 'regular') return 400;
|
|
119
|
+
return fallback;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=RowText.js.map
|