Jimin Huang
Change settings
452e071
raw
history blame
1.77 kB
<template>
<div class="flex gap-2 flex-wrap">
<button
v-for="code in orderedAssets" :key="code"
class="px-3 py-1 rounded-full border flex items-center gap-2"
:class="code===modelValue ? 'bg-black text-white' : 'bg-white'"
@click="$emit('update:modelValue', code)"
>
<img :src="iconFor(code)" alt="" class="asset-icon" decoding="async" loading="lazy" @error="hide($event)" />
<span>{{ code }}</span>
</button>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { dataService } from '../lib/dataService'
const props = defineProps({
modelValue: { type: String, default: '' },
preferredOrder: {
type: Array,
default: () => ['BTC','ETH','SOL','BNB','DOGE','XRP','AAPL','MSFT','BMRN','MRNA','TSLA']
}
})
const emit = defineEmits(['update:modelValue'])
// same pattern as your AssetsFilter.vue
const iconFor = (assetCode) =>
new URL(`../assets/images/assets_images/${assetCode}.png`, import.meta.url).href
const hide = (e) => { e.target.style.display = 'none' }
const available = computed(() => {
const rows = Array.isArray(dataService.tableRows) ? dataService.tableRows : []
return Array.from(new Set(rows.map(r => r.asset)))
})
const orderedAssets = computed(() => {
const present = new Set(available.value)
const primary = props.preferredOrder.filter(a => present.has(a))
const extras = [...present].filter(a => !props.preferredOrder.includes(a)).sort()
const list = [...primary, ...extras]
if (!list.includes(props.modelValue) && list.length) emit('update:modelValue', list[0])
return list
})
</script>
<style scoped>
.asset-icon{
width: 18px; height: 18px; flex: 0 0 18px;
object-fit: contain; display: inline-block; vertical-align: middle;
}
</style>