Skip to content

Commit f9b9b60

Browse files
committed
feat: update ChainSelector and SelectTrigger components for enhanced styling and functionality
1 parent 696fa00 commit f9b9b60

File tree

3 files changed

+66
-35
lines changed

3 files changed

+66
-35
lines changed

.vitepress/theme/style.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,15 @@
7676
--color-danger-2: var(--vp-c-red-2);
7777
--color-danger-3: var(--vp-c-red-3);
7878
--color-danger-soft: var(--vp-c-red-soft);
79+
80+
/* ShadCN */
81+
--color-muted-foreground: var(--vp-c-text-3);
82+
--color-ring: var(--vp-c-brand-2);
83+
--color-destructive: var(--vp-c-red-2);
84+
--color-popover: var(--vp-c-bg);
85+
--color-popover-foreground: var(--vp-c-text-1);
86+
--color-accent: var(--vp-c-bg-soft);
87+
--color-accent-foreground: var(--vp-c-text-1);
7988
}
8089

8190
:root {

src/components/ChainSelector.vue

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,55 @@
11
<template>
2-
<Select>
3-
<SelectTrigger>
4-
<SelectValue placeholder="Select Chain" />
5-
</SelectTrigger>
6-
<SelectContent>
7-
<SelectGroup
8-
v-for="chain in filteredChains"
9-
:key="chain.id"
10-
:value="chain.id.toString()"
11-
:class="className"
12-
>
13-
<SelectItem :value="chain.id.toString()">
14-
<img :src="chain.icon" class="size-4" :alt="chain.name" />
15-
{{ chain.name }}
2+
<div class="flex items-center">
3+
<Select v-model="selectedChainId" :class="className">
4+
<SelectTrigger>
5+
<SelectValue :placeholder="selectedChain?.name || 'Select chain'">
6+
<div v-if="selectedChain" class="flex items-center gap-2">
7+
<img
8+
v-if="selectedChain.icon"
9+
:src="selectedChain.icon"
10+
:alt="selectedChain.name"
11+
class="h-4 w-4 rounded-full"
12+
/>
13+
<span>{{ selectedChain.name }}</span>
14+
</div>
15+
<span v-else>Select Chain</span>
16+
</SelectValue>
17+
</SelectTrigger>
18+
19+
<SelectContent>
20+
<SelectItem
21+
v-for="chain in filteredChains"
22+
:key="chain.id"
23+
:value="chain.id.toString()"
24+
>
25+
<SelectItemText>
26+
<div class="flex items-center gap-2">
27+
<img
28+
v-if="chain.icon"
29+
:src="chain.icon"
30+
:alt="chain.name"
31+
class="h-4 w-4 rounded-full"
32+
/>
33+
<span>{{ chain.name }}</span>
34+
</div>
35+
</SelectItemText>
1636
</SelectItem>
17-
</SelectGroup>
18-
</SelectContent>
19-
</Select>
37+
</SelectContent>
38+
</Select>
39+
</div>
2040
</template>
2141

2242
<script setup lang="ts">
23-
import { computed } from 'vue';
43+
import { computed, watch } from 'vue';
2444
import { useAccount } from '@wagmi/vue';
2545
import { useChainSwitch } from '@/hooks/useChainSwitch';
2646
import { getSupportedChains, getChainById } from '@/utils/chain.utils';
2747
import useUserStore from '@/stores/useUser.store';
2848
import {
2949
Select,
3050
SelectContent,
31-
SelectGroup,
3251
SelectItem,
52+
SelectItemText,
3353
SelectTrigger,
3454
SelectValue,
3555
} from '@/components/ui/select';
@@ -49,32 +69,34 @@ const userStore = useUserStore();
4969
const filteredChains = getSupportedChains();
5070
5171
// Computed
72+
const selectedChain = computed(() => {
73+
const currentChainId = chainId.value || userStore.chainId;
74+
return currentChainId ? getChainById(currentChainId) : undefined;
75+
});
76+
5277
const selectedChainId = computed({
5378
get: () => {
54-
return (chainId.value || userStore.chainId || -1).toString();
79+
const currentChainId = chainId.value || userStore.chainId;
80+
return currentChainId ? currentChainId.toString() : '';
5581
},
56-
set: (value: string) => {
82+
set: async (value: string) => {
5783
const numericValue = Number(value);
58-
if (numericValue !== -1) {
84+
if (numericValue && numericValue !== -1) {
5985
const chain = getChainById(numericValue);
6086
if (chain) {
6187
userStore.setSelectedChain(chain);
88+
await requestChainChange(numericValue);
6289
}
6390
}
6491
},
6592
});
6693
67-
// Methods
68-
async function handleChainChange(value: string) {
69-
const numericValue = Number(value);
70-
71-
if (numericValue === -1) return;
72-
73-
const chain = getChainById(numericValue);
74-
if (chain) {
75-
userStore.setSelectedChain(chain);
76-
77-
await requestChainChange(numericValue);
94+
watch(chainId, (newChainId) => {
95+
if (newChainId) {
96+
const chain = getChainById(newChainId);
97+
if (chain) {
98+
userStore.setSelectedChain(chain);
99+
}
78100
}
79-
}
101+
});
80102
</script>

src/components/ui/select/SelectTrigger.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const forwardedProps = useForwardProps(delegatedProps);
2727
v-bind="forwardedProps"
2828
:class="
2929
cn(
30-
`border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,
30+
`border-border! data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 aria-invalid:border-destructive bg-soft-bg! flex w-fit items-center justify-between gap-2 rounded-md border px-3! py-2! text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,
3131
props.class
3232
)
3333
"

0 commit comments

Comments
 (0)