@onekeyfe/react-native-native-list 6.7.0-alpha.412 → 6.7.0-alpha.413
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/NativeListAccessoryStack.kt +0 -5
- package/android/src/main/java/com/onekey/nativelist/NativeListLeadingVisual.kt +0 -5
- package/android/src/main/java/com/onekey/nativelist/NativeListPrimitives.kt +338 -117
- package/android/src/main/java/com/onekey/nativelist/NativeListRendererRowView.kt +0 -5
- package/docs/SPEC.md +7 -114
- package/ios/NativeListAccessoryStack.swift +16 -6
- package/ios/NativeListDataRowRenderer.swift +6 -15
- package/ios/NativeListDesignAssets.swift +84 -13
- package/ios/NativeListIdentityRenderer.swift +10 -12
- package/ios/NativeListLeadingVisual.swift +9 -11
- package/ios/NativeListMarketRenderer.swift +13 -7
- package/ios/NativeListMediaTileRenderer.swift +2 -6
- package/ios/NativeListMetricCardRenderer.swift +2 -4
- package/ios/NativeListSectionHeaderRenderer.swift +4 -12
- package/ios/Resources/NativeListIcons.xcassets/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_bottom.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_bottom.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_top.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_top.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_badge_verified_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_badge_verified_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chart_trending_up.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chart_trending_up.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_checked.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_checked.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_indeterminate.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_indeterminate.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_bottom.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_bottom.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_grabber_ver.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_grabber_ver.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_right_small.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_right_small.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_top.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_top.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_crypto_coin_outline.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_crypto_coin_outline.imageset/icon.svg +4 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_document2.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_document2.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_dot_hor.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_dot_hor.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_dot_ver_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_dot_ver_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_drag.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_drag.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_error_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_error_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_gas_solid.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_gas_solid.imageset/icon.svg +3 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_image_square_waves.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_image_square_waves.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_info_circle.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_info_circle.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_pencil.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_pencil.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_circle.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_circle.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_large.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_large.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_small.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_small.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_questionmark_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_questionmark_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_refresh_ccw_outline.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_refresh_ccw_outline.imageset/icon.svg +3 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_account_error_custom.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_account_error_custom.imageset/icon.svg +14 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_all_networks_solid.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_all_networks_solid.imageset/icon.svg +12 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_apple_brand.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_apple_brand.imageset/icon.svg +6 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_bot_illus.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_bot_illus.imageset/icon.svg +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_crossed_small_solid.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_crossed_small_solid.imageset/icon.svg +3 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_globus_outline.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_globus_outline.imageset/icon.svg +7 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_google_illus.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_google_illus.imageset/icon.svg +18 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_lock_solid.imageset/Contents.json +15 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_selector_lock_solid.imageset/icon.svg +7 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_shield_exclamation.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_shield_exclamation.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_speaker_promote.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_speaker_promote.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_star.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_star.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_star_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_star_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_swap_hor.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_swap_hor.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_ticket.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_ticket.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_wallet.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_wallet.imageset/icon.svg +1 -0
- package/ios/tests/NativeListAccessoryStackTests.swift +0 -12
- package/lib/module/web/NativeListWebEngine.js +323 -21
- package/lib/module/web/templates/ActivityRowRenderer.js +24 -4
- package/lib/module/web/templates/MarketTableRowRenderer.js +15 -11
- package/lib/module/web/templates/MediaTileRowRenderer.js +12 -2
- package/lib/typescript/src/web/NativeListWebEngine.d.ts +1 -0
- package/package.json +4 -10
- package/react-native-native-list.podspec +5 -0
- package/src/web/NativeListWebEngine.ts +405 -25
- package/src/web/templates/ActivityRowRenderer.ts +53 -15
- package/src/web/templates/MarketTableRowRenderer.ts +29 -17
- package/src/web/templates/MediaTileRowRenderer.ts +15 -2
- package/android/src/main/java/com/onekey/nativelist/NativeListGeneratedIcons.kt +0 -47
- package/ios/NativeListGeneratedIcons.swift +0 -55
- package/ios/NativeListIconBinding.swift +0 -171
- package/ios/tests/NativeListSharedIconTests.swift +0 -236
- package/lib/module/web/NativeListGeneratedIcons.js +0 -31
- package/lib/typescript/src/web/NativeListGeneratedIcons.d.ts +0 -2
- package/scripts/generate-icons.mjs +0 -150
- package/scripts/generate-icons.test.mjs +0 -288
- package/scripts/native-list-icons.json +0 -260
- package/src/web/NativeListGeneratedIcons.ts +0 -28
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import crypto from 'node:crypto';
|
|
4
|
-
import { createRequire } from 'node:module';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
7
|
-
const require = createRequire(import.meta.url);
|
|
8
|
-
const prettier = require('prettier');
|
|
9
|
-
const format = JSON.parse(
|
|
10
|
-
fs.readFileSync(path.join(root, 'package.json'), 'utf8')
|
|
11
|
-
).prettier;
|
|
12
|
-
const header =
|
|
13
|
-
'// Generated by scripts/generate-icons.mjs. Coverage and legacy names only; hosts provide SVG resources.\n';
|
|
14
|
-
export function generateOutputs(
|
|
15
|
-
fixtureRoot = path.resolve(
|
|
16
|
-
root,
|
|
17
|
-
'../../example/react-native/icon-fixtures/native/icons'
|
|
18
|
-
),
|
|
19
|
-
outputRoot = root
|
|
20
|
-
) {
|
|
21
|
-
const entries = JSON.parse(
|
|
22
|
-
fs.readFileSync(path.join(root, 'scripts/native-list-icons.json'), 'utf8')
|
|
23
|
-
);
|
|
24
|
-
const catalog = JSON.parse(
|
|
25
|
-
fs.readFileSync(path.join(fixtureRoot, 'manifest.json'), 'utf8')
|
|
26
|
-
);
|
|
27
|
-
const records = resolveRecords(entries, catalog, fixtureRoot);
|
|
28
|
-
return renderOutputs(records, outputRoot);
|
|
29
|
-
}
|
|
30
|
-
export function resolveRecords(entries, catalog, fixtureRoot) {
|
|
31
|
-
const names = new Set();
|
|
32
|
-
if (!Array.isArray(entries)) throw new Error('Invalid icon manifest');
|
|
33
|
-
return entries
|
|
34
|
-
.map((entry) => {
|
|
35
|
-
if (
|
|
36
|
-
!entry ||
|
|
37
|
-
typeof entry.name !== 'string' ||
|
|
38
|
-
!/^[A-Z][A-Za-z0-9]*$/.test(entry.name) ||
|
|
39
|
-
names.has(entry.name) ||
|
|
40
|
-
!Array.isArray(entry.platforms) ||
|
|
41
|
-
!entry.platforms.length ||
|
|
42
|
-
new Set(entry.platforms).size !== entry.platforms.length ||
|
|
43
|
-
entry.platforms.some((p) => !['ios', 'android', 'web'].includes(p)) ||
|
|
44
|
-
!['template', 'original', 'primitive'].includes(entry.rendering)
|
|
45
|
-
)
|
|
46
|
-
throw new Error('Invalid icon manifest entry');
|
|
47
|
-
names.add(entry.name);
|
|
48
|
-
if (entry.name === 'Circle')
|
|
49
|
-
return { ...entry, canonical: 'Circle', width: 24, height: 24 };
|
|
50
|
-
if (
|
|
51
|
-
typeof entry.source !== 'string' ||
|
|
52
|
-
entry.source.includes('..') ||
|
|
53
|
-
path.isAbsolute(entry.source)
|
|
54
|
-
)
|
|
55
|
-
throw new Error('Invalid icon manifest entry');
|
|
56
|
-
const matches = Object.entries(catalog).filter(
|
|
57
|
-
([, value]) => value.source === entry.source
|
|
58
|
-
);
|
|
59
|
-
if (matches.length > 1)
|
|
60
|
-
throw new Error(`Ambiguous shared SVG source: ${entry.source}`);
|
|
61
|
-
const match = matches[0];
|
|
62
|
-
if (!match) throw new Error(`Missing shared SVG source: ${entry.source}`);
|
|
63
|
-
const [canonical, metadata] = match;
|
|
64
|
-
const source = fs.readFileSync(
|
|
65
|
-
path.join(fixtureRoot, `${canonical}.svg`),
|
|
66
|
-
'utf8'
|
|
67
|
-
);
|
|
68
|
-
const raw = source.endsWith('\n') ? source : source + '\n';
|
|
69
|
-
if (
|
|
70
|
-
crypto.createHash('sha256').update(raw).digest('hex') !==
|
|
71
|
-
metadata.digest
|
|
72
|
-
)
|
|
73
|
-
throw new Error(`Shared SVG resources stale: ${entry.source}`);
|
|
74
|
-
return {
|
|
75
|
-
...entry,
|
|
76
|
-
canonical,
|
|
77
|
-
width: metadata.viewBox[2],
|
|
78
|
-
height: metadata.viewBox[3],
|
|
79
|
-
};
|
|
80
|
-
})
|
|
81
|
-
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
82
|
-
}
|
|
83
|
-
function renderOutputs(records, outputRoot) {
|
|
84
|
-
const swift =
|
|
85
|
-
header +
|
|
86
|
-
'import UIKit\n\nstruct NativeListIconMetadata {\n let name: String\n let size: CGSize\n let original: Bool\n}\n\nenum NativeListGeneratedIcons {\n static let icons: [String: NativeListIconMetadata] = [\n' +
|
|
87
|
-
records
|
|
88
|
-
.filter((x) => x.platforms.includes('ios'))
|
|
89
|
-
.map(
|
|
90
|
-
(x) =>
|
|
91
|
-
` "${x.name}": NativeListIconMetadata(name: "${
|
|
92
|
-
x.canonical
|
|
93
|
-
}", size: CGSize(width: ${x.width}, height: ${x.height}), original: ${
|
|
94
|
-
x.rendering === 'original'
|
|
95
|
-
}),`
|
|
96
|
-
)
|
|
97
|
-
.join('\n') +
|
|
98
|
-
'\n ]\n}\n';
|
|
99
|
-
const kotlin =
|
|
100
|
-
header +
|
|
101
|
-
'package com.margelo.nitro.nativelist\n\ninternal data class NativeListIconMetadata(val name: String, val width: Float, val height: Float)\ninternal val nativeListGeneratedIcons: Map<String, NativeListIconMetadata> = mapOf(\n' +
|
|
102
|
-
records
|
|
103
|
-
.filter((x) => x.platforms.includes('android'))
|
|
104
|
-
.map(
|
|
105
|
-
(x) =>
|
|
106
|
-
` "${x.name}" to NativeListIconMetadata("${x.canonical}", ${x.width}f, ${x.height}f),`
|
|
107
|
-
)
|
|
108
|
-
.join('\n') +
|
|
109
|
-
'\n)\n';
|
|
110
|
-
const web =
|
|
111
|
-
header +
|
|
112
|
-
'export const nativeListGeneratedIcons: Readonly<Record<string, string>> = ' +
|
|
113
|
-
JSON.stringify(
|
|
114
|
-
Object.fromEntries(
|
|
115
|
-
records
|
|
116
|
-
.filter((x) => x.platforms.includes('web'))
|
|
117
|
-
.map((x) => [x.name, x.canonical])
|
|
118
|
-
)
|
|
119
|
-
) +
|
|
120
|
-
';\n';
|
|
121
|
-
return new Map([
|
|
122
|
-
[path.join(outputRoot, 'ios/NativeListGeneratedIcons.swift'), swift],
|
|
123
|
-
[
|
|
124
|
-
path.join(
|
|
125
|
-
outputRoot,
|
|
126
|
-
'android/src/main/java/com/onekey/nativelist/NativeListGeneratedIcons.kt'
|
|
127
|
-
),
|
|
128
|
-
kotlin,
|
|
129
|
-
],
|
|
130
|
-
[
|
|
131
|
-
path.join(outputRoot, 'src/web/NativeListGeneratedIcons.ts'),
|
|
132
|
-
prettier.format(web, { ...format, parser: 'typescript' }),
|
|
133
|
-
],
|
|
134
|
-
]);
|
|
135
|
-
}
|
|
136
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
137
|
-
const outputs = generateOutputs();
|
|
138
|
-
const stale = [...outputs].filter(
|
|
139
|
-
([file, text]) =>
|
|
140
|
-
!fs.existsSync(file) || fs.readFileSync(file, 'utf8') !== text
|
|
141
|
-
);
|
|
142
|
-
if (process.argv.includes('--check') && stale.length)
|
|
143
|
-
throw new Error('Stale NativeList icon metadata');
|
|
144
|
-
if (!process.argv.includes('--check'))
|
|
145
|
-
for (const [file, text] of stale) {
|
|
146
|
-
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
147
|
-
fs.writeFileSync(file, text);
|
|
148
|
-
}
|
|
149
|
-
console.log(JSON.stringify({ outputs: outputs.size, changed: stale.length }));
|
|
150
|
-
}
|
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { spawnSync } from 'node:child_process';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import test from 'node:test';
|
|
7
|
-
import { generateOutputs, resolveRecords } from './generate-icons.mjs';
|
|
8
|
-
const scripts = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const packageRoot = path.dirname(scripts);
|
|
10
|
-
const fixtureRoot = path.resolve(
|
|
11
|
-
packageRoot,
|
|
12
|
-
'../../example/react-native/icon-fixtures/native/icons'
|
|
13
|
-
);
|
|
14
|
-
const manifest = JSON.parse(
|
|
15
|
-
fs.readFileSync(path.join(scripts, 'native-list-icons.json'), 'utf8')
|
|
16
|
-
);
|
|
17
|
-
const catalogFile = path.join(fixtureRoot, 'manifest.json');
|
|
18
|
-
const catalog = JSON.parse(fs.readFileSync(catalogFile, 'utf8'));
|
|
19
|
-
// Frozen migration coverage, independent from the production manifest.
|
|
20
|
-
const migrationCoverage = {
|
|
21
|
-
ios: [
|
|
22
|
-
'AccountErrorCustom',
|
|
23
|
-
'AllNetworksSolid',
|
|
24
|
-
'AppleBrand',
|
|
25
|
-
'ArrowBottomOutline',
|
|
26
|
-
'ArrowTopOutline',
|
|
27
|
-
'BadgeVerifiedSolid',
|
|
28
|
-
'BotIllus',
|
|
29
|
-
'ChartTrendingUpOutline',
|
|
30
|
-
'CheckboxCheckedCustom',
|
|
31
|
-
'CheckboxIndeterminateCustom',
|
|
32
|
-
'ChevronBottomOutline',
|
|
33
|
-
'ChevronGrabberVerOutline',
|
|
34
|
-
'ChevronRightSmallOutline',
|
|
35
|
-
'ChevronTopOutline',
|
|
36
|
-
'CrossedSmallSolid',
|
|
37
|
-
'CryptoCoinOutline',
|
|
38
|
-
'Document2Outline',
|
|
39
|
-
'DotHorOutline',
|
|
40
|
-
'DotVerSolid',
|
|
41
|
-
'DragOutline',
|
|
42
|
-
'ErrorSolid',
|
|
43
|
-
'GasSolid',
|
|
44
|
-
'GlobusOutline',
|
|
45
|
-
'GoogleIllus',
|
|
46
|
-
'ImageSquareWavesOutline',
|
|
47
|
-
'InfoCircleOutline',
|
|
48
|
-
'LockSolid',
|
|
49
|
-
'MinusCircleOutline',
|
|
50
|
-
'MinusCircleSolid',
|
|
51
|
-
'PencilOutline',
|
|
52
|
-
'PlusCircleOutline',
|
|
53
|
-
'PlusLargeOutline',
|
|
54
|
-
'PlusSmallOutline',
|
|
55
|
-
'QuestionmarkSolid',
|
|
56
|
-
'RefreshCcwOutline',
|
|
57
|
-
'ShieldExclamationOutline',
|
|
58
|
-
'SpeakerPromoteOutline',
|
|
59
|
-
'StarOutline',
|
|
60
|
-
'StarSolid',
|
|
61
|
-
'SwapHorOutline',
|
|
62
|
-
'TicketOutline',
|
|
63
|
-
'WalletOutline',
|
|
64
|
-
],
|
|
65
|
-
android: [
|
|
66
|
-
'AccountErrorCustom',
|
|
67
|
-
'AllNetworksSolid',
|
|
68
|
-
'AppleBrand',
|
|
69
|
-
'ArrowBottomOutline',
|
|
70
|
-
'ArrowTopOutline',
|
|
71
|
-
'BadgeVerifiedSolid',
|
|
72
|
-
'BotIllus',
|
|
73
|
-
'ChartTrendingUpOutline',
|
|
74
|
-
'ChevronBottomOutline',
|
|
75
|
-
'ChevronGrabberVerOutline',
|
|
76
|
-
'ChevronRightSmallOutline',
|
|
77
|
-
'ChevronTopOutline',
|
|
78
|
-
'Circle',
|
|
79
|
-
'CrossedSmallSolid',
|
|
80
|
-
'CryptoCoinOutline',
|
|
81
|
-
'Document2Outline',
|
|
82
|
-
'DotHorOutline',
|
|
83
|
-
'DotVerSolid',
|
|
84
|
-
'DragOutline',
|
|
85
|
-
'ErrorSolid',
|
|
86
|
-
'GasSolid',
|
|
87
|
-
'GlobusOutline',
|
|
88
|
-
'GoogleIllus',
|
|
89
|
-
'ImageSquareWavesOutline',
|
|
90
|
-
'InfoCircleOutline',
|
|
91
|
-
'LockSolid',
|
|
92
|
-
'MinusCircleOutline',
|
|
93
|
-
'MinusCircleSolid',
|
|
94
|
-
'PencilOutline',
|
|
95
|
-
'PlusCircleOutline',
|
|
96
|
-
'PlusLargeOutline',
|
|
97
|
-
'PlusSmallOutline',
|
|
98
|
-
'QuestionmarkSolid',
|
|
99
|
-
'RefreshCcwOutline',
|
|
100
|
-
'ShieldExclamationOutline',
|
|
101
|
-
'SpeakerPromoteOutline',
|
|
102
|
-
'StarOutline',
|
|
103
|
-
'StarSolid',
|
|
104
|
-
'SwapHorOutline',
|
|
105
|
-
'TicketOutline',
|
|
106
|
-
'WalletOutline',
|
|
107
|
-
],
|
|
108
|
-
web: [
|
|
109
|
-
'AccountErrorCustom',
|
|
110
|
-
'AllNetworksSolid',
|
|
111
|
-
'AppleBrand',
|
|
112
|
-
'BadgeVerifiedSolid',
|
|
113
|
-
'BotIllus',
|
|
114
|
-
'CheckboxCheckedCustom',
|
|
115
|
-
'CheckboxIndeterminateCustom',
|
|
116
|
-
'ChevronRightSmallOutline',
|
|
117
|
-
'Circle',
|
|
118
|
-
'CrossedSmallSolid',
|
|
119
|
-
'CryptoCoinOutline',
|
|
120
|
-
'Document2Outline',
|
|
121
|
-
'DotHorOutline',
|
|
122
|
-
'DotVerSolid',
|
|
123
|
-
'DragOutline',
|
|
124
|
-
'GasSolid',
|
|
125
|
-
'GlobusOutline',
|
|
126
|
-
'GoogleIllus',
|
|
127
|
-
'LockSolid',
|
|
128
|
-
'PencilOutline',
|
|
129
|
-
'PlusLargeOutline',
|
|
130
|
-
'PlusSmallOutline',
|
|
131
|
-
'RefreshCcwOutline',
|
|
132
|
-
'TicketOutline',
|
|
133
|
-
'WalletOutline',
|
|
134
|
-
],
|
|
135
|
-
};
|
|
136
|
-
function assertRegistryCoverage(entries) {
|
|
137
|
-
for (const platform of Object.keys(migrationCoverage))
|
|
138
|
-
assert.deepEqual(
|
|
139
|
-
entries
|
|
140
|
-
.filter((entry) => entry.platforms.includes(platform))
|
|
141
|
-
.map((entry) => entry.name)
|
|
142
|
-
.sort(),
|
|
143
|
-
migrationCoverage[platform]
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
test('preserves frozen coverage, canonical aliases and intrinsic metadata without path copies', () => {
|
|
148
|
-
assertRegistryCoverage(manifest);
|
|
149
|
-
assert.throws(() =>
|
|
150
|
-
assertRegistryCoverage(
|
|
151
|
-
manifest.map((e) =>
|
|
152
|
-
e.name === 'DotVerSolid' ? { ...e, name: 'RenamedDotVerSolid' } : e
|
|
153
|
-
)
|
|
154
|
-
)
|
|
155
|
-
);
|
|
156
|
-
const records = resolveRecords(manifest, catalog, fixtureRoot);
|
|
157
|
-
assert.equal(
|
|
158
|
-
records.find((e) => e.name === 'BadgeVerifiedSolid').canonical,
|
|
159
|
-
'BadgeRecognizedSolid'
|
|
160
|
-
);
|
|
161
|
-
for (const [name, w, h] of [
|
|
162
|
-
['AppleBrand', 16, 20],
|
|
163
|
-
['CheckboxCheckedCustom', 16, 16],
|
|
164
|
-
['AccountErrorCustom', 18, 18],
|
|
165
|
-
]) {
|
|
166
|
-
const record = records.find((e) => e.name === name);
|
|
167
|
-
assert.deepEqual([record.width, record.height], [w, h]);
|
|
168
|
-
}
|
|
169
|
-
const outputs = generateOutputs(fixtureRoot);
|
|
170
|
-
assert.equal(outputs.size, 3);
|
|
171
|
-
assert.deepEqual([...outputs], [...generateOutputs(fixtureRoot)]);
|
|
172
|
-
const contents = [...outputs.values()];
|
|
173
|
-
assert.ok(
|
|
174
|
-
contents.every(
|
|
175
|
-
(text) => !text.includes(fixtureRoot) && !text.includes('<path')
|
|
176
|
-
)
|
|
177
|
-
);
|
|
178
|
-
const keys = [
|
|
179
|
-
[...contents[0].matchAll(/^ "([^"]+)":/gm)].map((m) => m[1]),
|
|
180
|
-
[...contents[1].matchAll(/^ "([^"]+)" to /gm)].map((m) => m[1]),
|
|
181
|
-
[...contents[2].matchAll(/^ ([A-Za-z0-9]+):/gm)].map((m) => m[1]),
|
|
182
|
-
];
|
|
183
|
-
assert.deepEqual(keys, [
|
|
184
|
-
migrationCoverage.ios,
|
|
185
|
-
migrationCoverage.android,
|
|
186
|
-
migrationCoverage.web,
|
|
187
|
-
]);
|
|
188
|
-
});
|
|
189
|
-
test('rejects invalid coverage metadata and missing, ambiguous or stale canonical sources', () => {
|
|
190
|
-
for (const invalid of [
|
|
191
|
-
{ ...manifest[0], name: undefined },
|
|
192
|
-
{ ...manifest[0], platforms: ['other'] },
|
|
193
|
-
{ ...manifest[0], platforms: ['ios', 'ios'] },
|
|
194
|
-
])
|
|
195
|
-
assert.throws(
|
|
196
|
-
() => resolveRecords([invalid], catalog, fixtureRoot),
|
|
197
|
-
/Invalid icon manifest/
|
|
198
|
-
);
|
|
199
|
-
assert.throws(
|
|
200
|
-
() => resolveRecords([manifest[0], manifest[0]], catalog, fixtureRoot),
|
|
201
|
-
/Invalid icon manifest/
|
|
202
|
-
);
|
|
203
|
-
assert.throws(
|
|
204
|
-
() => resolveRecords(manifest, {}, fixtureRoot),
|
|
205
|
-
/Missing shared SVG/
|
|
206
|
-
);
|
|
207
|
-
assert.throws(
|
|
208
|
-
() =>
|
|
209
|
-
resolveRecords(
|
|
210
|
-
manifest,
|
|
211
|
-
{
|
|
212
|
-
...catalog,
|
|
213
|
-
Duplicate:
|
|
214
|
-
catalog[
|
|
215
|
-
Object.keys(catalog).find(
|
|
216
|
-
(k) => catalog[k].source === manifest[0].source
|
|
217
|
-
)
|
|
218
|
-
],
|
|
219
|
-
},
|
|
220
|
-
fixtureRoot
|
|
221
|
-
),
|
|
222
|
-
/Ambiguous shared SVG/
|
|
223
|
-
);
|
|
224
|
-
const changed = structuredClone(catalog);
|
|
225
|
-
changed[
|
|
226
|
-
Object.keys(changed).find((k) => changed[k].source === manifest[0].source)
|
|
227
|
-
].digest = '0';
|
|
228
|
-
assert.throws(() => resolveRecords(manifest, changed, fixtureRoot), /stale/);
|
|
229
|
-
});
|
|
230
|
-
test('generation is idempotent, check is read-only and invalid late input cannot partially write', () => {
|
|
231
|
-
const tempRoot = path.join(packageRoot, '.tmp');
|
|
232
|
-
fs.mkdirSync(tempRoot, { recursive: true });
|
|
233
|
-
const temp = fs.mkdtempSync(path.join(tempRoot, 'metadata-'));
|
|
234
|
-
try {
|
|
235
|
-
const sdk = path.join(temp, 'native-views/react-native-native-list');
|
|
236
|
-
fs.mkdirSync(path.join(sdk, 'scripts'), { recursive: true });
|
|
237
|
-
for (const name of ['generate-icons.mjs', 'native-list-icons.json'])
|
|
238
|
-
fs.copyFileSync(
|
|
239
|
-
path.join(scripts, name),
|
|
240
|
-
path.join(sdk, 'scripts', name)
|
|
241
|
-
);
|
|
242
|
-
fs.copyFileSync(
|
|
243
|
-
path.join(packageRoot, 'package.json'),
|
|
244
|
-
path.join(sdk, 'package.json')
|
|
245
|
-
);
|
|
246
|
-
fs.symlinkSync(
|
|
247
|
-
path.resolve(packageRoot, '../../node_modules'),
|
|
248
|
-
path.join(temp, 'node_modules'),
|
|
249
|
-
'dir'
|
|
250
|
-
);
|
|
251
|
-
const targetCatalog = path.join(
|
|
252
|
-
temp,
|
|
253
|
-
'example/react-native/icon-fixtures/native/icons/manifest.json'
|
|
254
|
-
);
|
|
255
|
-
fs.mkdirSync(path.dirname(targetCatalog), { recursive: true });
|
|
256
|
-
fs.cpSync(fixtureRoot, path.dirname(targetCatalog), { recursive: true });
|
|
257
|
-
const run = (check = false) =>
|
|
258
|
-
spawnSync(
|
|
259
|
-
process.execPath,
|
|
260
|
-
[
|
|
261
|
-
path.join(sdk, 'scripts/generate-icons.mjs'),
|
|
262
|
-
...(check ? ['--check'] : []),
|
|
263
|
-
],
|
|
264
|
-
{ encoding: 'utf8' }
|
|
265
|
-
);
|
|
266
|
-
assert.equal(run().status, 0);
|
|
267
|
-
assert.equal(JSON.parse(run().stdout).changed, 0);
|
|
268
|
-
assert.equal(run(true).status, 0);
|
|
269
|
-
const files = [...generateOutputs(fixtureRoot, sdk).keys()];
|
|
270
|
-
const snapshot = () => files.map((file) => fs.readFileSync(file, 'utf8'));
|
|
271
|
-
fs.appendFileSync(files[0], '// stale\n');
|
|
272
|
-
const stale = snapshot();
|
|
273
|
-
assert.notEqual(run(true).status, 0);
|
|
274
|
-
assert.deepEqual(snapshot(), stale);
|
|
275
|
-
assert.equal(run().status, 0);
|
|
276
|
-
const before = snapshot();
|
|
277
|
-
const changed = structuredClone(catalog);
|
|
278
|
-
changed[
|
|
279
|
-
Object.keys(changed).find((k) => changed[k].source === manifest[0].source)
|
|
280
|
-
].viewBox = [0, 0, 12, 12];
|
|
281
|
-
delete changed.DotVerSolid;
|
|
282
|
-
fs.writeFileSync(targetCatalog, JSON.stringify(changed));
|
|
283
|
-
assert.notEqual(run().status, 0);
|
|
284
|
-
assert.deepEqual(snapshot(), before);
|
|
285
|
-
} finally {
|
|
286
|
-
fs.rmSync(temp, { recursive: true, force: true });
|
|
287
|
-
}
|
|
288
|
-
});
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"name": "AccountErrorCustom",
|
|
4
|
-
"source": "custom/account-error.svg",
|
|
5
|
-
"platforms": ["ios", "android", "web"],
|
|
6
|
-
"rendering": "original"
|
|
7
|
-
},
|
|
8
|
-
{
|
|
9
|
-
"name": "AllNetworksSolid",
|
|
10
|
-
"source": "solid/all-networks.svg",
|
|
11
|
-
"platforms": ["ios", "android", "web"],
|
|
12
|
-
"rendering": "template"
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"name": "AppleBrand",
|
|
16
|
-
"source": "brand/apple.svg",
|
|
17
|
-
"platforms": ["ios", "android", "web"],
|
|
18
|
-
"rendering": "template"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"name": "ArrowBottomOutline",
|
|
22
|
-
"source": "outline/arrow-bottom.svg",
|
|
23
|
-
"platforms": ["ios", "android"],
|
|
24
|
-
"rendering": "template"
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"name": "ArrowTopOutline",
|
|
28
|
-
"source": "outline/arrow-top.svg",
|
|
29
|
-
"platforms": ["ios", "android"],
|
|
30
|
-
"rendering": "template"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"name": "BadgeVerifiedSolid",
|
|
34
|
-
"source": "solid/badge-recognized.svg",
|
|
35
|
-
"platforms": ["ios", "android", "web"],
|
|
36
|
-
"rendering": "template"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"name": "BotIllus",
|
|
40
|
-
"source": "illus/bot.svg",
|
|
41
|
-
"platforms": ["ios", "android", "web"],
|
|
42
|
-
"rendering": "original"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"name": "ChartTrendingUpOutline",
|
|
46
|
-
"source": "outline/chart-trending-up.svg",
|
|
47
|
-
"platforms": ["ios", "android"],
|
|
48
|
-
"rendering": "template"
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
"name": "CheckboxCheckedCustom",
|
|
52
|
-
"source": "custom/checkbox-checked.svg",
|
|
53
|
-
"platforms": ["ios", "web"],
|
|
54
|
-
"rendering": "template"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"name": "CheckboxIndeterminateCustom",
|
|
58
|
-
"source": "custom/checkbox-indeterminate.svg",
|
|
59
|
-
"platforms": ["ios", "web"],
|
|
60
|
-
"rendering": "template"
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"name": "ChevronBottomOutline",
|
|
64
|
-
"source": "outline/chevron-bottom.svg",
|
|
65
|
-
"platforms": ["ios", "android"],
|
|
66
|
-
"rendering": "template"
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
"name": "ChevronGrabberVerOutline",
|
|
70
|
-
"source": "outline/chevron-grabber-ver.svg",
|
|
71
|
-
"platforms": ["ios", "android"],
|
|
72
|
-
"rendering": "template"
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"name": "ChevronRightSmallOutline",
|
|
76
|
-
"source": "outline/chevron-right-small.svg",
|
|
77
|
-
"platforms": ["ios", "android", "web"],
|
|
78
|
-
"rendering": "template"
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
"name": "ChevronTopOutline",
|
|
82
|
-
"source": "outline/chevron-top.svg",
|
|
83
|
-
"platforms": ["ios", "android"],
|
|
84
|
-
"rendering": "template"
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
"name": "Circle",
|
|
88
|
-
"source": null,
|
|
89
|
-
"platforms": ["android", "web"],
|
|
90
|
-
"rendering": "template"
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"name": "CrossedSmallSolid",
|
|
94
|
-
"source": "solid/crossed-small.svg",
|
|
95
|
-
"platforms": ["ios", "android", "web"],
|
|
96
|
-
"rendering": "template"
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
"name": "CryptoCoinOutline",
|
|
100
|
-
"source": "outline/crypto-coin.svg",
|
|
101
|
-
"platforms": ["ios", "android", "web"],
|
|
102
|
-
"rendering": "template"
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
"name": "Document2Outline",
|
|
106
|
-
"source": "outline/document-2.svg",
|
|
107
|
-
"platforms": ["ios", "android", "web"],
|
|
108
|
-
"rendering": "template"
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"name": "DotHorOutline",
|
|
112
|
-
"source": "outline/dot-hor.svg",
|
|
113
|
-
"platforms": ["ios", "android", "web"],
|
|
114
|
-
"rendering": "template"
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
"name": "DotVerSolid",
|
|
118
|
-
"source": "solid/dot-ver.svg",
|
|
119
|
-
"platforms": ["ios", "android", "web"],
|
|
120
|
-
"rendering": "template"
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
"name": "DragOutline",
|
|
124
|
-
"source": "outline/drag.svg",
|
|
125
|
-
"platforms": ["ios", "android", "web"],
|
|
126
|
-
"rendering": "template"
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
"name": "ErrorSolid",
|
|
130
|
-
"source": "solid/error.svg",
|
|
131
|
-
"platforms": ["ios", "android"],
|
|
132
|
-
"rendering": "template"
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
"name": "GasSolid",
|
|
136
|
-
"source": "solid/gas.svg",
|
|
137
|
-
"platforms": ["ios", "android", "web"],
|
|
138
|
-
"rendering": "template"
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
"name": "GlobusOutline",
|
|
142
|
-
"source": "outline/globus.svg",
|
|
143
|
-
"platforms": ["ios", "android", "web"],
|
|
144
|
-
"rendering": "template"
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
"name": "GoogleIllus",
|
|
148
|
-
"source": "illus/google.svg",
|
|
149
|
-
"platforms": ["ios", "android", "web"],
|
|
150
|
-
"rendering": "original"
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
"name": "ImageSquareWavesOutline",
|
|
154
|
-
"source": "outline/image-square-waves.svg",
|
|
155
|
-
"platforms": ["ios", "android"],
|
|
156
|
-
"rendering": "template"
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
"name": "InfoCircleOutline",
|
|
160
|
-
"source": "outline/info-circle.svg",
|
|
161
|
-
"platforms": ["ios", "android"],
|
|
162
|
-
"rendering": "template"
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
"name": "LockSolid",
|
|
166
|
-
"source": "solid/lock.svg",
|
|
167
|
-
"platforms": ["ios", "android", "web"],
|
|
168
|
-
"rendering": "template"
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
"name": "MinusCircleOutline",
|
|
172
|
-
"source": "outline/minus-circle.svg",
|
|
173
|
-
"platforms": ["ios", "android"],
|
|
174
|
-
"rendering": "template"
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
"name": "MinusCircleSolid",
|
|
178
|
-
"source": "solid/minus-circle.svg",
|
|
179
|
-
"platforms": ["ios", "android"],
|
|
180
|
-
"rendering": "template"
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
"name": "PencilOutline",
|
|
184
|
-
"source": "outline/pencil.svg",
|
|
185
|
-
"platforms": ["ios", "android", "web"],
|
|
186
|
-
"rendering": "template"
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
"name": "PlusCircleOutline",
|
|
190
|
-
"source": "outline/plus-circle.svg",
|
|
191
|
-
"platforms": ["ios", "android"],
|
|
192
|
-
"rendering": "template"
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
"name": "PlusLargeOutline",
|
|
196
|
-
"source": "outline/plus-large.svg",
|
|
197
|
-
"platforms": ["ios", "android", "web"],
|
|
198
|
-
"rendering": "template"
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
"name": "PlusSmallOutline",
|
|
202
|
-
"source": "outline/plus-small.svg",
|
|
203
|
-
"platforms": ["ios", "android", "web"],
|
|
204
|
-
"rendering": "template"
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
"name": "QuestionmarkSolid",
|
|
208
|
-
"source": "solid/questionmark.svg",
|
|
209
|
-
"platforms": ["ios", "android"],
|
|
210
|
-
"rendering": "template"
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
"name": "RefreshCcwOutline",
|
|
214
|
-
"source": "outline/refresh-ccw.svg",
|
|
215
|
-
"platforms": ["ios", "android", "web"],
|
|
216
|
-
"rendering": "template"
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
"name": "ShieldExclamationOutline",
|
|
220
|
-
"source": "outline/shield-exclamation.svg",
|
|
221
|
-
"platforms": ["ios", "android"],
|
|
222
|
-
"rendering": "template"
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
"name": "SpeakerPromoteOutline",
|
|
226
|
-
"source": "outline/speaker-promote.svg",
|
|
227
|
-
"platforms": ["ios", "android"],
|
|
228
|
-
"rendering": "template"
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
"name": "StarOutline",
|
|
232
|
-
"source": "outline/star.svg",
|
|
233
|
-
"platforms": ["ios", "android"],
|
|
234
|
-
"rendering": "template"
|
|
235
|
-
},
|
|
236
|
-
{
|
|
237
|
-
"name": "StarSolid",
|
|
238
|
-
"source": "solid/star.svg",
|
|
239
|
-
"platforms": ["ios", "android"],
|
|
240
|
-
"rendering": "template"
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
"name": "SwapHorOutline",
|
|
244
|
-
"source": "outline/swap-hor.svg",
|
|
245
|
-
"platforms": ["ios", "android"],
|
|
246
|
-
"rendering": "template"
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
"name": "TicketOutline",
|
|
250
|
-
"source": "outline/ticket.svg",
|
|
251
|
-
"platforms": ["ios", "android", "web"],
|
|
252
|
-
"rendering": "template"
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
"name": "WalletOutline",
|
|
256
|
-
"source": "outline/wallet.svg",
|
|
257
|
-
"platforms": ["ios", "android", "web"],
|
|
258
|
-
"rendering": "template"
|
|
259
|
-
}
|
|
260
|
-
]
|