Item.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <template>
  2. <SmartLink
  3. :to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
  4. :exact="exact"
  5. :blank="blank"
  6. class="inline-flex items-center flex-shrink-0 px-4 py-2 rounded transition hover:bg-primaryDark hover:text-secondaryDark focus:outline-none focus-visible:bg-primaryDark focus-visible:text-secondaryDark"
  7. :class="[
  8. { 'opacity-75 cursor-not-allowed': disabled },
  9. { 'pointer-events-none': loading },
  10. { 'flex-1': label },
  11. { 'flex-row-reverse justify-end': reverse },
  12. {
  13. 'border border-divider hover:border-dividerDark focus-visible:border-dividerDark':
  14. outline,
  15. },
  16. ]"
  17. :disabled="disabled"
  18. :tabindex="loading ? '-1' : '0'"
  19. role="menuitem"
  20. >
  21. <span
  22. v-if="!loading"
  23. class="inline-flex items-center"
  24. :class="{ 'self-start': infoIcon }"
  25. >
  26. <i
  27. v-if="icon"
  28. class="opacity-75 material-icons"
  29. :class="[
  30. label ? (reverse ? 'ml-4' : 'mr-4') : '',
  31. { 'text-accent': active },
  32. ]"
  33. >
  34. {{ icon }}
  35. </i>
  36. <SmartIcon
  37. v-if="svg"
  38. :name="svg"
  39. class="opacity-75 svg-icons"
  40. :class="[
  41. label ? (reverse ? 'ml-4' : 'mr-4') : '',
  42. { 'text-accent': active },
  43. ]"
  44. />
  45. </span>
  46. <SmartSpinner v-else class="mr-4 text-secondaryDark" />
  47. <div
  48. class="inline-flex items-start flex-1 truncate"
  49. :class="{ 'flex-col': description }"
  50. >
  51. <div class="font-semibold truncate">
  52. {{ label }}
  53. </div>
  54. <p v-if="description" class="my-2 text-left text-secondaryLight">
  55. {{ description }}
  56. </p>
  57. </div>
  58. <i
  59. v-if="infoIcon"
  60. class="items-center self-center ml-6 material-icons"
  61. :class="{ 'text-accent': activeInfoIcon }"
  62. >
  63. {{ infoIcon }}
  64. </i>
  65. <div v-if="shortcut.length" class="ml-2 <sm:hidden font-medium">
  66. <kbd
  67. v-for="(key, index) in shortcut"
  68. :key="`key-${index}`"
  69. class="-mr-2 shortcut-key"
  70. >
  71. {{ key }}
  72. </kbd>
  73. </div>
  74. </SmartLink>
  75. </template>
  76. <script lang="ts">
  77. import { defineComponent } from "@nuxtjs/composition-api"
  78. export default defineComponent({
  79. props: {
  80. to: {
  81. type: String,
  82. default: "",
  83. },
  84. exact: {
  85. type: Boolean,
  86. default: true,
  87. },
  88. blank: {
  89. type: Boolean,
  90. default: false,
  91. },
  92. label: {
  93. type: String,
  94. default: "",
  95. },
  96. description: {
  97. type: String,
  98. default: "",
  99. },
  100. icon: {
  101. type: String,
  102. default: "",
  103. },
  104. svg: {
  105. type: String,
  106. default: "",
  107. },
  108. disabled: {
  109. type: Boolean,
  110. default: false,
  111. },
  112. loading: {
  113. type: Boolean,
  114. default: false,
  115. },
  116. reverse: {
  117. type: Boolean,
  118. default: false,
  119. },
  120. outline: {
  121. type: Boolean,
  122. default: false,
  123. },
  124. shortcut: {
  125. type: Array,
  126. default: () => [],
  127. },
  128. active: {
  129. type: Boolean,
  130. default: false,
  131. },
  132. activeInfoIcon: {
  133. type: Boolean,
  134. default: false,
  135. },
  136. infoIcon: {
  137. type: String,
  138. default: "",
  139. },
  140. },
  141. })
  142. </script>