logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git

emoji_input.vue (5359B)


  1. <template>
  2. <div
  3. ref="root"
  4. class="input emoji-input"
  5. :class="{ 'with-picker': !hideEmojiButton }"
  6. >
  7. <slot
  8. :id="'textbox-' + randomSeed"
  9. :aria-owns="suggestionListId"
  10. aria-autocomplete="both"
  11. :aria-expanded="showSuggestions"
  12. :aria-activedescendant="(!showSuggestions || highlighted === -1) ? '' : suggestionItemId(highlighted)"
  13. />
  14. <!-- TODO: make the 'x' disappear if at the end maybe? -->
  15. <div
  16. ref="hiddenOverlay"
  17. class="hidden-overlay"
  18. :style="overlayStyle"
  19. :aria-hidden="true"
  20. >
  21. <span>{{ preText }}</span>
  22. <span
  23. ref="hiddenOverlayCaret"
  24. class="caret"
  25. >x</span>
  26. <span>{{ postText }}</span>
  27. </div>
  28. <screen-reader-notice
  29. ref="screenReaderNotice"
  30. aria-live="assertive"
  31. />
  32. <template v-if="enableEmojiPicker">
  33. <button
  34. v-if="!hideEmojiButton"
  35. class="button-unstyled emoji-picker-icon"
  36. type="button"
  37. :title="$t('emoji.add_emoji')"
  38. @click.prevent="togglePicker"
  39. >
  40. <FAIcon :icon="['far', 'smile-beam']" />
  41. </button>
  42. <EmojiPicker
  43. v-if="enableEmojiPicker"
  44. ref="picker"
  45. :enable-sticker-picker="enableStickerPicker"
  46. class="emoji-picker-panel"
  47. @emoji="insert"
  48. @sticker-uploaded="onStickerUploaded"
  49. @sticker-upload-failed="onStickerUploadFailed"
  50. @show="onPickerShown"
  51. @close="onPickerClosed"
  52. />
  53. </template>
  54. <Popover
  55. ref="suggestorPopover"
  56. class="autocomplete-panel"
  57. placement="bottom"
  58. :trigger-attrs="{ 'aria-hidden': true }"
  59. >
  60. <template #content>
  61. <div
  62. :id="suggestionListId"
  63. ref="panel-body"
  64. class="autocomplete-panel-body"
  65. role="listbox"
  66. >
  67. <div
  68. v-for="(suggestion, index) in suggestions"
  69. :id="suggestionItemId(index)"
  70. :key="index"
  71. class="menu-item autocomplete-item"
  72. role="option"
  73. :class="{ '-active': index === highlighted }"
  74. :aria-label="autoCompleteItemLabel(suggestion)"
  75. :aria-selected="index === highlighted"
  76. @click.stop.prevent="onClick($event, suggestion)"
  77. >
  78. <span class="image">
  79. <img
  80. v-if="suggestion.img"
  81. :src="suggestion.img"
  82. >
  83. <span v-else>{{ suggestion.replacement }}</span>
  84. </span>
  85. <div class="label">
  86. <span
  87. v-if="suggestion.user"
  88. class="displayText"
  89. >
  90. {{ suggestion.displayText }}<UnicodeDomainIndicator
  91. :user="suggestion.user"
  92. :at="false"
  93. />
  94. </span>
  95. <span
  96. v-if="!suggestion.user"
  97. class="displayText"
  98. >
  99. {{ maybeLocalizedEmojiName(suggestion) }}
  100. </span>
  101. <span class="detailText">{{ suggestion.detailText }}</span>
  102. </div>
  103. </div>
  104. </div>
  105. </template>
  106. </Popover>
  107. </div>
  108. </template>
  109. <script src="./emoji_input.js"></script>
  110. <style lang="scss">
  111. .input.emoji-input {
  112. padding: 0;
  113. display: flex;
  114. flex-direction: column;
  115. position: relative;
  116. .emoji-picker-icon {
  117. position: absolute;
  118. top: 0;
  119. right: 0;
  120. margin: 0.2em 0.25em;
  121. font-size: 1.3em;
  122. cursor: pointer;
  123. line-height: 24px;
  124. &:hover i {
  125. color: var(--text);
  126. }
  127. }
  128. .emoji-picker-panel {
  129. position: absolute;
  130. z-index: 20;
  131. margin-top: 2px;
  132. &.hide {
  133. display: none;
  134. }
  135. }
  136. input,
  137. textarea {
  138. flex: 1 0 auto;
  139. color: inherit;
  140. /* stylelint-disable-next-line declaration-no-important */
  141. background: none !important;
  142. box-shadow: none;
  143. border: none;
  144. outline: none;
  145. }
  146. &.with-picker input {
  147. padding-right: 30px;
  148. }
  149. .hidden-overlay {
  150. opacity: 0;
  151. pointer-events: none;
  152. position: absolute;
  153. top: 0;
  154. bottom: 0;
  155. right: 0;
  156. left: 0;
  157. overflow: hidden;
  158. /* DEBUG STUFF */
  159. color: red;
  160. /* set opacity to non-zero to see the overlay */
  161. .caret {
  162. width: 0;
  163. margin-right: calc(-1ch - 1px);
  164. border: 1px solid red;
  165. }
  166. }
  167. }
  168. .autocomplete {
  169. &-panel {
  170. position: absolute;
  171. }
  172. &-item.menu-item {
  173. display: flex;
  174. padding-top: 0;
  175. padding-bottom: 0;
  176. .image {
  177. width: calc(var(--__line-height) + var(--__vertical-gap) * 2);
  178. height: calc(var(--__line-height) + var(--__vertical-gap) * 2);
  179. line-height: var(--__line-height);
  180. text-align: center;
  181. margin-right: var(--__horizontal-gap);
  182. img {
  183. width: calc(var(--__line-height) + var(--__vertical-gap) * 2);
  184. height: calc(var(--__line-height) + var(--__vertical-gap) * 2);
  185. object-fit: contain;
  186. }
  187. span {
  188. font-size: var(--__line-height);
  189. line-height: var(--__line-height);
  190. }
  191. }
  192. .label {
  193. display: flex;
  194. flex-direction: column;
  195. justify-content: center;
  196. margin: 0 0.1em 0 0.2em;
  197. .displayText {
  198. line-height: 1.5;
  199. }
  200. .detailText {
  201. font-size: 9px;
  202. line-height: 9px;
  203. }
  204. }
  205. }
  206. }
  207. </style>