kodadot/nft-gallery

View on GitHub
components/explore/ExploreSort.vue

Summary

Maintainability
Test Coverage
<template>
  <div>
    <NeoDropdown
      v-model="selectedSort"
      class="sort"
      :close-on-click="false"
      multiple
      :mobile-modal="false"
      aria-role="list"
      position="bottom-right"
      data-testid="explore-sort-dropdown"
      @change="onChange"
    >
      <template #trigger="{ active }">
        <NeoButton
          :active="active"
          type="button"
          :icon="active ? 'chevron-up' : 'chevron-down'"
          class="text-left is-hidden-mobile"
        >
          {{ $i18n.t('sort.collection.sortBy') }}
        </NeoButton>
        <NeoButton
          type="button"
          icon="filter"
          class="is-hidden-tablet"
        />

        <ActiveCount
          v-if="selectedSort.length"
          :count="selectedSort.length"
        />
      </template>

      <NeoDropdownItem
        v-for="option in options"
        :key="option"
        aria-role="listitem"
        class="flex"
        :data-testid="option"
        :value="option"
      >
        <span>
          {{
            $i18n.t(isItems ? `sort.${option}` : `sort.collection.${option}`)
          }}
        </span>
        <NeoIcon
          v-if="selectedSort.includes(option)"
          class="ml-2"
          icon="check"
        />
      </NeoDropdownItem>
    </NeoDropdown>
  </div>
</template>

<script setup lang="ts">
import {
  NeoButton,
  NeoDropdown,
  NeoDropdownItem,
  NeoIcon,
} from '@kodadot1/brick'
import ActiveCount from './ActiveCount.vue'

const route = useRoute()
const router = useRouter()
const { $i18n } = useNuxtApp()

const { hasItems: isItems } = useHasRoute()
const { options } = useRouteSortByOptions()

function removeDuplicateSortKeys(options: string[]) {
  const uniqueOptions = {}

  if (!Array.isArray(options)) {
    return []
  }

  options.forEach((option) => {
    const opt = option.split('_')
    const identifier = opt[0]
    const sort = opt[1]

    uniqueOptions[identifier] = sort
  })

  return Object.keys(uniqueOptions).map((identifier) => {
    return `${identifier}_${uniqueOptions[identifier]}`
  })
}

const sortOptions = ref<string[]>([])
const selectedSort = computed({
  get: () => sortOptions.value,
  set: value => (sortOptions.value = removeDuplicateSortKeys(value)),
})

function onChange(selected) {
  const { page, ...restQuery } = route.query
  router.push({
    path: route.fullPath,
    query: {
      ...restQuery,
      sort: removeDuplicateSortKeys(selected),
    },
  })
}

watch(
  () => route.query.sort,
  (sort) => {
    if (sort?.length) {
      selectedSort.value = parseQueryParamToArray(sort)
    }
    else if (selectedSort.value.length) {
      selectedSort.value = []
    }
  },
  { immediate: true },
)
</script>

<style lang="scss" scoped>
@import '@/assets/styles/abstracts/variables';

.sort {
  position: relative;

  &-active .is-neo {
    @include ktheme() {
      background-color: theme('text-color');
      color: theme('text-color-inverse');
    }
  }

  .neo-dropdown-item {
    width: 14rem;
  }
}

.dark .sort-check {
  filter: brightness(0%);
}
</style>