@lukso/transaction-view-core 0.3.1-dev.a8c9315
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/.turbo/turbo-build.log +33 -0
- package/CHANGELOG.md +104 -0
- package/LICENSE +201 -0
- package/README.md +264 -0
- package/dist/index.cjs +4573 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +493 -0
- package/dist/index.d.ts +493 -0
- package/dist/index.js +4534 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/index.cjs +2480 -0
- package/dist/shared/index.cjs.map +1 -0
- package/dist/shared/index.d.cts +887 -0
- package/dist/shared/index.d.ts +887 -0
- package/dist/shared/index.js +2437 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/styles/index.cjs +58 -0
- package/dist/styles/index.cjs.map +1 -0
- package/dist/styles/index.d.cts +9 -0
- package/dist/styles/index.d.ts +9 -0
- package/dist/styles/index.js +31 -0
- package/dist/styles/index.js.map +1 -0
- package/package.json +57 -0
- package/publish.log +0 -0
- package/src/components/asset-card.ts +426 -0
- package/src/components/contract-card.ts +238 -0
- package/src/components/description-view.ts +605 -0
- package/src/components/index.ts +20 -0
- package/src/components/info-panel.ts +437 -0
- package/src/components/permissions-block.ts +138 -0
- package/src/components/transaction-playback.ts +429 -0
- package/src/components/universal-token-view.ts +281 -0
- package/src/declaration.d.ts +4 -0
- package/src/examples/INTEGRATION_GUIDE.md +240 -0
- package/src/examples/TransactionContentWithReplacement.vue +269 -0
- package/src/index.ts +38 -0
- package/src/registry/index.ts +31 -0
- package/src/registry/lit-view-loader.ts +191 -0
- package/src/shared/address-display.ts +370 -0
- package/src/shared/address-view.ts +385 -0
- package/src/shared/custom-select.ts +164 -0
- package/src/shared/function-name-view.ts +89 -0
- package/src/shared/gas-provider-view.ts +218 -0
- package/src/shared/icon-view.ts +288 -0
- package/src/shared/image-list.ts +261 -0
- package/src/shared/image-loader-controller.ts +160 -0
- package/src/shared/index.ts +34 -0
- package/src/shared/load-web-components.ts +56 -0
- package/src/shared/notification-view.ts +132 -0
- package/src/shared/progress-view.ts +86 -0
- package/src/shared/safe-custom-element.ts +35 -0
- package/src/shared/scroll-to-bottom-button.ts +55 -0
- package/src/shared/signal-controller.ts +124 -0
- package/src/shared/transaction-view-controller.ts +345 -0
- package/src/shared/url-view.ts +129 -0
- package/src/shared/value-view.ts +510 -0
- package/src/styles/index.ts +28 -0
- package/src/styles/styles.css +1 -0
- package/src/vue-entry.ts +15 -0
- package/tailwind.config.cjs +9 -0
- package/tsconfig.json +22 -0
- package/tsup.config.ts +90 -0
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
import { css, html, LitElement } from 'lit'
|
|
2
|
+
import { property } from 'lit/decorators.js'
|
|
3
|
+
import { repeat } from 'lit/directives/repeat.js'
|
|
4
|
+
import { when } from 'lit/directives/when.js'
|
|
5
|
+
import { safeCustomElement } from '../shared/safe-custom-element'
|
|
6
|
+
|
|
7
|
+
// Import the EnhancedInfo type from the decoder package
|
|
8
|
+
type EnhancedInfo = {
|
|
9
|
+
address: `0x${string}`
|
|
10
|
+
standard?: string
|
|
11
|
+
tokenId?: `0x${string}`
|
|
12
|
+
name?: string
|
|
13
|
+
__gqltype?: 'Profile' | 'Asset' | 'Token'
|
|
14
|
+
[key: string]: unknown
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface TransactionInfo {
|
|
18
|
+
/** Transaction hash */
|
|
19
|
+
hash?: string
|
|
20
|
+
/** Block number */
|
|
21
|
+
blockNumber?: bigint | string
|
|
22
|
+
/** Block timestamp */
|
|
23
|
+
timestamp?: bigint | string | Date
|
|
24
|
+
/** Gas used */
|
|
25
|
+
gasUsed?: bigint | string
|
|
26
|
+
/** Gas price */
|
|
27
|
+
gasPrice?: bigint | string
|
|
28
|
+
/** Transaction status */
|
|
29
|
+
status?: 'success' | 'failed' | 'pending'
|
|
30
|
+
/** Network/chain name */
|
|
31
|
+
network?: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface DescriptionItem {
|
|
35
|
+
/** Label for the description item */
|
|
36
|
+
label: string
|
|
37
|
+
/** Value to display */
|
|
38
|
+
value: string
|
|
39
|
+
/** Optional secondary value or subtitle */
|
|
40
|
+
subtitle?: string
|
|
41
|
+
/** Whether this item is highlighted */
|
|
42
|
+
highlighted?: boolean
|
|
43
|
+
/** Whether to show copy button */
|
|
44
|
+
copyable?: boolean
|
|
45
|
+
/** Custom icon for this item */
|
|
46
|
+
icon?: string
|
|
47
|
+
/** Link URL if this item should be clickable */
|
|
48
|
+
link?: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface DescriptionViewData {
|
|
52
|
+
/** Main title/heading */
|
|
53
|
+
title?: string
|
|
54
|
+
/** Main description text */
|
|
55
|
+
description?: string
|
|
56
|
+
/** Address key (format: "ADDRESS" or "ADDRESS-TOKENID") */
|
|
57
|
+
address?: string
|
|
58
|
+
/** Value being transferred */
|
|
59
|
+
value?: bigint | string
|
|
60
|
+
/** Raw transaction object */
|
|
61
|
+
transaction?: any // DecoderResult type from decoder package
|
|
62
|
+
/** Enhanced info from decoder (contains metadata) */
|
|
63
|
+
enhancedInfo?: EnhancedInfo
|
|
64
|
+
/** Transaction-specific information */
|
|
65
|
+
transactionInfo?: TransactionInfo
|
|
66
|
+
/** Additional custom items to display */
|
|
67
|
+
customItems?: DescriptionItem[]
|
|
68
|
+
/** Transaction type for styling */
|
|
69
|
+
type?: 'transfer' | 'mint' | 'burn' | 'approve' | 'execute' | 'deploy'
|
|
70
|
+
/** Loading state */
|
|
71
|
+
loading?: boolean
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Description view component for displaying transaction details and metadata
|
|
76
|
+
* Provides flexible key-value display with support for various transaction types
|
|
77
|
+
*/
|
|
78
|
+
@safeCustomElement('description-view')
|
|
79
|
+
export class DescriptionView extends LitElement {
|
|
80
|
+
@property({ type: Object })
|
|
81
|
+
data: DescriptionViewData = {}
|
|
82
|
+
|
|
83
|
+
@property({ type: String })
|
|
84
|
+
variant: 'default' | 'compact' | 'detailed' = 'default'
|
|
85
|
+
|
|
86
|
+
static styles = css`
|
|
87
|
+
:host {
|
|
88
|
+
display: block;
|
|
89
|
+
font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.description-container {
|
|
93
|
+
background: white;
|
|
94
|
+
border-radius: 12px;
|
|
95
|
+
padding: 16px;
|
|
96
|
+
border: 1px solid #e5e7eb;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.compact .description-container {
|
|
100
|
+
padding: 12px;
|
|
101
|
+
border-radius: 8px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.detailed .description-container {
|
|
105
|
+
padding: 20px;
|
|
106
|
+
border-radius: 16px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.header {
|
|
110
|
+
margin-bottom: 16px;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.compact .header {
|
|
114
|
+
margin-bottom: 12px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.detailed .header {
|
|
118
|
+
margin-bottom: 20px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.title {
|
|
122
|
+
font-size: 16px;
|
|
123
|
+
font-weight: 600;
|
|
124
|
+
color: #111827;
|
|
125
|
+
margin: 0 0 8px 0;
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
gap: 8px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.compact .title {
|
|
132
|
+
font-size: 14px;
|
|
133
|
+
margin-bottom: 6px;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.detailed .title {
|
|
137
|
+
font-size: 18px;
|
|
138
|
+
margin-bottom: 12px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.type-badge {
|
|
142
|
+
display: inline-flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
padding: 4px 8px;
|
|
145
|
+
border-radius: 12px;
|
|
146
|
+
font-size: 11px;
|
|
147
|
+
font-weight: 600;
|
|
148
|
+
text-transform: uppercase;
|
|
149
|
+
letter-spacing: 0.5px;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.type-badge.transfer {
|
|
153
|
+
background: #dbeafe;
|
|
154
|
+
color: #1d4ed8;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.type-badge.mint {
|
|
158
|
+
background: #d1fae5;
|
|
159
|
+
color: #059669;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.type-badge.burn {
|
|
163
|
+
background: #fee2e2;
|
|
164
|
+
color: #dc2626;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.type-badge.approve {
|
|
168
|
+
background: #fef3c7;
|
|
169
|
+
color: #d97706;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.type-badge.execute {
|
|
173
|
+
background: #e0e7ff;
|
|
174
|
+
color: #4338ca;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.type-badge.deploy {
|
|
178
|
+
background: #f3e8ff;
|
|
179
|
+
color: #7c3aed;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.description {
|
|
183
|
+
font-size: 14px;
|
|
184
|
+
line-height: 1.5;
|
|
185
|
+
color: #6b7280;
|
|
186
|
+
margin: 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.compact .description {
|
|
190
|
+
font-size: 13px;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.detailed .description {
|
|
194
|
+
font-size: 15px;
|
|
195
|
+
line-height: 1.6;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.items-list {
|
|
199
|
+
display: flex;
|
|
200
|
+
flex-direction: column;
|
|
201
|
+
gap: 12px;
|
|
202
|
+
margin-top: 16px;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.compact .items-list {
|
|
206
|
+
gap: 8px;
|
|
207
|
+
margin-top: 12px;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.detailed .items-list {
|
|
211
|
+
gap: 16px;
|
|
212
|
+
margin-top: 20px;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.description-item {
|
|
216
|
+
display: flex;
|
|
217
|
+
justify-content: space-between;
|
|
218
|
+
align-items: flex-start;
|
|
219
|
+
padding: 12px;
|
|
220
|
+
background: #f9fafb;
|
|
221
|
+
border-radius: 8px;
|
|
222
|
+
border: 1px solid #e5e7eb;
|
|
223
|
+
transition: all 0.2s ease;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.compact .description-item {
|
|
227
|
+
padding: 8px;
|
|
228
|
+
border-radius: 6px;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.detailed .description-item {
|
|
232
|
+
padding: 16px;
|
|
233
|
+
border-radius: 12px;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.description-item.highlighted {
|
|
237
|
+
background: #eff6ff;
|
|
238
|
+
border-color: #3b82f6;
|
|
239
|
+
box-shadow: 0 0 0 1px rgba(59, 130, 246, 0.1);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.description-item.clickable {
|
|
243
|
+
cursor: pointer;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.description-item.clickable:hover {
|
|
247
|
+
background: #f3f4f6;
|
|
248
|
+
border-color: #d1d5db;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.description-item.highlighted.clickable:hover {
|
|
252
|
+
background: #dbeafe;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.item-label {
|
|
256
|
+
display: flex;
|
|
257
|
+
align-items: center;
|
|
258
|
+
gap: 8px;
|
|
259
|
+
font-size: 13px;
|
|
260
|
+
font-weight: 500;
|
|
261
|
+
color: #374151;
|
|
262
|
+
flex-shrink: 0;
|
|
263
|
+
min-width: 0;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.compact .item-label {
|
|
267
|
+
font-size: 12px;
|
|
268
|
+
gap: 6px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.detailed .item-label {
|
|
272
|
+
font-size: 14px;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.item-icon {
|
|
276
|
+
font-size: 14px;
|
|
277
|
+
flex-shrink: 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.item-value-section {
|
|
281
|
+
display: flex;
|
|
282
|
+
flex-direction: column;
|
|
283
|
+
align-items: flex-end;
|
|
284
|
+
gap: 4px;
|
|
285
|
+
min-width: 0;
|
|
286
|
+
flex: 1;
|
|
287
|
+
margin-left: 12px;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.item-value {
|
|
291
|
+
font-size: 14px;
|
|
292
|
+
font-weight: 500;
|
|
293
|
+
color: #111827;
|
|
294
|
+
word-break: break-all;
|
|
295
|
+
text-align: right;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.compact .item-value {
|
|
299
|
+
font-size: 13px;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.detailed .item-value {
|
|
303
|
+
font-size: 15px;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.item-subtitle {
|
|
307
|
+
font-size: 12px;
|
|
308
|
+
color: #6b7280;
|
|
309
|
+
text-align: right;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.compact .item-subtitle {
|
|
313
|
+
font-size: 11px;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.item-actions {
|
|
317
|
+
display: flex;
|
|
318
|
+
align-items: center;
|
|
319
|
+
gap: 4px;
|
|
320
|
+
margin-left: 8px;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.copy-button {
|
|
324
|
+
background: none;
|
|
325
|
+
border: none;
|
|
326
|
+
cursor: pointer;
|
|
327
|
+
padding: 4px;
|
|
328
|
+
border-radius: 4px;
|
|
329
|
+
color: #6b7280;
|
|
330
|
+
transition: all 0.2s ease;
|
|
331
|
+
font-size: 14px;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.copy-button:hover {
|
|
335
|
+
background-color: #e5e7eb;
|
|
336
|
+
color: #374151;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.external-link {
|
|
340
|
+
color: #3b82f6;
|
|
341
|
+
text-decoration: none;
|
|
342
|
+
font-size: 14px;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.external-link:hover {
|
|
346
|
+
text-decoration: underline;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.loading-state {
|
|
350
|
+
display: flex;
|
|
351
|
+
flex-direction: column;
|
|
352
|
+
align-items: center;
|
|
353
|
+
justify-content: center;
|
|
354
|
+
padding: 40px 20px;
|
|
355
|
+
color: #6b7280;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.loading-spinner {
|
|
359
|
+
font-size: 24px;
|
|
360
|
+
margin-bottom: 12px;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.loading-text {
|
|
364
|
+
font-size: 14px;
|
|
365
|
+
}
|
|
366
|
+
`
|
|
367
|
+
|
|
368
|
+
private _copyToClipboard(text: string) {
|
|
369
|
+
if (navigator.clipboard) {
|
|
370
|
+
navigator.clipboard.writeText(text)
|
|
371
|
+
this.dispatchEvent(
|
|
372
|
+
new CustomEvent('copied', {
|
|
373
|
+
detail: { text },
|
|
374
|
+
})
|
|
375
|
+
)
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
private _handleItemClick(item: DescriptionItem) {
|
|
380
|
+
if (item.link) {
|
|
381
|
+
window.open(item.link, '_blank', 'noopener,noreferrer')
|
|
382
|
+
}
|
|
383
|
+
this.dispatchEvent(
|
|
384
|
+
new CustomEvent('item-click', {
|
|
385
|
+
detail: { item },
|
|
386
|
+
})
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
private _renderHeader() {
|
|
391
|
+
if (!this.data.title && !this.data.description && !this.data.type) return ''
|
|
392
|
+
|
|
393
|
+
return html`
|
|
394
|
+
<div class="header">
|
|
395
|
+
${when(
|
|
396
|
+
this.data.title,
|
|
397
|
+
() => html`
|
|
398
|
+
<h2 class="title">
|
|
399
|
+
${this.data.title}
|
|
400
|
+
${when(
|
|
401
|
+
this.data.type,
|
|
402
|
+
() => html`
|
|
403
|
+
<span class="type-badge ${this.data.type}">
|
|
404
|
+
${this.data.type}
|
|
405
|
+
</span>
|
|
406
|
+
`
|
|
407
|
+
)}
|
|
408
|
+
</h2>
|
|
409
|
+
`
|
|
410
|
+
)}
|
|
411
|
+
|
|
412
|
+
${when(
|
|
413
|
+
this.data.description,
|
|
414
|
+
() => html`
|
|
415
|
+
<p class="description">${this.data.description}</p>
|
|
416
|
+
`
|
|
417
|
+
)}
|
|
418
|
+
</div>
|
|
419
|
+
`
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
private _renderItems() {
|
|
423
|
+
// Build items from various data sources
|
|
424
|
+
const items: DescriptionItem[] = []
|
|
425
|
+
|
|
426
|
+
// Add address information
|
|
427
|
+
if (this.data.address) {
|
|
428
|
+
const [contractAddress, tokenId] = this.data.address.split('-')
|
|
429
|
+
|
|
430
|
+
items.push({
|
|
431
|
+
label: 'Contract Address',
|
|
432
|
+
value: contractAddress,
|
|
433
|
+
icon: '📄',
|
|
434
|
+
copyable: true,
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
if (tokenId) {
|
|
438
|
+
items.push({
|
|
439
|
+
label: 'Token ID',
|
|
440
|
+
value: `#${tokenId}`,
|
|
441
|
+
subtitle: tokenId,
|
|
442
|
+
icon: '🏷️',
|
|
443
|
+
copyable: true,
|
|
444
|
+
})
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Add value information
|
|
449
|
+
if (this.data.value) {
|
|
450
|
+
items.push({
|
|
451
|
+
label: 'Amount',
|
|
452
|
+
value: this.data.value.toString(),
|
|
453
|
+
icon: '💰',
|
|
454
|
+
highlighted: true,
|
|
455
|
+
})
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Add transaction information
|
|
459
|
+
if (this.data.transactionInfo) {
|
|
460
|
+
const txInfo = this.data.transactionInfo
|
|
461
|
+
|
|
462
|
+
if (txInfo.hash) {
|
|
463
|
+
items.push({
|
|
464
|
+
label: 'Transaction Hash',
|
|
465
|
+
value: txInfo.hash,
|
|
466
|
+
icon: '🔗',
|
|
467
|
+
copyable: true,
|
|
468
|
+
})
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (txInfo.blockNumber) {
|
|
472
|
+
items.push({
|
|
473
|
+
label: 'Block Number',
|
|
474
|
+
value: txInfo.blockNumber.toString(),
|
|
475
|
+
icon: '🧱',
|
|
476
|
+
})
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (txInfo.status) {
|
|
480
|
+
items.push({
|
|
481
|
+
label: 'Status',
|
|
482
|
+
value: txInfo.status.charAt(0).toUpperCase() + txInfo.status.slice(1),
|
|
483
|
+
icon:
|
|
484
|
+
txInfo.status === 'success'
|
|
485
|
+
? '✅'
|
|
486
|
+
: txInfo.status === 'failed'
|
|
487
|
+
? '❌'
|
|
488
|
+
: '⏳',
|
|
489
|
+
highlighted: txInfo.status !== 'success',
|
|
490
|
+
})
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Add enhanced info metadata
|
|
495
|
+
if (this.data.enhancedInfo) {
|
|
496
|
+
const info = this.data.enhancedInfo
|
|
497
|
+
|
|
498
|
+
if (info.name) {
|
|
499
|
+
items.push({
|
|
500
|
+
label: 'Asset Name',
|
|
501
|
+
value: info.name,
|
|
502
|
+
icon: '🏷️',
|
|
503
|
+
})
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (info.standard) {
|
|
507
|
+
items.push({
|
|
508
|
+
label: 'Standard',
|
|
509
|
+
value: info.standard,
|
|
510
|
+
icon: '📋',
|
|
511
|
+
})
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Add custom items
|
|
516
|
+
if (this.data.customItems?.length) {
|
|
517
|
+
items.push(...this.data.customItems)
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if (!items.length) return ''
|
|
521
|
+
|
|
522
|
+
return html`
|
|
523
|
+
<div class="items-list">
|
|
524
|
+
${repeat(
|
|
525
|
+
items,
|
|
526
|
+
(item) => `${item.label}-${item.value}`,
|
|
527
|
+
(item) => html`
|
|
528
|
+
<div
|
|
529
|
+
class="description-item ${item.highlighted ? 'highlighted' : ''} ${item.link ? 'clickable' : ''}"
|
|
530
|
+
@click=${item.link ? () => this._handleItemClick(item) : undefined}
|
|
531
|
+
>
|
|
532
|
+
<div class="item-label">
|
|
533
|
+
${when(
|
|
534
|
+
item.icon,
|
|
535
|
+
() => html`<span class="item-icon">${item.icon}</span>`
|
|
536
|
+
)}
|
|
537
|
+
${item.label}
|
|
538
|
+
</div>
|
|
539
|
+
|
|
540
|
+
<div class="item-value-section">
|
|
541
|
+
<div class="item-value">
|
|
542
|
+
${
|
|
543
|
+
item.link
|
|
544
|
+
? html`<a class="external-link" href="${item.link}" target="_blank" rel="noopener noreferrer">${item.value}</a>`
|
|
545
|
+
: item.value
|
|
546
|
+
}
|
|
547
|
+
</div>
|
|
548
|
+
${when(
|
|
549
|
+
item.subtitle,
|
|
550
|
+
() => html`<div class="item-subtitle">${item.subtitle}</div>`
|
|
551
|
+
)}
|
|
552
|
+
</div>
|
|
553
|
+
|
|
554
|
+
<div class="item-actions">
|
|
555
|
+
${when(
|
|
556
|
+
item.copyable,
|
|
557
|
+
() => html`
|
|
558
|
+
<button
|
|
559
|
+
class="copy-button"
|
|
560
|
+
@click=${(e: Event) => {
|
|
561
|
+
e.stopPropagation()
|
|
562
|
+
this._copyToClipboard(item.value)
|
|
563
|
+
}}
|
|
564
|
+
title="Copy to clipboard"
|
|
565
|
+
>
|
|
566
|
+
📋
|
|
567
|
+
</button>
|
|
568
|
+
`
|
|
569
|
+
)}
|
|
570
|
+
</div>
|
|
571
|
+
</div>
|
|
572
|
+
`
|
|
573
|
+
)}
|
|
574
|
+
</div>
|
|
575
|
+
`
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
render() {
|
|
579
|
+
if (this.data.loading) {
|
|
580
|
+
return html`
|
|
581
|
+
<div class="description-container">
|
|
582
|
+
<div class="loading-state">
|
|
583
|
+
<div class="loading-spinner">⏳</div>
|
|
584
|
+
<div class="loading-text">Loading details...</div>
|
|
585
|
+
</div>
|
|
586
|
+
</div>
|
|
587
|
+
`
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
return html`
|
|
591
|
+
<div class="${this.variant} description-view">
|
|
592
|
+
<div class="description-container">
|
|
593
|
+
${this._renderHeader()}
|
|
594
|
+
${this._renderItems()}
|
|
595
|
+
</div>
|
|
596
|
+
</div>
|
|
597
|
+
`
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
declare global {
|
|
602
|
+
interface HTMLElementTagNameMap {
|
|
603
|
+
'description-view': DescriptionView
|
|
604
|
+
}
|
|
605
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Components index - imports all components to ensure they are registered as custom elements
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Import all Lit components to ensure they are defined as custom elements
|
|
6
|
+
import './universal-token-view.js'
|
|
7
|
+
import './asset-card.js'
|
|
8
|
+
import './info-panel.js'
|
|
9
|
+
import './description-view.js'
|
|
10
|
+
import './contract-card.js'
|
|
11
|
+
import './transaction-playback.js'
|
|
12
|
+
import './permissions-block.js'
|
|
13
|
+
|
|
14
|
+
// Import shared components
|
|
15
|
+
import '../shared/address-display.js'
|
|
16
|
+
import '../shared/address-view.js'
|
|
17
|
+
import '../shared/value-view.js'
|
|
18
|
+
|
|
19
|
+
// This file is imported dynamically to ensure all web components are registered
|
|
20
|
+
// when the transaction view system is initialized
|