Submit.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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
  36. @click="submitAction(action)"
  37. >
  38. {{ $t(action) }}
  39. </v-list-item-title>
  40. </v-list-item>
  41. </v-list>
  42. </v-menu>
  43. </v-btn>
  44. </template>
  45. <script setup lang="ts">
  46. import { computed, ref } from 'vue'
  47. import type { ComputedRef, Ref } from 'vue'
  48. const props = defineProps({
  49. actions: {
  50. type: Array,
  51. required: true,
  52. },
  53. dropDirection: {
  54. type: String,
  55. required: false,
  56. default: 'bottom',
  57. },
  58. validationPending: {
  59. type: Boolean,
  60. required: false,
  61. default: false,
  62. },
  63. })
  64. const emit = defineEmits(['submit'])
  65. const mainBtn: Ref = ref(null)
  66. const menuSize = computed(() => {
  67. // Btn size + 40px de padding
  68. return mainBtn.value?.$el.clientWidth + 40
  69. })
  70. const submitAction = (action: string) => {
  71. emit('submit', action)
  72. }
  73. const mainAction: ComputedRef<string> = computed(() => {
  74. return props.actions[0] as string
  75. })
  76. const hasOtherActions: ComputedRef<boolean> = computed(() => {
  77. return props.actions.length > 1
  78. })
  79. const otherActions: ComputedRef<Array<string>> = computed(() => {
  80. return props.actions.filter((_, index) => index > 0) as Array<string>
  81. })
  82. </script>
  83. <style scoped>
  84. .submit-btn {
  85. margin-right: 12px;
  86. @media (max-width: 600px) {
  87. margin: 0;
  88. }
  89. }
  90. .v-list-item--dense {
  91. min-height: 25px;
  92. }
  93. .subAction {
  94. cursor: pointer;
  95. }
  96. </style>