@buoy-gg/assets 7.0.36 → 7.0.38
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 +41 -12
- package/lib/commonjs/capture/expo.js +1 -46
- package/lib/commonjs/capture/install.js +1 -78
- package/lib/commonjs/capture/isBuoyAsset.js +1 -0
- package/lib/commonjs/capture/measure.js +1 -186
- package/lib/commonjs/capture/metroGraph.js +1 -148
- package/lib/commonjs/capture/registry.js +1 -127
- package/lib/commonjs/components/AssetDetail.js +1 -214
- package/lib/commonjs/components/AssetImage.js +1 -0
- package/lib/commonjs/components/AssetRow.js +1 -233
- package/lib/commonjs/components/AssetsFilterBar.js +1 -96
- package/lib/commonjs/components/AssetsHeader.js +1 -72
- package/lib/commonjs/components/AssetsIcon.js +1 -19
- package/lib/commonjs/components/AssetsListControls.js +1 -96
- package/lib/commonjs/components/AssetsModal.js +1 -347
- package/lib/commonjs/components/ScanNotice.js +1 -0
- package/lib/commonjs/components/optionalExpoImage.js +1 -0
- package/lib/commonjs/components/optionalExpoImage.web.js +1 -0
- package/lib/commonjs/export.js +1 -62
- package/lib/commonjs/format.js +1 -59
- package/lib/commonjs/hooks/useAssetRecords.js +1 -22
- package/lib/commonjs/hooks/useAssetScanStatus.js +1 -0
- package/lib/commonjs/index.js +1 -313
- package/lib/commonjs/preset.js +1 -39
- package/lib/commonjs/remote.js +1 -65
- package/lib/commonjs/state.js +1 -51
- package/lib/commonjs/store/assetStore.js +1 -241
- package/lib/commonjs/store/baseline.js +1 -173
- package/lib/commonjs/store/insights.js +1 -120
- package/lib/commonjs/sync/assetsSyncAdapter.js +1 -157
- package/lib/commonjs/types.js +1 -2
- package/lib/commonjs/utils/deviceScale.js +1 -50
- package/lib/commonjs/utils/testIDs.js +1 -114
- package/lib/module/capture/expo.js +1 -41
- package/lib/module/capture/install.js +1 -72
- package/lib/module/capture/isBuoyAsset.js +1 -0
- package/lib/module/capture/measure.js +1 -179
- package/lib/module/capture/metroGraph.js +1 -141
- package/lib/module/capture/registry.js +1 -120
- package/lib/module/components/AssetDetail.js +1 -210
- package/lib/module/components/AssetImage.js +1 -0
- package/lib/module/components/AssetRow.js +1 -229
- package/lib/module/components/AssetsFilterBar.js +1 -92
- package/lib/module/components/AssetsHeader.js +1 -68
- package/lib/module/components/AssetsIcon.js +1 -12
- package/lib/module/components/AssetsListControls.js +1 -92
- package/lib/module/components/AssetsModal.js +1 -342
- package/lib/module/components/ScanNotice.js +1 -0
- package/lib/module/components/optionalExpoImage.js +1 -0
- package/lib/module/components/optionalExpoImage.web.js +1 -0
- package/lib/module/export.js +1 -57
- package/lib/module/format.js +1 -51
- package/lib/module/hooks/useAssetRecords.js +1 -18
- package/lib/module/hooks/useAssetScanStatus.js +1 -0
- package/lib/module/index.js +1 -63
- package/lib/module/preset.js +1 -35
- package/lib/module/remote.js +1 -58
- package/lib/module/state.js +1 -47
- package/lib/module/store/assetStore.js +1 -226
- package/lib/module/store/baseline.js +1 -165
- package/lib/module/store/insights.js +1 -116
- package/lib/module/sync/assetsSyncAdapter.js +1 -153
- package/lib/module/types.js +1 -2
- package/lib/module/utils/deviceScale.js +1 -46
- package/lib/module/utils/testIDs.js +1 -103
- package/lib/typescript/capture/isBuoyAsset.d.ts +9 -0
- package/lib/typescript/capture/registry.d.ts +1 -1
- package/lib/typescript/components/AssetDetail.d.ts +2 -2
- package/lib/typescript/components/AssetImage.d.ts +9 -0
- package/lib/typescript/components/AssetsFilterBar.d.ts +3 -2
- package/lib/typescript/components/AssetsHeader.d.ts +2 -1
- package/lib/typescript/components/AssetsListControls.d.ts +2 -9
- package/lib/typescript/components/ScanNotice.d.ts +7 -0
- package/lib/typescript/components/optionalExpoImage.d.ts +13 -0
- package/lib/typescript/components/optionalExpoImage.web.d.ts +3 -0
- package/lib/typescript/hooks/useAssetScanStatus.d.ts +6 -0
- package/lib/typescript/state.d.ts +2 -0
- package/lib/typescript/store/assetStore.d.ts +3 -1
- package/lib/typescript/types.d.ts +3 -0
- package/lib/typescript/utils/testIDs.d.ts +2 -5
- package/package.json +7 -3
- package/lib/commonjs/capture/expo.js.map +0 -1
- package/lib/commonjs/capture/install.js.map +0 -1
- package/lib/commonjs/capture/measure.js.map +0 -1
- package/lib/commonjs/capture/metroGraph.js.map +0 -1
- package/lib/commonjs/capture/registry.js.map +0 -1
- package/lib/commonjs/components/AssetDetail.js.map +0 -1
- package/lib/commonjs/components/AssetRow.js.map +0 -1
- package/lib/commonjs/components/AssetsFilterBar.js.map +0 -1
- package/lib/commonjs/components/AssetsHeader.js.map +0 -1
- package/lib/commonjs/components/AssetsIcon.js.map +0 -1
- package/lib/commonjs/components/AssetsListControls.js.map +0 -1
- package/lib/commonjs/components/AssetsModal.js.map +0 -1
- package/lib/commonjs/components/BaselineBar.js +0 -115
- package/lib/commonjs/components/BaselineBar.js.map +0 -1
- package/lib/commonjs/export.js.map +0 -1
- package/lib/commonjs/format.js.map +0 -1
- package/lib/commonjs/hooks/useAssetRecords.js.map +0 -1
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/preset.js.map +0 -1
- package/lib/commonjs/remote.js.map +0 -1
- package/lib/commonjs/state.js.map +0 -1
- package/lib/commonjs/store/assetStore.js.map +0 -1
- package/lib/commonjs/store/baseline.js.map +0 -1
- package/lib/commonjs/store/insights.js.map +0 -1
- package/lib/commonjs/sync/assetsSyncAdapter.js.map +0 -1
- package/lib/commonjs/types.js.map +0 -1
- package/lib/commonjs/utils/deviceScale.js.map +0 -1
- package/lib/commonjs/utils/testIDs.js.map +0 -1
- package/lib/module/capture/expo.js.map +0 -1
- package/lib/module/capture/install.js.map +0 -1
- package/lib/module/capture/measure.js.map +0 -1
- package/lib/module/capture/metroGraph.js.map +0 -1
- package/lib/module/capture/registry.js.map +0 -1
- package/lib/module/components/AssetDetail.js.map +0 -1
- package/lib/module/components/AssetRow.js.map +0 -1
- package/lib/module/components/AssetsFilterBar.js.map +0 -1
- package/lib/module/components/AssetsHeader.js.map +0 -1
- package/lib/module/components/AssetsIcon.js.map +0 -1
- package/lib/module/components/AssetsListControls.js.map +0 -1
- package/lib/module/components/AssetsModal.js.map +0 -1
- package/lib/module/components/BaselineBar.js +0 -111
- package/lib/module/components/BaselineBar.js.map +0 -1
- package/lib/module/export.js.map +0 -1
- package/lib/module/format.js.map +0 -1
- package/lib/module/hooks/useAssetRecords.js.map +0 -1
- package/lib/module/index.js.map +0 -1
- package/lib/module/preset.js.map +0 -1
- package/lib/module/remote.js.map +0 -1
- package/lib/module/state.js.map +0 -1
- package/lib/module/store/assetStore.js.map +0 -1
- package/lib/module/store/baseline.js.map +0 -1
- package/lib/module/store/insights.js.map +0 -1
- package/lib/module/sync/assetsSyncAdapter.js.map +0 -1
- package/lib/module/types.js.map +0 -1
- package/lib/module/utils/deviceScale.js.map +0 -1
- package/lib/module/utils/testIDs.js.map +0 -1
- package/lib/typescript/capture/expo.d.ts.map +0 -1
- package/lib/typescript/capture/install.d.ts.map +0 -1
- package/lib/typescript/capture/measure.d.ts.map +0 -1
- package/lib/typescript/capture/metroGraph.d.ts.map +0 -1
- package/lib/typescript/capture/registry.d.ts.map +0 -1
- package/lib/typescript/components/AssetDetail.d.ts.map +0 -1
- package/lib/typescript/components/AssetRow.d.ts.map +0 -1
- package/lib/typescript/components/AssetsFilterBar.d.ts.map +0 -1
- package/lib/typescript/components/AssetsHeader.d.ts.map +0 -1
- package/lib/typescript/components/AssetsIcon.d.ts.map +0 -1
- package/lib/typescript/components/AssetsListControls.d.ts.map +0 -1
- package/lib/typescript/components/AssetsModal.d.ts.map +0 -1
- package/lib/typescript/components/BaselineBar.d.ts +0 -13
- package/lib/typescript/components/BaselineBar.d.ts.map +0 -1
- package/lib/typescript/export.d.ts.map +0 -1
- package/lib/typescript/format.d.ts.map +0 -1
- package/lib/typescript/hooks/useAssetRecords.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/remote.d.ts.map +0 -1
- package/lib/typescript/state.d.ts.map +0 -1
- package/lib/typescript/store/assetStore.d.ts.map +0 -1
- package/lib/typescript/store/baseline.d.ts.map +0 -1
- package/lib/typescript/store/insights.d.ts.map +0 -1
- package/lib/typescript/sync/assetsSyncAdapter.d.ts.map +0 -1
- package/lib/typescript/types.d.ts.map +0 -1
- package/lib/typescript/utils/deviceScale.d.ts.map +0 -1
- package/lib/typescript/utils/testIDs.d.ts.map +0 -1
|
@@ -1,229 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* AssetRow — one bundled asset as a family-style card (matching the network
|
|
5
|
-
* tool's rows): rounded card, colored accent edge per kind, thumbnail, name,
|
|
6
|
-
* quiet metadata, bold right-aligned size, and finding badges ONLY when a
|
|
7
|
-
* finding exists. A thin proportional bar along the card bottom makes the
|
|
8
|
-
* heavy assets feel heavy at a glance.
|
|
9
|
-
*
|
|
10
|
-
* Thumbnails render through the NUMERIC registry id when available — that
|
|
11
|
-
* routes through resolveAssetSource natively, so it works in dev, iOS
|
|
12
|
-
* release (file://) and Android release (bare resource id) alike. They carry
|
|
13
|
-
* the buoy-internal testID so the images tool never records our own UI.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
17
|
-
import { macOSColors, night, Pill } from "@buoy-gg/shared-ui";
|
|
18
|
-
import { displaySource } from "../capture/measure";
|
|
19
|
-
import { formatDimensions, formatScales, formatSize, KIND_COLORS, KIND_LABELS } from "../format";
|
|
20
|
-
import { estDecodedBytes } from "../store/assetStore";
|
|
21
|
-
import { assetBadgeTestID, assetRowTestID } from "../utils/testIDs";
|
|
22
|
-
|
|
23
|
-
/** Which audit findings apply to this record (drives the row badges). */
|
|
24
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
25
|
-
function Badge({
|
|
26
|
-
label,
|
|
27
|
-
color,
|
|
28
|
-
testID
|
|
29
|
-
}) {
|
|
30
|
-
// Quiet chip: legibility from light-gray text on a neutral fill. Only the
|
|
31
|
-
// serious tiers (red) and WEBP (blue) carry a small dot; the rest are plain.
|
|
32
|
-
return /*#__PURE__*/_jsx(Pill, {
|
|
33
|
-
label: label,
|
|
34
|
-
color: color,
|
|
35
|
-
variant: "quiet",
|
|
36
|
-
dot: Boolean(color),
|
|
37
|
-
style: {
|
|
38
|
-
paddingVertical: 2.5
|
|
39
|
-
},
|
|
40
|
-
testID: testID
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
export function AssetRow({
|
|
44
|
-
record,
|
|
45
|
-
flags,
|
|
46
|
-
sizeFraction,
|
|
47
|
-
onPress
|
|
48
|
-
}) {
|
|
49
|
-
const accent = KIND_COLORS[record.kind];
|
|
50
|
-
const thumbSource = record.kind === "image" ? displaySource(record) : null;
|
|
51
|
-
const badges = [];
|
|
52
|
-
if (!record.loaded) badges.push({
|
|
53
|
-
label: "UNUSED"
|
|
54
|
-
});
|
|
55
|
-
if (flags.oversize) badges.push({
|
|
56
|
-
label: "OVERSIZE",
|
|
57
|
-
color: macOSColors.semantic.error
|
|
58
|
-
});
|
|
59
|
-
if (flags.duplicate) badges.push({
|
|
60
|
-
label: "DUP"
|
|
61
|
-
});
|
|
62
|
-
if (flags.heavy) badges.push({
|
|
63
|
-
label: "HEAVY"
|
|
64
|
-
});
|
|
65
|
-
if (flags.scaleAnomaly) badges.push({
|
|
66
|
-
label: "BAD SCALE",
|
|
67
|
-
color: macOSColors.semantic.error
|
|
68
|
-
});else if (flags.scaleGap) badges.push({
|
|
69
|
-
label: "LOW-RES"
|
|
70
|
-
});
|
|
71
|
-
if (flags.webp) badges.push({
|
|
72
|
-
label: "WEBP",
|
|
73
|
-
color: macOSColors.semantic.info
|
|
74
|
-
});
|
|
75
|
-
return /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
76
|
-
style: styles.card,
|
|
77
|
-
testID: assetRowTestID(record.name, record.type),
|
|
78
|
-
onPress: () => onPress(record.id),
|
|
79
|
-
activeOpacity: 0.7,
|
|
80
|
-
children: [/*#__PURE__*/_jsxs(View, {
|
|
81
|
-
style: styles.body,
|
|
82
|
-
children: [/*#__PURE__*/_jsx(View, {
|
|
83
|
-
style: styles.thumbBox,
|
|
84
|
-
children: thumbSource != null ? /*#__PURE__*/_jsx(Image
|
|
85
|
-
// buoy-internal- prefix: the images tool skips its own toolchain's
|
|
86
|
-
// views, so previewing an asset never records a render of itself.
|
|
87
|
-
, {
|
|
88
|
-
testID: "buoy-internal-assets-thumb",
|
|
89
|
-
source: thumbSource,
|
|
90
|
-
style: styles.thumb,
|
|
91
|
-
resizeMode: "contain"
|
|
92
|
-
}) : /*#__PURE__*/_jsx(Text, {
|
|
93
|
-
style: [styles.thumbFallback, {
|
|
94
|
-
color: accent
|
|
95
|
-
}],
|
|
96
|
-
children: KIND_LABELS[record.kind]
|
|
97
|
-
})
|
|
98
|
-
}), /*#__PURE__*/_jsxs(View, {
|
|
99
|
-
style: styles.main,
|
|
100
|
-
children: [/*#__PURE__*/_jsxs(Text, {
|
|
101
|
-
style: styles.name,
|
|
102
|
-
numberOfLines: 1,
|
|
103
|
-
testID: `${assetRowTestID(record.name, record.type)}-name`,
|
|
104
|
-
children: [record.name, /*#__PURE__*/_jsxs(Text, {
|
|
105
|
-
style: styles.ext,
|
|
106
|
-
children: [".", record.type]
|
|
107
|
-
})]
|
|
108
|
-
}), /*#__PURE__*/_jsxs(View, {
|
|
109
|
-
style: styles.metaRow,
|
|
110
|
-
children: [record.kind === "image" && record.width != null ? /*#__PURE__*/_jsx(Text, {
|
|
111
|
-
style: styles.meta,
|
|
112
|
-
children: formatDimensions(record)
|
|
113
|
-
}) : null, record.kind === "image" && record.scales.length ? /*#__PURE__*/_jsx(Text, {
|
|
114
|
-
style: styles.meta,
|
|
115
|
-
children: formatScales(record.scales)
|
|
116
|
-
}) : null]
|
|
117
|
-
})]
|
|
118
|
-
}), /*#__PURE__*/_jsxs(View, {
|
|
119
|
-
style: styles.right,
|
|
120
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
121
|
-
style: styles.size,
|
|
122
|
-
testID: `${assetRowTestID(record.name, record.type)}-size`,
|
|
123
|
-
children: formatSize(record, estDecodedBytes(record))
|
|
124
|
-
}), badges.length ? /*#__PURE__*/_jsx(View, {
|
|
125
|
-
style: styles.badgeRow,
|
|
126
|
-
children: badges.slice(0, 3).map(b => /*#__PURE__*/_jsx(Badge, {
|
|
127
|
-
label: b.label,
|
|
128
|
-
color: b.color,
|
|
129
|
-
testID: assetBadgeTestID(record.name, record.type, b.label)
|
|
130
|
-
}, b.label))
|
|
131
|
-
}) : null]
|
|
132
|
-
})]
|
|
133
|
-
}), sizeFraction > 0 ? /*#__PURE__*/_jsx(View, {
|
|
134
|
-
style: styles.sizeTrack,
|
|
135
|
-
children: /*#__PURE__*/_jsx(View, {
|
|
136
|
-
style: [styles.sizeFill, {
|
|
137
|
-
backgroundColor: accent,
|
|
138
|
-
width: `${Math.max(2, Math.round(sizeFraction * 100))}%`
|
|
139
|
-
}]
|
|
140
|
-
})
|
|
141
|
-
}) : null]
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
const styles = StyleSheet.create({
|
|
145
|
-
card: {
|
|
146
|
-
marginHorizontal: 10,
|
|
147
|
-
marginTop: 6,
|
|
148
|
-
borderRadius: 10,
|
|
149
|
-
backgroundColor: night.color.surface,
|
|
150
|
-
borderWidth: 1,
|
|
151
|
-
borderColor: night.color.border,
|
|
152
|
-
overflow: "hidden"
|
|
153
|
-
},
|
|
154
|
-
body: {
|
|
155
|
-
flexDirection: "row",
|
|
156
|
-
alignItems: "center",
|
|
157
|
-
paddingVertical: 8,
|
|
158
|
-
paddingHorizontal: 12,
|
|
159
|
-
gap: 10
|
|
160
|
-
},
|
|
161
|
-
thumbBox: {
|
|
162
|
-
width: 40,
|
|
163
|
-
height: 40,
|
|
164
|
-
borderRadius: 8,
|
|
165
|
-
// Light plate so dark glyph assets stay visible on the dark card.
|
|
166
|
-
backgroundColor: "rgba(255,255,255,0.10)",
|
|
167
|
-
borderWidth: 1,
|
|
168
|
-
borderColor: night.color.border,
|
|
169
|
-
alignItems: "center",
|
|
170
|
-
justifyContent: "center",
|
|
171
|
-
overflow: "hidden"
|
|
172
|
-
},
|
|
173
|
-
thumb: {
|
|
174
|
-
width: 34,
|
|
175
|
-
height: 34
|
|
176
|
-
},
|
|
177
|
-
thumbFallback: {
|
|
178
|
-
fontSize: 9,
|
|
179
|
-
fontWeight: "700",
|
|
180
|
-
letterSpacing: 0.5
|
|
181
|
-
},
|
|
182
|
-
main: {
|
|
183
|
-
flex: 1,
|
|
184
|
-
gap: 3
|
|
185
|
-
},
|
|
186
|
-
name: {
|
|
187
|
-
color: night.color.text,
|
|
188
|
-
fontSize: 12,
|
|
189
|
-
fontWeight: "600"
|
|
190
|
-
},
|
|
191
|
-
ext: {
|
|
192
|
-
color: night.color.textTertiary,
|
|
193
|
-
fontWeight: "400"
|
|
194
|
-
},
|
|
195
|
-
metaRow: {
|
|
196
|
-
flexDirection: "row",
|
|
197
|
-
alignItems: "center",
|
|
198
|
-
gap: 8
|
|
199
|
-
},
|
|
200
|
-
meta: {
|
|
201
|
-
color: night.color.textSecondary,
|
|
202
|
-
fontSize: 10,
|
|
203
|
-
fontVariant: ["tabular-nums"]
|
|
204
|
-
},
|
|
205
|
-
right: {
|
|
206
|
-
alignItems: "flex-end",
|
|
207
|
-
gap: 4
|
|
208
|
-
},
|
|
209
|
-
size: {
|
|
210
|
-
color: night.color.text,
|
|
211
|
-
fontSize: 12,
|
|
212
|
-
fontWeight: "700",
|
|
213
|
-
fontVariant: ["tabular-nums"]
|
|
214
|
-
},
|
|
215
|
-
badgeRow: {
|
|
216
|
-
flexDirection: "row",
|
|
217
|
-
gap: 4
|
|
218
|
-
},
|
|
219
|
-
sizeTrack: {
|
|
220
|
-
height: 2,
|
|
221
|
-
backgroundColor: "transparent"
|
|
222
|
-
},
|
|
223
|
-
sizeFill: {
|
|
224
|
-
height: 2,
|
|
225
|
-
opacity: 0.45,
|
|
226
|
-
borderTopRightRadius: 2
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
//# sourceMappingURL=AssetRow.js.map
|
|
1
|
+
"use strict";import{StyleSheet,Text,TouchableOpacity,View}from"react-native";import{macOSColors,night,Pill}from"@buoy-gg/shared-ui";import{AssetImage}from"./AssetImage";import{formatDimensions,formatScales,formatSize,KIND_COLORS,KIND_LABELS}from"../format";import{estDecodedBytes}from"../store/assetStore";import{assetBadgeTestID,assetRowTestID}from"../utils/testIDs";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";function Badge({label:e,color:t,testID:s}){return _jsx(Pill,{label:e,color:t,variant:"quiet",dot:Boolean(t),style:{paddingVertical:2.5},testID:s})}export function AssetRow({record:e,flags:t,sizeFraction:s,onPress:o}){const l=KIND_COLORS[e.kind],r=[];return e.loaded||r.push({label:"NOT OBSERVED"}),t.oversize&&r.push({label:"OVERSIZE",color:macOSColors.semantic.error}),t.duplicate&&r.push({label:"DUP"}),t.heavy&&r.push({label:"HEAVY"}),t.scaleAnomaly?r.push({label:"BAD SCALE",color:macOSColors.semantic.error}):t.scaleGap&&r.push({label:"LOW-RES"}),t.webp&&r.push({label:"WEBP",color:macOSColors.semantic.info}),_jsxs(TouchableOpacity,{style:styles.card,testID:assetRowTestID(e.name,e.type),onPress:()=>o(e.id),activeOpacity:.7,children:[_jsxs(View,{style:styles.body,children:[_jsx(View,{style:styles.thumbBox,children:"image"===e.kind?_jsx(AssetImage,{testID:"buoy-internal-assets-thumb",record:e,style:styles.thumb,compact:!0}):_jsx(Text,{style:[styles.thumbFallback,{color:l}],children:KIND_LABELS[e.kind]})}),_jsxs(View,{style:styles.main,children:[_jsxs(Text,{style:styles.name,numberOfLines:1,testID:`${assetRowTestID(e.name,e.type)}-name`,children:[e.name,_jsxs(Text,{style:styles.ext,children:[".",e.type]})]}),_jsxs(View,{style:styles.metaRow,children:["image"===e.kind&&null!=e.width?_jsx(Text,{style:styles.meta,children:formatDimensions(e)}):null,"image"===e.kind&&e.scales.length?_jsx(Text,{style:styles.meta,children:formatScales(e.scales)}):null]})]}),_jsxs(View,{style:styles.right,children:[_jsx(Text,{style:styles.size,testID:`${assetRowTestID(e.name,e.type)}-size`,children:formatSize(e,estDecodedBytes(e))}),r.length?_jsx(View,{style:styles.badgeRow,children:r.slice(0,3).map(t=>_jsx(Badge,{label:t.label,color:t.color,testID:assetBadgeTestID(e.name,e.type,t.label)},t.label))}):null]})]}),s>0?_jsx(View,{style:styles.sizeTrack,children:_jsx(View,{style:[styles.sizeFill,{backgroundColor:l,width:`${Math.max(2,Math.round(100*s))}%`}]})}):null]})}const styles=StyleSheet.create({card:{marginHorizontal:10,marginTop:6,borderRadius:10,backgroundColor:night.color.surface,borderWidth:1,borderColor:night.color.border,overflow:"hidden"},body:{flexDirection:"row",alignItems:"center",paddingVertical:8,paddingHorizontal:12,gap:10},thumbBox:{width:40,height:40,borderRadius:8,backgroundColor:"rgba(255,255,255,0.10)",borderWidth:1,borderColor:night.color.border,alignItems:"center",justifyContent:"center",overflow:"hidden"},thumb:{width:34,height:34},thumbFallback:{fontSize:9,fontWeight:"700",letterSpacing:.5},main:{flex:1,gap:3},name:{color:night.color.text,fontSize:12,fontWeight:"600"},ext:{color:night.color.textTertiary,fontWeight:"400"},metaRow:{flexDirection:"row",alignItems:"center",gap:8},meta:{color:night.color.textSecondary,fontSize:10,fontVariant:["tabular-nums"]},right:{alignItems:"flex-end",gap:4},size:{color:night.color.text,fontSize:12,fontWeight:"700",fontVariant:["tabular-nums"]},badgeRow:{flexDirection:"row",gap:4},sizeTrack:{height:2,backgroundColor:"transparent"},sizeFill:{height:2,opacity:.45,borderTopRightRadius:2}});
|
|
@@ -1,92 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* AssetsFilterBar — kind filter pills with counts, styled like the network
|
|
5
|
-
* tool's bordered pills: outlined, kind-accent-colored when active. Wrapping
|
|
6
|
-
* row, not a horizontal ScrollView (same height-measurement pitfall the
|
|
7
|
-
* images tool documents).
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
11
|
-
import { night } from "@buoy-gg/shared-ui";
|
|
12
|
-
import { KIND_COLORS, KIND_LABELS } from "../format";
|
|
13
|
-
import { ASSETS_TEST_IDS, assetFilterTestID } from "../utils/testIDs";
|
|
14
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
15
|
-
export function AssetsFilterBar({
|
|
16
|
-
stats,
|
|
17
|
-
filter,
|
|
18
|
-
onChange
|
|
19
|
-
}) {
|
|
20
|
-
const chips = [{
|
|
21
|
-
key: "all",
|
|
22
|
-
label: `ALL ${stats.total}`,
|
|
23
|
-
accent: night.color.textSecondary
|
|
24
|
-
}];
|
|
25
|
-
for (const kind of Object.keys(stats.byKind)) {
|
|
26
|
-
const entry = stats.byKind[kind];
|
|
27
|
-
if (entry.count > 0) {
|
|
28
|
-
chips.push({
|
|
29
|
-
key: kind,
|
|
30
|
-
label: `${KIND_LABELS[kind]} ${entry.count}`,
|
|
31
|
-
accent: KIND_COLORS[kind]
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (stats.neverLoaded > 0) {
|
|
36
|
-
// Amber, not semantic.warning — the bright yellow reads as an alarm.
|
|
37
|
-
chips.push({
|
|
38
|
-
key: "unused",
|
|
39
|
-
label: `UNUSED ${stats.neverLoaded}`,
|
|
40
|
-
accent: "#FF9F1C"
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
if (chips.length <= 1) return null;
|
|
44
|
-
return /*#__PURE__*/_jsx(View, {
|
|
45
|
-
style: styles.bar,
|
|
46
|
-
testID: ASSETS_TEST_IDS.filterBar,
|
|
47
|
-
children: chips.map(chip => {
|
|
48
|
-
const active = chip.key === filter;
|
|
49
|
-
return /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
50
|
-
testID: assetFilterTestID(chip.key),
|
|
51
|
-
style: [styles.chip, active && {
|
|
52
|
-
borderColor: chip.accent,
|
|
53
|
-
backgroundColor: `${chip.accent}1A`
|
|
54
|
-
}]
|
|
55
|
-
// Tapping the active chip again untoggles back to ALL.
|
|
56
|
-
,
|
|
57
|
-
onPress: () => onChange(active ? "all" : chip.key),
|
|
58
|
-
children: /*#__PURE__*/_jsx(Text, {
|
|
59
|
-
testID: `${assetFilterTestID(chip.key)}-label`,
|
|
60
|
-
style: [styles.chipText, {
|
|
61
|
-
color: active ? chip.accent : night.color.textSecondary
|
|
62
|
-
}],
|
|
63
|
-
children: chip.label
|
|
64
|
-
})
|
|
65
|
-
}, chip.key);
|
|
66
|
-
})
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
const styles = StyleSheet.create({
|
|
70
|
-
bar: {
|
|
71
|
-
flexDirection: "row",
|
|
72
|
-
flexWrap: "wrap",
|
|
73
|
-
gap: 6,
|
|
74
|
-
paddingHorizontal: 10,
|
|
75
|
-
paddingVertical: 8
|
|
76
|
-
},
|
|
77
|
-
chip: {
|
|
78
|
-
borderWidth: 1,
|
|
79
|
-
borderColor: night.color.border,
|
|
80
|
-
backgroundColor: night.color.surface,
|
|
81
|
-
borderRadius: 999,
|
|
82
|
-
paddingHorizontal: 10,
|
|
83
|
-
paddingVertical: 5
|
|
84
|
-
},
|
|
85
|
-
chipText: {
|
|
86
|
-
fontSize: 10,
|
|
87
|
-
fontWeight: "700",
|
|
88
|
-
letterSpacing: 0.4,
|
|
89
|
-
lineHeight: 13
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
//# sourceMappingURL=AssetsFilterBar.js.map
|
|
1
|
+
"use strict";import{StyleSheet,Text,TouchableOpacity,View}from"react-native";import{night}from"@buoy-gg/shared-ui";import{KIND_COLORS,KIND_LABELS}from"../format";import{ASSETS_TEST_IDS,assetFilterTestID}from"../utils/testIDs";import{jsx as _jsx}from"react/jsx-runtime";export function AssetsFilterBar({stats:e,duplicateCount:t,filter:r,onChange:o}){const l=[{key:"all",label:`ALL ${e.total}`,accent:night.color.textSecondary},{key:"duplicates",label:`DUPLICATES ${t}`,accent:"#FF9F1C"}];for(const t of Object.keys(e.byKind)){const r=e.byKind[t];r.count>0&&l.push({key:t,label:`${KIND_LABELS[t]} ${r.count}`,accent:KIND_COLORS[t]})}return e.neverLoaded>0&&l.push({key:"unused",label:`NOT OBSERVED ${e.neverLoaded}`,accent:"#FF9F1C"}),l.length<=1?null:_jsx(View,{style:styles.bar,testID:ASSETS_TEST_IDS.filterBar,children:l.map(e=>{const t=e.key===r;return _jsx(TouchableOpacity,{accessibilityRole:"button",accessibilityState:{selected:t},testID:assetFilterTestID(e.key),style:[styles.chip,t&&{borderColor:e.accent,backgroundColor:`${e.accent}1A`}],onPress:()=>o(t?"all":e.key),children:_jsx(Text,{testID:`${assetFilterTestID(e.key)}-label`,style:[styles.chipText,{color:t?e.accent:night.color.textSecondary}],children:e.label})},e.key)})})}const styles=StyleSheet.create({bar:{flexDirection:"row",flexWrap:"wrap",gap:6,paddingHorizontal:10,paddingVertical:8},chip:{borderWidth:1,borderColor:night.color.border,backgroundColor:night.color.surface,borderRadius:999,paddingHorizontal:10,paddingVertical:5},chipText:{fontSize:10,fontWeight:"700",letterSpacing:.4,lineHeight:13}});
|
|
@@ -1,68 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* AssetsHeader — shared ModalHeader wiring, matching the Images/Console
|
|
5
|
-
* header pattern. List mode shows inventory totals plus the shared
|
|
6
|
-
* ToolbarCopyButton (full markdown report); detail mode shows back
|
|
7
|
-
* navigation and the single-asset report.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { ModalHeader, ToolbarClearButton, ToolbarCopyButton } from "@buoy-gg/shared-ui";
|
|
11
|
-
import { formatBytes } from "../format";
|
|
12
|
-
import { ASSETS_TEST_IDS } from "../utils/testIDs";
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
export function AssetsHeader({
|
|
15
|
-
stats,
|
|
16
|
-
measuring,
|
|
17
|
-
detailOpen,
|
|
18
|
-
detailIndex = -1,
|
|
19
|
-
detailTotal = 0,
|
|
20
|
-
onCloseDetail,
|
|
21
|
-
onClear,
|
|
22
|
-
getReport,
|
|
23
|
-
onBack
|
|
24
|
-
}) {
|
|
25
|
-
if (detailOpen) {
|
|
26
|
-
const counter = detailIndex >= 0 && detailTotal > 0 ? `${detailIndex + 1} of ${detailTotal}` : undefined;
|
|
27
|
-
return /*#__PURE__*/_jsxs(ModalHeader, {
|
|
28
|
-
children: [/*#__PURE__*/_jsx(ModalHeader.Navigation, {
|
|
29
|
-
onBack: onCloseDetail
|
|
30
|
-
}), /*#__PURE__*/_jsx(ModalHeader.Content, {
|
|
31
|
-
title: "Asset detail",
|
|
32
|
-
subtitle: counter,
|
|
33
|
-
testID: ASSETS_TEST_IDS.title
|
|
34
|
-
}), /*#__PURE__*/_jsx(ModalHeader.Actions, {
|
|
35
|
-
children: /*#__PURE__*/_jsx(ToolbarCopyButton, {
|
|
36
|
-
value: getReport,
|
|
37
|
-
testID: ASSETS_TEST_IDS.copy
|
|
38
|
-
})
|
|
39
|
-
})]
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
const subtitleParts = [`${stats.total} assets`];
|
|
43
|
-
// A mid-measure byte total reads as nonsense ("653 B+") — wait it out.
|
|
44
|
-
if (stats.totalBytes > 0 && !measuring) {
|
|
45
|
-
const partial = stats.measuredCount < stats.total ? "+" : "";
|
|
46
|
-
subtitleParts.push(`${formatBytes(stats.totalBytes)}${partial}`);
|
|
47
|
-
}
|
|
48
|
-
if (stats.neverLoaded > 0) subtitleParts.push(`${stats.neverLoaded} never loaded`);
|
|
49
|
-
if (stats.fontFamilies > 0) subtitleParts.push(`${stats.fontFamilies} fonts`);
|
|
50
|
-
return /*#__PURE__*/_jsxs(ModalHeader, {
|
|
51
|
-
children: [onBack ? /*#__PURE__*/_jsx(ModalHeader.Navigation, {
|
|
52
|
-
onBack: onBack
|
|
53
|
-
}) : null, /*#__PURE__*/_jsx(ModalHeader.Content, {
|
|
54
|
-
title: "Assets",
|
|
55
|
-
subtitle: subtitleParts.join(" · "),
|
|
56
|
-
testID: ASSETS_TEST_IDS.title
|
|
57
|
-
}), /*#__PURE__*/_jsxs(ModalHeader.Actions, {
|
|
58
|
-
children: [/*#__PURE__*/_jsx(ToolbarCopyButton, {
|
|
59
|
-
value: getReport,
|
|
60
|
-
testID: ASSETS_TEST_IDS.copy
|
|
61
|
-
}), /*#__PURE__*/_jsx(ToolbarClearButton, {
|
|
62
|
-
onPress: onClear,
|
|
63
|
-
testID: ASSETS_TEST_IDS.clear
|
|
64
|
-
})]
|
|
65
|
-
})]
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
//# sourceMappingURL=AssetsHeader.js.map
|
|
1
|
+
"use strict";import{ModalHeader,ToolbarClearButton,ToolbarCopyButton}from"@buoy-gg/shared-ui";import{formatBytes}from"../format";import{ASSETS_TEST_IDS}from"../utils/testIDs";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export function AssetsHeader({stats:t,measuring:e,discovering:o=!1,detailOpen:s,detailIndex:a=-1,detailTotal:r=0,onCloseDetail:l,onClear:n,getReport:i,onBack:d}){if(s){const t=a>=0&&r>0?`${a+1} of ${r}`:void 0;return _jsxs(ModalHeader,{children:[_jsx(ModalHeader.Navigation,{onBack:l}),_jsx(ModalHeader.Content,{title:"Asset detail",subtitle:t,testID:ASSETS_TEST_IDS.title}),_jsx(ModalHeader.Actions,{children:_jsx(ToolbarCopyButton,{value:i,testID:ASSETS_TEST_IDS.copy})})]})}const S=[`${t.total} assets${o?" so far":""}`];if(t.totalBytes>0&&!e&&!o){const e=t.measuredCount<t.total?"+":"";S.push(`${formatBytes(t.totalBytes)}${e}`)}return t.neverLoaded>0&&S.push(`${t.neverLoaded} not observed`),t.fontFamilies>0&&S.push(`${t.fontFamilies} fonts`),_jsxs(ModalHeader,{children:[d?_jsx(ModalHeader.Navigation,{onBack:d}):null,_jsx(ModalHeader.Content,{title:"Assets",subtitle:S.join(" · "),testID:ASSETS_TEST_IDS.title}),_jsxs(ModalHeader.Actions,{children:[_jsx(ToolbarCopyButton,{value:i,testID:ASSETS_TEST_IDS.copy}),_jsx(ToolbarClearButton,{onPress:n,testID:ASSETS_TEST_IDS.clear})]})]})}
|
|
@@ -1,12 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* AssetsIcon — re-exported from the Buoy Icon Format.
|
|
5
|
-
*
|
|
6
|
-
* The artwork lives in shared/icons/assets.json and is generated into
|
|
7
|
-
* @buoy-gg/floating-tools-core, so React Native, the desktop dashboard and
|
|
8
|
-
* Flutter all render the same drawing. Edit the JSON, then `pnpm icons`.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export { AssetsIcon, ASSETS_ICON_COLOR } from "@buoy-gg/shared-ui";
|
|
12
|
-
//# sourceMappingURL=AssetsIcon.js.map
|
|
1
|
+
"use strict";export{AssetsIcon,ASSETS_ICON_COLOR}from"@buoy-gg/shared-ui";
|
|
@@ -1,92 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* AssetsListControls — one compact row: name search, sort cycle (SIZE →
|
|
5
|
-
* NAME → TYPE), and — when no baseline exists yet — the BASE button that
|
|
6
|
-
* saves one. Once a baseline exists the BaselineBar takes over the diff UI,
|
|
7
|
-
* so this row never wastes space on a hint sentence.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { StyleSheet, Text, TextInput, TouchableOpacity, View } from "react-native";
|
|
11
|
-
import { night } from "@buoy-gg/shared-ui";
|
|
12
|
-
import { saveBaseline } from "../store/baseline";
|
|
13
|
-
import { ASSETS_TEST_IDS } from "../utils/testIDs";
|
|
14
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
-
const NEXT_SORT = {
|
|
16
|
-
size: "name",
|
|
17
|
-
name: "type",
|
|
18
|
-
type: "size"
|
|
19
|
-
};
|
|
20
|
-
export function AssetsListControls({
|
|
21
|
-
query,
|
|
22
|
-
onQueryChange,
|
|
23
|
-
sort,
|
|
24
|
-
onSortChange,
|
|
25
|
-
showBaselineButton
|
|
26
|
-
}) {
|
|
27
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
28
|
-
style: styles.row,
|
|
29
|
-
children: [/*#__PURE__*/_jsx(TextInput, {
|
|
30
|
-
style: styles.input,
|
|
31
|
-
value: query,
|
|
32
|
-
onChangeText: onQueryChange,
|
|
33
|
-
placeholder: "Search assets\u2026",
|
|
34
|
-
placeholderTextColor: night.color.placeholder,
|
|
35
|
-
autoCapitalize: "none",
|
|
36
|
-
autoCorrect: false,
|
|
37
|
-
testID: ASSETS_TEST_IDS.search
|
|
38
|
-
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
39
|
-
style: styles.button,
|
|
40
|
-
onPress: () => onSortChange(NEXT_SORT[sort]),
|
|
41
|
-
testID: ASSETS_TEST_IDS.sort,
|
|
42
|
-
children: /*#__PURE__*/_jsxs(Text, {
|
|
43
|
-
style: styles.buttonText,
|
|
44
|
-
testID: `${ASSETS_TEST_IDS.sort}-label`,
|
|
45
|
-
children: ["\u2193 ", sort.toUpperCase()]
|
|
46
|
-
})
|
|
47
|
-
}), showBaselineButton ? /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
48
|
-
style: styles.button,
|
|
49
|
-
onPress: () => void saveBaseline(),
|
|
50
|
-
testID: ASSETS_TEST_IDS.saveBaseline,
|
|
51
|
-
children: /*#__PURE__*/_jsx(Text, {
|
|
52
|
-
style: styles.buttonText,
|
|
53
|
-
children: "BASE"
|
|
54
|
-
})
|
|
55
|
-
}) : null]
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
const styles = StyleSheet.create({
|
|
59
|
-
row: {
|
|
60
|
-
flexDirection: "row",
|
|
61
|
-
alignItems: "center",
|
|
62
|
-
gap: 8,
|
|
63
|
-
paddingHorizontal: 10,
|
|
64
|
-
paddingBottom: 8
|
|
65
|
-
},
|
|
66
|
-
input: {
|
|
67
|
-
flex: 1,
|
|
68
|
-
backgroundColor: night.color.surfaceElevated,
|
|
69
|
-
borderWidth: 1,
|
|
70
|
-
borderColor: night.color.border,
|
|
71
|
-
borderRadius: 8,
|
|
72
|
-
paddingHorizontal: 10,
|
|
73
|
-
paddingVertical: 6,
|
|
74
|
-
color: night.color.text,
|
|
75
|
-
fontSize: 12
|
|
76
|
-
},
|
|
77
|
-
button: {
|
|
78
|
-
backgroundColor: night.color.surface,
|
|
79
|
-
borderWidth: 1,
|
|
80
|
-
borderColor: night.color.border,
|
|
81
|
-
borderRadius: 8,
|
|
82
|
-
paddingHorizontal: 10,
|
|
83
|
-
paddingVertical: 7
|
|
84
|
-
},
|
|
85
|
-
buttonText: {
|
|
86
|
-
color: night.color.textSecondary,
|
|
87
|
-
fontSize: 10,
|
|
88
|
-
fontWeight: "700",
|
|
89
|
-
letterSpacing: 0.5
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
//# sourceMappingURL=AssetsListControls.js.map
|
|
1
|
+
"use strict";import{StyleSheet,Text,TextInput,TouchableOpacity,View}from"react-native";import{night}from"@buoy-gg/shared-ui";import{ASSETS_TEST_IDS}from"../utils/testIDs";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const NEXT_SORT={size:"name",name:"type",type:"size"};export function AssetsListControls({query:t,onQueryChange:e,sort:o,onSortChange:r}){return _jsxs(View,{style:styles.row,children:[_jsx(TextInput,{style:styles.input,value:t,onChangeText:e,placeholder:"Search assets…",placeholderTextColor:night.color.placeholder,autoCapitalize:"none",autoCorrect:!1,testID:ASSETS_TEST_IDS.search}),_jsx(TouchableOpacity,{style:styles.button,onPress:()=>r(NEXT_SORT[o]),testID:ASSETS_TEST_IDS.sort,children:_jsxs(Text,{style:styles.buttonText,testID:`${ASSETS_TEST_IDS.sort}-label`,children:["↓ ",o.toUpperCase()]})})]})}const styles=StyleSheet.create({row:{flexDirection:"row",alignItems:"center",gap:8,paddingHorizontal:10,paddingBottom:8},input:{flex:1,backgroundColor:night.color.surfaceElevated,borderWidth:1,borderColor:night.color.border,borderRadius:8,paddingHorizontal:10,paddingVertical:6,color:night.color.text,fontSize:12},button:{backgroundColor:night.color.surface,borderWidth:1,borderColor:night.color.border,borderRadius:8,paddingHorizontal:10,paddingVertical:7},buttonText:{color:night.color.textSecondary,fontSize:10,fontWeight:"700",letterSpacing:.5}});
|