LanguageSelector.vue 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <template>
  2. <v-select
  3. v-model="locale"
  4. :items="items"
  5. :key="`locale-${locale}`"
  6. density="compact"
  7. variant="plain"
  8. :hide-details="true"
  9. class="language-selector"
  10. >
  11. <template v-slot:selection="data">
  12. <v-img :src="data.item.raw.logo" left :width="16" class="mr-2"/>
  13. <span>{{ data.item.title }}</span>
  14. </template>
  15. <template v-slot:item="{ props, item }">
  16. <v-list-item v-bind="props">
  17. <template v-slot:prepend>
  18. <v-img :src="item.raw.logo" :width="16" class="mr-2"/>
  19. </template>
  20. </v-list-item>
  21. </template>
  22. </v-select>
  23. </template>
  24. <script setup lang="ts">
  25. import { ref, watch } from 'vue'
  26. import { useI18n } from 'vue-i18n'
  27. const items = [
  28. { value: 'fr', title: 'FR', logo: '/images/logos/french_flag.svg' },
  29. { value: 'en', title: 'EN', logo: '/images/logos/us-uk_flag.svg' },
  30. ]
  31. const { setLocale } = useI18n()
  32. const locale = ref('fr')
  33. watch(locale, () => {
  34. setLocale(locale.value)
  35. });
  36. </script>
  37. <style scoped lang="scss">
  38. .language-selector {
  39. max-width: 80px;
  40. :deep(.v-field) {
  41. flex: 0 0 auto;
  42. }
  43. }
  44. :deep(.v-field__input) {
  45. padding: 0;
  46. }
  47. :deep(.v-select__menu-icon) {
  48. font-size: 15px;
  49. margin-top: 1px;
  50. margin-left: 0;
  51. }
  52. :deep(.v-list) {
  53. width: 72px;
  54. }
  55. :deep(.v-list-item) {
  56. padding: 24px;
  57. }
  58. :deep(.v-list-item__content) {
  59. display: flex;
  60. flex-direction: row;
  61. .v-avatar {
  62. width: 18px;
  63. height: 18px;
  64. }
  65. }
  66. </style>