timezone-button.vue 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <script setup lang="ts">
  2. import type { ExtendedModalApi } from '@vben-core/popup-ui';
  3. import { ref, unref, watch } from 'vue';
  4. import { createIconifyIcon } from '@vben/icons';
  5. import { $t } from '@vben/locales';
  6. import { useVbenModal } from '@vben-core/popup-ui';
  7. import {
  8. RadioGroup,
  9. RadioGroupItem,
  10. VbenIconButton,
  11. } from '@vben-core/shadcn-ui';
  12. interface Props {
  13. timezoneOptions: string[];
  14. okHandler?: (
  15. modalApi: ExtendedModalApi,
  16. timezone?: string,
  17. ) => Promise<void> | void;
  18. timezone?: string;
  19. }
  20. const props = defineProps<Props>();
  21. const emit = defineEmits<{ change: [string] }>();
  22. const TimezoneIcon = createIconifyIcon('fluent-mdl2:world-clock');
  23. const [Modal, modalApi] = useVbenModal({
  24. fullscreenButton: false,
  25. onConfirm: () => {
  26. props.okHandler?.(modalApi, unref(timezoneValue));
  27. },
  28. });
  29. const handleClick = () => {
  30. modalApi.open();
  31. };
  32. const timezoneValue = ref<string | undefined>(unref(props.timezone));
  33. watch(
  34. () => props.timezone,
  35. (newTimezone) => {
  36. timezoneValue.value = unref(newTimezone);
  37. },
  38. );
  39. const handleClickItem = (timezone: string) => {
  40. timezoneValue.value = timezone;
  41. emit('change', timezone);
  42. };
  43. </script>
  44. <template>
  45. <div>
  46. <VbenIconButton
  47. :tooltip="$t('ui.widgets.timezone.setTimezone')"
  48. class="hover:animate-[shrink_0.3s_ease-in-out]"
  49. @click="handleClick"
  50. >
  51. <TimezoneIcon class="text-foreground size-4" />
  52. </VbenIconButton>
  53. <Modal :title="$t('ui.widgets.timezone.setTimezone')">
  54. <div class="timezone-container">
  55. <RadioGroup v-model="timezoneValue" class="flex flex-col gap-2">
  56. <div
  57. class="flex cursor-pointer items-center gap-2"
  58. v-for="item in props.timezoneOptions"
  59. :key="`container${item}`"
  60. @click="handleClickItem(item)"
  61. >
  62. <RadioGroupItem :id="item" :value="item" />
  63. <label :for="item" class="cursor-pointer">{{ item }}</label>
  64. </div>
  65. </RadioGroup>
  66. </div>
  67. </Modal>
  68. </div>
  69. </template>
  70. <style scoped>
  71. .timezone-container {
  72. padding-left: 20px;
  73. }
  74. </style>