You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
3.0 KiB

4 years ago
  1. <template>
  2. <v-menu
  3. v-if="label"
  4. v-model="showMenu"
  5. offset-y
  6. >
  7. <template v-slot:activator="{ on }">
  8. <span :style="{ borderColor: color }" class="highlight bottom" v-on="on">
  9. <span class="highlight__content">{{ content }}<v-icon class="delete" @click.stop="remove">mdi-close-circle</v-icon></span><span :data-label="label" :style="{ backgroundColor: color, color: textColor }" class="highlight__label" />
  10. </span>
  11. </template>
  12. <v-list
  13. dense
  14. min-width="150"
  15. max-height="400"
  16. class="overflow-y-auto"
  17. >
  18. <v-list-item
  19. v-for="(item, i) in labels"
  20. :key="i"
  21. v-shortkey.once="[item.suffix_key]"
  22. @shortkey="update(item)"
  23. @click="update(item)"
  24. >
  25. <v-list-item-content>
  26. <v-list-item-title v-text="item.text" />
  27. </v-list-item-content>
  28. <v-list-item-action>
  29. <v-list-item-action-text v-text="item.suffix_key" />
  30. </v-list-item-action>
  31. </v-list-item>
  32. </v-list>
  33. </v-menu>
  34. <span v-else :class="[newline ? 'newline' : '']">{{ content }}</span>
  35. </template>
  36. <script>
  37. import { idealColor } from '~/plugins/utils.js'
  38. export default {
  39. props: {
  40. content: {
  41. type: String,
  42. default: '',
  43. required: true
  44. },
  45. label: {
  46. type: String,
  47. default: ''
  48. },
  49. color: {
  50. type: String,
  51. default: '#64FFDA'
  52. },
  53. labels: {
  54. type: Array,
  55. default: () => [],
  56. required: true
  57. },
  58. newline: {
  59. type: Boolean
  60. }
  61. },
  62. data() {
  63. return {
  64. showMenu: false
  65. }
  66. },
  67. computed: {
  68. textColor() {
  69. return idealColor(this.color)
  70. }
  71. },
  72. methods: {
  73. update(label) {
  74. this.$emit('update', label)
  75. this.showMenu = false
  76. },
  77. remove() {
  78. this.$emit('remove')
  79. }
  80. }
  81. }
  82. </script>
  83. <style scoped>
  84. .highlight.blue {
  85. background: #edf4fa !important;
  86. }
  87. .highlight.bottom {
  88. display: block;
  89. white-space: normal;
  90. }
  91. .highlight:first-child {
  92. margin-left: 0;
  93. }
  94. .highlight {
  95. border: 2px solid;
  96. margin: 4px 6px 4px 3px;
  97. vertical-align: middle;
  98. box-shadow: 2px 4px 20px rgba(0,0,0,.1);
  99. position: relative;
  100. cursor: default;
  101. min-width: 26px;
  102. line-height: 22px;
  103. display: flex;
  104. }
  105. .highlight .delete {
  106. top:-15px;
  107. left:-13px;
  108. position:absolute;
  109. display: none;
  110. }
  111. .highlight:hover .delete {
  112. display: block;
  113. }
  114. .highlight__content {
  115. display: flex;
  116. flex-wrap: wrap;
  117. align-items: center;
  118. padding: 2px 2px 0px 6px;
  119. }
  120. .highlight.bottom .highlight__content:after {
  121. content: " ";
  122. padding-right: 3px;
  123. }
  124. .highlight__label {
  125. line-height: 14px;
  126. padding-top: 1px;
  127. align-items: center;
  128. justify-content: center;
  129. display: flex;
  130. padding: 0 8px;
  131. text-align: center;
  132. -webkit-user-select: none;
  133. -moz-user-select: none;
  134. -ms-user-select: none;
  135. user-select: none;
  136. color: white;
  137. }
  138. .highlight__label::after {
  139. content: attr(data-label);
  140. display: block;
  141. font-size: 14px;
  142. -webkit-font-smoothing: subpixel-antialiased;
  143. letter-spacing: .1em;
  144. }
  145. .newline {
  146. width: 100%;
  147. }
  148. </style>