Submit.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <template>
  2. <v-btn
  3. ref="mainBtn"
  4. class="submit-btn theme-primary"
  5. :class="hasOtherActions ? 'pr-0' : ''"
  6. :disabled="validationPending"
  7. @click="submitAction(mainAction)"
  8. >
  9. {{ $t(mainAction) }}
  10. <v-divider v-if="hasOtherActions" class="ml-3" :vertical="true" />
  11. <v-menu
  12. v-if="hasOtherActions"
  13. :top="dropDirection === 'top'"
  14. offset-y
  15. left
  16. :nudge-top="dropDirection === 'top' ? 6 : 0"
  17. :nudge-bottom="dropDirection === 'bottom' ? 6 : 0"
  18. >
  19. <template #activator="{ on }">
  20. <v-toolbar-title v-on="on">
  21. <v-icon class="pl-3 pr-3">
  22. {{
  23. dropDirection === 'top' ? 'fa fa-caret-up' : 'fa fa-caret-down'
  24. }}
  25. </v-icon>
  26. </v-toolbar-title>
  27. </template>
  28. <v-list :min-width="menuSize">
  29. <v-list-item
  30. v-for="(action, index) in otherActions"
  31. :key="index"
  32. dense
  33. class="subAction"
  34. >
  35. <v-list-item-title @click="submitAction(action)">
  36. {{ $t(action) }}
  37. </v-list-item-title>
  38. </v-list-item>
  39. </v-list>
  40. </v-menu>
  41. </v-btn>
  42. </template>
  43. <script setup lang="ts">
  44. import { computed, ref } from 'vue'
  45. import type { ComputedRef, Ref } from 'vue'
  46. const props = defineProps({
  47. actions: {
  48. type: Array,
  49. required: true,
  50. },
  51. dropDirection: {
  52. type: String,
  53. required: false,
  54. default: 'bottom',
  55. },
  56. validationPending: {
  57. type: Boolean,
  58. required: false,
  59. default: false,
  60. },
  61. })
  62. const emit = defineEmits(['submit'])
  63. const mainBtn: Ref = ref(null)
  64. const menuSize = computed(() => {
  65. // Btn size + 40px de padding
  66. return mainBtn.value?.$el.clientWidth + 40
  67. })
  68. const submitAction = (action: string) => {
  69. emit('submit', action)
  70. }
  71. const mainAction: ComputedRef<string> = computed(() => {
  72. return props.actions[0] as string
  73. })
  74. const hasOtherActions: ComputedRef<boolean> = computed(() => {
  75. return props.actions.length > 1
  76. })
  77. const otherActions: ComputedRef<Array<string>> = computed(() => {
  78. return props.actions.filter((_, index) => index > 0) as Array<string>
  79. })
  80. </script>
  81. <style scoped>
  82. .submit-btn {
  83. margin-right: 12px;
  84. @media (max-width: 600px) {
  85. margin: 0;
  86. }
  87. }
  88. .v-list-item--dense {
  89. min-height: 25px;
  90. }
  91. .subAction {
  92. cursor: pointer;
  93. }
  94. </style>