Skip to content

Commit 80719af

Browse files
committed
fix: tablist ui
1 parent 1ad9371 commit 80719af

File tree

3 files changed

+76
-69
lines changed

3 files changed

+76
-69
lines changed

app.vue

Lines changed: 58 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,58 @@
22
<div class="flex">
33
<div class="p-1 box-content w-[calc(100%+40px)] mx-auto max-w-[935px] grow">
44
<Header />
5-
<div role="tablist" class="border-t border-[#dbdbdb] dark:border-neutral-800 box-border items-center grid grid-cols-3 gap-1 relative">
6-
<div class="flex flex-row text-center dark:text-[#a8a8a8]">
7-
<label class="group w-full block relative py-1 focus-within:border-[#353535] border border-transparent rounded-full">
8-
<button class="flex relative gap-2 w-full">
9-
<div class="cursor-pointer py-1.5 -my-2 group-focus-within:-mr-4 group-focus-within:invisible">
10-
<Icon name="heroicons-outline:magnifying-glass" size="20"></Icon>
11-
</div>
12-
<div class="relative flex-grow">
13-
<input
14-
class="w-full bg-transparent outline-none placeholder:text-[#a8a8a8]"
15-
type="text"
16-
v-model="searchTerm"
17-
:placeholder="selectedCategory ? `Search in ${selectedCategory}` : 'Search'" />
18-
</div>
19-
<div @click="searchTerm = null" class="cursor-pointer py-1.5 -my-2 mr-2 group-focus-within:visible invisible">
20-
<Icon v-if="!loading" name="mingcute:close-circle-fill" size="20" />
21-
<Icon v-else-if="loading" name="Loading" size="20" />
5+
<div role="tablist" class="mb-4 flex items-stretch flex-col max-w-full">
6+
<div class="flex-row flex-nowrap flex items-center gap-4">
7+
<div class="flex-grow flex-shrink flex flex-col text-neutral-300 font-medium">
8+
<form
9+
class="flex-grow flex bg-white/10 h-10 transition-all pl-4 pr-3 rounded-xl border border-transparent hover:border-neutral-600 focus-within:border-neutral-600 focus-within:bg-neutral-800/30 group">
10+
<div class="flex items-center gap-4 w-full">
11+
<div class="flex text-neutral-500">
12+
<Icon name="majesticons:search-line" size="22"></Icon>
13+
</div>
14+
<div class="flex w-full">
15+
<input
16+
class="placeholder:text-neutral-500 bg-transparent outline-none w-full py-2"
17+
v-model="searchTerm"
18+
:placeholder="selectedCategory ? `Search in ${selectedCategory}` : 'Search'" />
19+
</div>
20+
<div @click="searchTerm = ''" class="flex transition-all cursor-pointer text-neutral-500 group-focus-within:visible invisible">
21+
<Icon v-if="!loading" name="solar:close-square-bold" size="24" />
22+
<Icon v-else-if="loading" name="Loading" size="20" />
23+
</div>
2224
</div>
23-
</button>
24-
</label>
25-
</div>
26-
<div class="justify-end flex gap-[60px] col-span-2">
25+
</form>
26+
</div>
2727
<div
2828
@click.stop="
2929
isDropdownCategory = !isDropdownCategory;
3030
isDropdownSortBy = false;
3131
"
32-
:class="{ activeTab: isDropdownCategory || selectedCategory }"
33-
class="items-center dark:text-[#a8a8a8] text-xs flex h-[52px] justify-center cursor-pointer border-t border-transparent -mt-px">
34-
<div class="flex box-border items-center">
35-
<Icon name="system-uicons:grid-squares" size="22" />
36-
<span class="ml-1.5 font-semibold uppercase tracking-wider select-none">Category</span>
32+
class="items-center text-sm justify-center cursor-pointer select-none font-semibold relative">
33+
<div class="flex box-border items-center active:scale-95 bg-white/10 hover:bg-white/20 h-10 transition-all py-1.5 pr-3 pl-4 rounded-xl">
34+
<span class="mr-3">{{ selectedCategory || 'All Categories' }}</span>
35+
<Icon name="ion:chevron-down-outline" size="14" />
3736
</div>
3837
<Transition>
39-
<div v-show="isDropdownCategory" class="absolute top-full z-10 right-[55px] dropdown text-neutral-100">
40-
<div class="dropdown-triangle left-[30%]"></div>
41-
<div class="text-sm bg-white dark:bg-neutral-800 rounded-2xl overflow-hidden">
42-
<div
43-
class="flex justify-between gap-3 px-4 py-2.5 hover:dark:bg-[#3c3c3c] hover:transition-all border-b dark:border-[#353535] last:border-b-0"
44-
@click="selectedCategory = ''">
45-
<div>All Categories</div>
46-
<Icon v-if="selectedCategory === ''" name="system-uicons:check" size="20" />
38+
<div
39+
v-if="isDropdownCategory"
40+
class="absolute top-full z-10 text-[13px] font-medium rounded-xl dark:bg-neutral-800/80 border border-white/10 backdrop-blur-xl left-0 mt-3">
41+
<div class="w-44 m-2">
42+
<div @click="selectedCategory = ''" class="py-2 px-3 rounded-lg hover:bg-white/5 transition-all duration-300">
43+
<div class="flex justify-between items-center">
44+
<div class="mr-4 w-full">All Categories</div>
45+
<Icon v-if="selectedCategory === ''" name="mingcute:check-line" size="16" />
46+
</div>
4747
</div>
4848
<div
49-
class="flex justify-between gap-3 px-4 py-2.5 hover:dark:bg-[#3c3c3c] hover:transition-all border-b dark:border-[#353535] last:border-b-0"
5049
v-for="category in categories"
5150
:key="category.id"
52-
@click="selectedCategory = category.name">
53-
<div>{{ category.name }}</div>
54-
<Icon v-if="selectedCategory === category.name" name="system-uicons:check" size="20" />
51+
@click="selectedCategory = category.name"
52+
class="py-2 px-3 rounded-lg hover:bg-white/5 transition-all duration-300">
53+
<div class="flex justify-between items-center">
54+
<div class="mr-4 w-full">{{ category.name }}</div>
55+
<Icon v-if="selectedCategory === category.name" name="mingcute:check-line" size="16" />
56+
</div>
5557
</div>
5658
</div>
5759
</div>
@@ -62,23 +64,25 @@
6264
isDropdownSortBy = !isDropdownSortBy;
6365
isDropdownCategory = false;
6466
"
65-
:class="{ activeTab: isDropdownSortBy || selectedOption !== 'Newest' }"
66-
class="items-center dark:text-[#a8a8a8] text-xs flex h-[52px] justify-center cursor-pointer border-t border-transparent -mt-px">
67-
<div class="flex box-border items-center">
68-
<Icon name="system-uicons:filter" size="22" />
69-
<span class="ml-1.5 font-semibold uppercase tracking-wider select-none">Sort by</span>
67+
class="items-center text-sm justify-center cursor-pointer select-none font-semibold relative">
68+
<div class="flex box-border items-center active:scale-95 bg-white/10 hover:bg-white/20 h-10 transition-all py-1.5 pr-3 pl-4 rounded-xl">
69+
<span class="mr-3">{{ selectedOption }}</span>
70+
<Icon name="ion:chevron-down-outline" size="14" />
7071
</div>
7172
<Transition>
72-
<div v-show="isDropdownSortBy" class="absolute top-full z-10 -right-[18px] dropdown text-neutral-100">
73-
<div class="dropdown-triangle left-[57%]"></div>
74-
<div class="text-sm bg-white dark:bg-neutral-800 rounded-2xl overflow-hidden">
73+
<div
74+
v-if="isDropdownSortBy"
75+
class="absolute top-full z-10 text-[13px] font-medium rounded-xl dark:bg-neutral-800/80 border border-white/10 backdrop-blur-xl right-0 mt-3">
76+
<div class="w-44 m-2">
7577
<div
76-
class="flex justify-between gap-3 px-4 py-2.5 hover:dark:bg-[#3c3c3c] hover:transition-all border-b dark:border-[#353535] last:border-b-0"
7778
v-for="(option, index) in options"
7879
:key="index"
79-
@click="selectedOption = option.value">
80-
<div>{{ option.value }}</div>
81-
<Icon v-if="selectedOption === option.value" name="system-uicons:check" size="20" />
80+
@click="selectedOption = option.value"
81+
class="py-2 px-3 rounded-lg hover:bg-white/5 transition-all duration-300">
82+
<div class="flex justify-between items-center">
83+
<div class="mr-4 w-full">{{ option.value }}</div>
84+
<Icon v-if="selectedOption === option.value" name="mingcute:check-line" size="16" />
85+
</div>
8286
</div>
8387
</div>
8488
</div>
@@ -255,33 +259,18 @@ watch([selectedOption, searchTerm, selectedCategory], ([newSelectedOption, newSe
255259
@apply bg-black text-neutral-100;
256260
color-scheme: dark;
257261
}
258-
.dropdown {
259-
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.15));
260-
}
261-
.dropdown-triangle {
262-
@apply absolute dark:bg-neutral-800 h-5 w-4 -top-[10px] rotate-90;
263-
clip-path: path('M8 0C8 4 9.32406e-08 7.819 1.25211e-07 10.5C1.57188e-07 13.1815 8 17.0005 8 21L8 0Z');
264-
}
265262
.v-enter-active {
266-
@apply transition ease-out duration-100;
263+
@apply transition ease-out duration-200;
267264
}
268265
.v-enter-from,
269266
.v-leave-to {
270-
@apply transform opacity-0 scale-95;
267+
@apply translate-y-5 opacity-0;
271268
}
272-
273269
.v-enter-to,
274270
.v-leave-from {
275-
@apply transform opacity-100 scale-100;
271+
@apply transform opacity-100;
276272
}
277-
278273
.v-leave-active {
279-
@apply transition ease-in duration-75;
280-
}
281-
.activeTab {
282-
@apply text-neutral-100 border-neutral-100;
283-
}
284-
.disabled {
285-
opacity: 0.4;
274+
@apply transition ease-in duration-150;
286275
}
287276
</style>

nuxt.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,13 @@ export default defineNuxtConfig({
77
},
88
},
99
},
10+
app: {
11+
head: {
12+
link: [
13+
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
14+
{ rel: 'preconnect', href: 'https://fonts.gstatic.com' },
15+
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap' },
16+
],
17+
},
18+
},
1019
});

tailwind.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
theme: {
3+
extend: {
4+
fontFamily: {
5+
sans: ['Inter', 'Helvetica', 'Arial', 'sans-serif'],
6+
},
7+
},
8+
},
9+
};

0 commit comments

Comments
 (0)