🤷‍♂️ RStudio Addin to Search and Copy Emoji
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.

139 lines
3.9KB

  1. import { EmojiButton } from './emoji-button.js' // @joeattardi/emoji-button
  2. const pickerTypePlugin = {
  3. render(picker) {
  4. const choices = [
  5. {value: 'unicode', label: '<span>Unicode</span>'},
  6. {value: 'html', label: '<span>HTML</span>'},
  7. {value: 'emo_ji', label: '<span style="font-family: monospace;">emo::ji</span>'}
  8. ]
  9. function htmlToElems(html) {
  10. let temp = document.createElement('template');
  11. temp.innerHTML = html;
  12. return temp.content.childNodes;
  13. }
  14. function makeRadioElement({value, label}) {
  15. const div = document.createElement('div')
  16. const divLabel = document.createElement('label')
  17. divLabel.classList = 'radio-inline'
  18. const input = document.createElement('input')
  19. input.type = 'radio'
  20. input.name = 'picker_type'
  21. input.value = value
  22. if (document.getElementById('picker-gadget').matches('.' + value)) {
  23. input.checked = 'checked'
  24. }
  25. divLabel.appendChild(input)
  26. divLabel.appendChild(htmlToElems(label)[0])
  27. div.appendChild(divLabel)
  28. return div
  29. }
  30. const div = document.createElement('div')
  31. div.id = 'picker_type'
  32. const label = document.createElement('label')
  33. label.classList = 'control-label'
  34. label['for'] = 'picker_type'
  35. label.innerText = 'Insert as...'
  36. div.appendChild(label)
  37. choices.map(makeRadioElement).forEach(el => div.appendChild(el))
  38. return div;
  39. }
  40. }
  41. const picker = new EmojiButton({
  42. position: {
  43. top: '0',
  44. right: '0',
  45. bottom: '0',
  46. left: '0'
  47. },
  48. autoHide: false,
  49. theme: document.getElementById('picker-gadget').matches('.dark-theme') ? 'dark' : 'light',
  50. // plugins: [closePlugin, insertEmoji]
  51. plugins: [pickerTypePlugin]
  52. })
  53. picker.on('emoji', function(selection) {
  54. selection.html = he.encode(selection.emoji)
  55. Shiny.setInputValue('emoji', selection, { priority: 'event' });
  56. });
  57. picker.togglePicker(document.getElementById('emoji-picker'))
  58. const divPicker = document.querySelector('.emoji-picker__wrapper')
  59. divPicker.style.top = '0'
  60. divPicker.style.left = '0'
  61. divPicker.addEventListener('keydown', function(ev) {
  62. if (ev.keyCode === 27) {
  63. ev.stopPropagation()
  64. Shiny.setInputValue('close', Date.now())
  65. }
  66. })
  67. // Communicate choices of emoji type to insert ...
  68. const pickerInput = document.getElementById('picker_type')
  69. function reportPickerType() {
  70. const choices = [...pickerInput.querySelectorAll('input')]
  71. const value = choices.filter(item => item.checked).map(item => item.value)
  72. Shiny.setInputValue('picker_type', value[0])
  73. }
  74. function updatePickerType(value) {
  75. const choices = [...pickerInput.querySelectorAll('input')]
  76. choices.forEach(function(choice) {
  77. if (choice.value === value) {
  78. choice.checked = 'checked'
  79. Shiny.setInputValue('picker_type', value)
  80. } else {
  81. choice.removeAttribute('checked')
  82. }
  83. })
  84. }
  85. pickerInput.addEventListener('change', reportPickerType)
  86. $().on('shiny:sessioninitialized', reportPickerType)
  87. Shiny.addCustomMessageHandler('update_picker_type', updatePickerType)
  88. const badEmojiAlert = document.getElementById('alert_bad_emo_ji')
  89. let hideAlertTimer = null
  90. function hideBadEmojiAlert() {
  91. badEmojiAlert.classList.remove('show-bad-emo-ji')
  92. }
  93. function showBadEmojiAlert(name) {
  94. if (hideAlertTimer) {
  95. clearTimeout(hideAlertTimer)
  96. }
  97. badEmojiAlert.classList.add('show-bad-emo-ji')
  98. document.getElementById('bad_emo_ji_name').innerText = name
  99. hideAlertTimer = setTimeout(hideBadEmojiAlert, 3000)
  100. }
  101. Shiny.addCustomMessageHandler('bad_emo_ji', showBadEmojiAlert)
  102. function searchEmoji(word) {
  103. const searchInput = document.querySelector('input.emoji-picker__search')
  104. searchInput.value = ''
  105. word.split('').forEach(function(key) {
  106. const keyEvent = new KeyboardEvent('keyup', {key})
  107. searchInput.value += key
  108. searchInput.dispatchEvent(keyEvent)
  109. })
  110. }
  111. Shiny.addCustomMessageHandler('search_emoji', searchEmoji)