Skip to content

Commit

Permalink
#455 refactor topics dropdown to headless UI combobox
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtavis committed Nov 22, 2023
1 parent 064b828 commit 2437018
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 77 deletions.
103 changes: 103 additions & 0 deletions frontend/components/combobox/ComboboxTopics.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<template>
<div class="flex z-50">
<Combobox v-model="selectedTopic">
<div class="relative">
<div
class="flex relative w-full cursor-default overflow-hidden rounded-lg shadow-sm shadow-zinc-700 focus-brand"
>
<ComboboxInput
@change="query = $event.target.value"
class="w-full border border-light-text dark:border-dark-cta-orange bg-light-cta-orange dark:bg-dark-cta-orange/20 text-light-text dark:text-light-cta-orange py-2 pl-4 rounded-lg"
:displayValue="(_) => selectedTopic.name"
/>
<ComboboxButton
class="absolute inset-y-0 right-0 flex items-center pr-2 text-light-text dark:text-dark-cta-orange"
>
<Icon name="bi:chevron-expand" />
</ComboboxButton>
</div>
<TransitionRoot
@after-leave="query = ''"
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<ComboboxOptions
class="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-light-distinct dark:bg-dark-distinct py-1 text-base shadow-lg shadow-zinc-700 ring-1 ring-black/5 focus:outline-none sm:text-sm"
>
<div
v-if="filteredTopics.length === 0 && query !== ''"
class="relative cursor-default select-none px-4 py-2 text-light-special-text dark:text-dark-special-text"
>
{{ $t("components.combobox-topics.no-matching-topics") }}
</div>

<ComboboxOption
v-for="topic in filteredTopics"
v-slot="{ selected, active }"
:key="topic.id"
as="template"
:value="topic"
>
<li
class="relative cursor-default select-none py-2 pl-10 pr-4"
:class="{
'bg-light-cta-orange/80 text-light-text dark:bg-dark-cta-orange/40 dark:text-dark-cta-orange':
active,
'text-light-text dark:text-dark-text': !active,
}"
>
<span class="block truncate">
{{ topic.name }}
</span>
<span
v-if="selected"
class="absolute inset-y-0 left-0 flex items-center pl-3"
:class="{
'text-light-text dark:text-dark-cta-orange': active,
'text-light-cta-orange dark:text-dark-cta-orange': !active,
}"
>
<Icon name="bi:check-lg" />
</span>
</li>
</ComboboxOption>
</ComboboxOptions>
</TransitionRoot>
</div>
</Combobox>
</div>
</template>

<script setup lang="ts">
import {
Combobox,
ComboboxButton,
ComboboxInput,
ComboboxOption,
ComboboxOptions,
TransitionRoot,
} from "@headlessui/vue";
import { computed, ref } from "vue";
const topics = [
{ id: 1, name: "Filter for all topics" },
{ id: 2, name: "Environment" },
{ id: 3, name: "Animal rights" },
{ id: 4, name: "Racial justice" },
];
const selectedTopic = ref(topics[0]);
const query = ref("");
const filteredTopics = computed(() =>
query.value === ""
? topics
: topics.filter((topic) =>
topic.name
.toLowerCase()
.replace(/\s+/g, "")
.includes(query.value.toLowerCase().replace(/\s+/g, ""))
)
);
</script>
68 changes: 0 additions & 68 deletions frontend/components/dropdown/DropdownTopics.vue

This file was deleted.

1 change: 1 addition & 0 deletions frontend/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
"components.card-search-result-resource.img-alt-text": "The resource logo of",
"components.card-topic-selection.header": "Topics",
"components.card-topic-selection.selector-placeholder": "Type to filter topics",
"components.combobox-topics.no-matching-topics": "No matching topics.",
"components.feed-item.img-alt-text": "A social media post's image.",
"components.footer._global.activist-tagline": "Open-source, nonprofit activism platform.",
"components.footer._global.powered-by-netlify": "This site is powered by Netlify.",
Expand Down
17 changes: 8 additions & 9 deletions frontend/pages/home/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
:header="$t('pages.home.index.header')"
:tagline="$t('pages.home.index.subheader')"
>
<div class="flex flex-col space-x-3 sm:flex-row">
<DropdownTopics :topic="$t('pages.home.index.dropdown-topics')" :hasIcon="true" :items="topicItems" iconName="bi:globe" :isRounded="true"/>
</div>
<ComboboxTopics
:topic="$t('pages.home.index.dropdown-topics')"
:hasIcon="true"
:items="topicItems"
iconName="bi:globe"
:isRounded="true"
/>
</HeaderAppPage>
<div class="pt-3 pb-6 space-y-6 md:pt-4">
<div
Expand Down Expand Up @@ -63,12 +67,7 @@ definePageMeta({
layout: "sidebar",
});
const topicItems = [
"Topic 1",
"Topic 2",
"Topic 3",
"Topic 4"
]
const topicItems = ["Topic 1", "Topic 2", "Topic 3", "Topic 4"];
const resource: Resource = {
name: "Test Resource",
Expand Down

0 comments on commit 2437018

Please sign in to comment.