@nextcloud/vue 8.11.0 → 8.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/dist/Components/NcActionButtonGroup.cjs +1 -1
  3. package/dist/Components/NcActionButtonGroup.mjs +1 -1
  4. package/dist/Components/NcActionInput.cjs +1 -1
  5. package/dist/Components/NcActionInput.mjs +1 -1
  6. package/dist/Components/NcActions.cjs +1 -1
  7. package/dist/Components/NcActions.mjs +1 -1
  8. package/dist/Components/NcAppContent.cjs +1 -1
  9. package/dist/Components/NcAppContent.mjs +1 -1
  10. package/dist/Components/NcAppNavigation.cjs +1 -1
  11. package/dist/Components/NcAppNavigation.mjs +1 -1
  12. package/dist/Components/NcAppNavigationCaption.cjs +1 -1
  13. package/dist/Components/NcAppNavigationCaption.mjs +1 -1
  14. package/dist/Components/NcAppNavigationItem.cjs +1 -1
  15. package/dist/Components/NcAppNavigationItem.mjs +1 -1
  16. package/dist/Components/NcAppNavigationNewItem.cjs +1 -1
  17. package/dist/Components/NcAppNavigationNewItem.mjs +1 -1
  18. package/dist/Components/NcAppNavigationSettings.cjs +1 -1
  19. package/dist/Components/NcAppNavigationSettings.mjs +1 -1
  20. package/dist/Components/NcAppNavigationToggle.cjs +1 -1
  21. package/dist/Components/NcAppNavigationToggle.mjs +1 -1
  22. package/dist/Components/NcAppSettingsDialog.cjs +1 -1
  23. package/dist/Components/NcAppSettingsDialog.mjs +1 -1
  24. package/dist/Components/NcAppSidebar.cjs +1 -1
  25. package/dist/Components/NcAppSidebar.mjs +1 -1
  26. package/dist/Components/NcAvatar.cjs +1 -1
  27. package/dist/Components/NcAvatar.mjs +1 -1
  28. package/dist/Components/NcBreadcrumb.cjs +1 -1
  29. package/dist/Components/NcBreadcrumb.mjs +1 -1
  30. package/dist/Components/NcBreadcrumbs.cjs +1 -1
  31. package/dist/Components/NcBreadcrumbs.mjs +1 -1
  32. package/dist/Components/NcCheckboxRadioSwitch.cjs +1 -1
  33. package/dist/Components/NcCheckboxRadioSwitch.mjs +1 -1
  34. package/dist/Components/NcColorPicker.cjs +1 -1
  35. package/dist/Components/NcColorPicker.mjs +1 -1
  36. package/dist/Components/NcContent.cjs +1 -1
  37. package/dist/Components/NcContent.mjs +1 -1
  38. package/dist/Components/NcDashboardWidget.cjs +1 -1
  39. package/dist/Components/NcDashboardWidget.mjs +1 -1
  40. package/dist/Components/NcDashboardWidgetItem.cjs +1 -1
  41. package/dist/Components/NcDashboardWidgetItem.mjs +1 -1
  42. package/dist/Components/NcDateTime.cjs +1 -1
  43. package/dist/Components/NcDateTime.mjs +1 -1
  44. package/dist/Components/NcDateTimePicker.cjs +2 -2
  45. package/dist/Components/NcDateTimePicker.mjs +4 -4
  46. package/dist/Components/NcDateTimePickerNative.cjs +1 -1
  47. package/dist/Components/NcDateTimePickerNative.mjs +1 -1
  48. package/dist/Components/NcDialog.cjs +1 -1
  49. package/dist/Components/NcDialog.mjs +1 -1
  50. package/dist/Components/NcEmojiPicker.cjs +1 -1
  51. package/dist/Components/NcEmojiPicker.mjs +1 -1
  52. package/dist/Components/NcHeaderMenu.cjs +1 -1
  53. package/dist/Components/NcHeaderMenu.mjs +1 -1
  54. package/dist/Components/NcListItem.cjs +1 -1
  55. package/dist/Components/NcListItem.mjs +1 -1
  56. package/dist/Components/NcListItemIcon.cjs +1 -1
  57. package/dist/Components/NcListItemIcon.mjs +1 -1
  58. package/dist/Components/NcModal.cjs +1 -1
  59. package/dist/Components/NcModal.mjs +3 -3
  60. package/dist/Components/NcPasswordField.cjs +1 -1
  61. package/dist/Components/NcPasswordField.mjs +1 -1
  62. package/dist/Components/NcRelatedResourcesPanel.cjs +1 -1
  63. package/dist/Components/NcRelatedResourcesPanel.mjs +1 -1
  64. package/dist/Components/NcRichContenteditable.cjs +1 -1
  65. package/dist/Components/NcRichContenteditable.mjs +2 -2
  66. package/dist/Components/NcRichText.cjs +1 -1
  67. package/dist/Components/NcRichText.mjs +3 -3
  68. package/dist/Components/NcSelect.cjs +1 -1
  69. package/dist/Components/NcSelect.mjs +1 -1
  70. package/dist/Components/NcSelectTags.cjs +1 -1
  71. package/dist/Components/NcSelectTags.mjs +1 -1
  72. package/dist/Components/NcSettingsInputText.cjs +1 -1
  73. package/dist/Components/NcSettingsInputText.mjs +1 -1
  74. package/dist/Components/NcSettingsSection.cjs +1 -1
  75. package/dist/Components/NcSettingsSection.mjs +1 -1
  76. package/dist/Components/NcSettingsSelectGroup.cjs +1 -1
  77. package/dist/Components/NcSettingsSelectGroup.mjs +1 -1
  78. package/dist/Components/NcTextField.cjs +1 -1
  79. package/dist/Components/NcTextField.mjs +1 -1
  80. package/dist/Components/NcTimezonePicker.cjs +1 -1
  81. package/dist/Components/NcTimezonePicker.mjs +1 -1
  82. package/dist/Components/NcUserBubble.cjs +1 -1
  83. package/dist/Components/NcUserBubble.mjs +1 -1
  84. package/dist/Components/NcUserStatusIcon.cjs +1 -1
  85. package/dist/Components/NcUserStatusIcon.mjs +1 -1
  86. package/dist/Functions/reference.cjs +1 -1
  87. package/dist/Functions/reference.mjs +1 -1
  88. package/dist/Functions/usernameToColor.cjs +1 -1
  89. package/dist/Functions/usernameToColor.mjs +1 -1
  90. package/dist/Mixins/richEditor.cjs +1 -1
  91. package/dist/Mixins/richEditor.mjs +1 -1
  92. package/dist/assets/{NcActionInput-DjNK8ORa.css → NcActionInput-8F2WF3yH.css} +67 -67
  93. package/dist/assets/{NcActions-DL7ZZIjx.css → NcActions-CiiQkX9v.css} +12 -12
  94. package/dist/assets/{NcAppNavigation-BgGJuJPv.css → NcAppNavigation-wkQJnaLW.css} +12 -12
  95. package/dist/assets/{NcAppNavigationItem-BxoyzD83.css → NcAppNavigationItem-hYyNqvah.css} +44 -44
  96. package/dist/assets/{NcAppSidebar-BGQX62or.css → NcAppSidebar-DlVjDHcd.css} +45 -50
  97. package/dist/assets/{NcAvatar-j5b9vXAH.css → NcAvatar-BozWHt1s.css} +27 -27
  98. package/dist/assets/{NcBreadcrumbs-oFXQlxy-.css → NcBreadcrumbs-E-TglkuV.css} +7 -7
  99. package/dist/assets/{NcDateTimePicker-D8gouVII.css → NcDateTimePicker-q_BLnhHU.css} +10 -10
  100. package/dist/assets/{NcDialog-M36tj7nk.css → NcDialog-DEKSpcnR.css} +17 -16
  101. package/dist/assets/NcListItem-BIFTbr17.css +180 -0
  102. package/dist/assets/{NcMentionBubble-BhiXWJv8.css → NcMentionBubble-7PQ8wEko.css} +9 -9
  103. package/dist/assets/{NcRichContenteditable-DvTdg1DO.css → NcRichContenteditable-BQ2-fqnd.css} +10 -10
  104. package/dist/assets/{NcRichText-D2BBsB-_.css → NcRichText-DNXuHl34.css} +76 -65
  105. package/dist/chunks/{GenColors-SRrPRTFN.mjs → GenColors-Dceu3ds2.mjs} +1 -1
  106. package/dist/chunks/{GenColors-SRrPRTFN.mjs.map → GenColors-Dceu3ds2.mjs.map} +1 -1
  107. package/dist/chunks/{GenColors-BCHzPRPI.cjs → GenColors-hkqGpnOK.cjs} +1 -1
  108. package/dist/chunks/{GenColors-BCHzPRPI.cjs.map → GenColors-hkqGpnOK.cjs.map} +1 -1
  109. package/dist/chunks/{NcActionButtonGroup-Dc9G34Er.cjs → NcActionButtonGroup-B1XhnIBl.cjs} +1 -1
  110. package/dist/chunks/{NcActionButtonGroup-Dc9G34Er.cjs.map → NcActionButtonGroup-B1XhnIBl.cjs.map} +1 -1
  111. package/dist/chunks/{NcActionButtonGroup-BS4fKDux.mjs → NcActionButtonGroup-DU1taycQ.mjs} +1 -1
  112. package/dist/chunks/{NcActionButtonGroup-BS4fKDux.mjs.map → NcActionButtonGroup-DU1taycQ.mjs.map} +1 -1
  113. package/dist/chunks/{NcActionInput-B_upGNjs.mjs → NcActionInput-53RB9uQe.mjs} +6 -6
  114. package/dist/chunks/NcActionInput-53RB9uQe.mjs.map +1 -0
  115. package/dist/chunks/{NcActionInput-C6WR9W8-.cjs → NcActionInput-N2wrvq5K.cjs} +3 -3
  116. package/dist/chunks/NcActionInput-N2wrvq5K.cjs.map +1 -0
  117. package/dist/chunks/{NcActions-DL722iMU.cjs → NcActions-BtvXtZF4.cjs} +55 -35
  118. package/dist/chunks/{NcActions-ClU5w8U1.mjs.map → NcActions-BtvXtZF4.cjs.map} +1 -1
  119. package/dist/chunks/{NcActions-ClU5w8U1.mjs → NcActions-DiFslXqv.mjs} +84 -64
  120. package/dist/chunks/{NcActions-DL722iMU.cjs.map → NcActions-DiFslXqv.mjs.map} +1 -1
  121. package/dist/chunks/{NcAppContent-CZUuFw1x.mjs → NcAppContent-BDhK1rUf.mjs} +1 -1
  122. package/dist/chunks/{NcAppContent-CZUuFw1x.mjs.map → NcAppContent-BDhK1rUf.mjs.map} +1 -1
  123. package/dist/chunks/{NcAppContent-CyPht0ua.cjs → NcAppContent-Be1m1O_W.cjs} +1 -1
  124. package/dist/chunks/{NcAppContent-CyPht0ua.cjs.map → NcAppContent-Be1m1O_W.cjs.map} +1 -1
  125. package/dist/chunks/{NcAppNavigation-8_Bef_ph.mjs → NcAppNavigation-CElLRpH-.mjs} +3 -3
  126. package/dist/chunks/{NcAppNavigation-8_Bef_ph.mjs.map → NcAppNavigation-CElLRpH-.mjs.map} +1 -1
  127. package/dist/chunks/{NcAppNavigation-BPCfq5ox.cjs → NcAppNavigation-DKUnWfen.cjs} +3 -3
  128. package/dist/chunks/{NcAppNavigation-BPCfq5ox.cjs.map → NcAppNavigation-DKUnWfen.cjs.map} +1 -1
  129. package/dist/chunks/{NcAppNavigationCaption-DNugUyEL.cjs → NcAppNavigationCaption-Cdcv-0jj.cjs} +1 -1
  130. package/dist/chunks/{NcAppNavigationCaption-DNugUyEL.cjs.map → NcAppNavigationCaption-Cdcv-0jj.cjs.map} +1 -1
  131. package/dist/chunks/{NcAppNavigationCaption-DZl4aJXn.mjs → NcAppNavigationCaption-DI7SIPdI.mjs} +1 -1
  132. package/dist/chunks/{NcAppNavigationCaption-DZl4aJXn.mjs.map → NcAppNavigationCaption-DI7SIPdI.mjs.map} +1 -1
  133. package/dist/chunks/{NcAppNavigationItem-znyy3LU1.cjs → NcAppNavigationItem-7xN_CMHW.cjs} +6 -8
  134. package/dist/chunks/{NcAppNavigationItem-D7L6HxhH.mjs.map → NcAppNavigationItem-7xN_CMHW.cjs.map} +1 -1
  135. package/dist/chunks/{NcAppNavigationItem-D7L6HxhH.mjs → NcAppNavigationItem-Djfc0DPY.mjs} +8 -10
  136. package/dist/chunks/{NcAppNavigationItem-znyy3LU1.cjs.map → NcAppNavigationItem-Djfc0DPY.mjs.map} +1 -1
  137. package/dist/chunks/{NcAppNavigationNewItem-DgPfNmx6.cjs → NcAppNavigationNewItem-5B4-U2NI.cjs} +1 -1
  138. package/dist/chunks/{NcAppNavigationNewItem-DgPfNmx6.cjs.map → NcAppNavigationNewItem-5B4-U2NI.cjs.map} +1 -1
  139. package/dist/chunks/{NcAppNavigationNewItem-CRLPUH7B.mjs → NcAppNavigationNewItem-CN3vYnc_.mjs} +1 -1
  140. package/dist/chunks/{NcAppNavigationNewItem-CRLPUH7B.mjs.map → NcAppNavigationNewItem-CN3vYnc_.mjs.map} +1 -1
  141. package/dist/chunks/{NcAppNavigationSettings-DPb0p_eD.cjs → NcAppNavigationSettings-Cnr4jYzW.cjs} +2 -2
  142. package/dist/chunks/{NcAppNavigationSettings-DPb0p_eD.cjs.map → NcAppNavigationSettings-Cnr4jYzW.cjs.map} +1 -1
  143. package/dist/chunks/{NcAppNavigationSettings-EcktukV4.mjs → NcAppNavigationSettings-LmpAoM-x.mjs} +2 -2
  144. package/dist/chunks/{NcAppNavigationSettings-EcktukV4.mjs.map → NcAppNavigationSettings-LmpAoM-x.mjs.map} +1 -1
  145. package/dist/chunks/{NcAppNavigationToggle-CSOgniTa.cjs → NcAppNavigationToggle-B5XmO21v.cjs} +1 -1
  146. package/dist/chunks/{NcAppNavigationToggle-CSOgniTa.cjs.map → NcAppNavigationToggle-B5XmO21v.cjs.map} +1 -1
  147. package/dist/chunks/{NcAppNavigationToggle-DwO9-oiH.mjs → NcAppNavigationToggle-D0oeWL17.mjs} +1 -1
  148. package/dist/chunks/{NcAppNavigationToggle-DwO9-oiH.mjs.map → NcAppNavigationToggle-D0oeWL17.mjs.map} +1 -1
  149. package/dist/chunks/{NcAppSettingsDialog-EIsS0HU9.cjs → NcAppSettingsDialog-B6crPJ6a.cjs} +1 -1
  150. package/dist/chunks/{NcAppSettingsDialog-EIsS0HU9.cjs.map → NcAppSettingsDialog-B6crPJ6a.cjs.map} +1 -1
  151. package/dist/chunks/{NcAppSettingsDialog-fgbU_-h8.mjs → NcAppSettingsDialog-BLOgrVCz.mjs} +2 -2
  152. package/dist/chunks/{NcAppSettingsDialog-fgbU_-h8.mjs.map → NcAppSettingsDialog-BLOgrVCz.mjs.map} +1 -1
  153. package/dist/chunks/{NcAppSidebar-BbEflEtM.mjs → NcAppSidebar-CqER6-dl.mjs} +18 -12
  154. package/dist/chunks/NcAppSidebar-CqER6-dl.mjs.map +1 -0
  155. package/dist/chunks/{NcAppSidebar-DNAgJFfm.cjs → NcAppSidebar-qC5-u1p0.cjs} +18 -12
  156. package/dist/chunks/NcAppSidebar-qC5-u1p0.cjs.map +1 -0
  157. package/dist/chunks/{NcAvatar-k_VeT7Vp.mjs → NcAvatar-BBhoG-za.mjs} +96 -92
  158. package/dist/chunks/NcAvatar-BBhoG-za.mjs.map +1 -0
  159. package/dist/chunks/{NcAvatar-CDeuGCns.cjs → NcAvatar-BuqOk4mX.cjs} +66 -67
  160. package/dist/chunks/NcAvatar-BuqOk4mX.cjs.map +1 -0
  161. package/dist/chunks/{NcBreadcrumb-6--UKRl5.cjs → NcBreadcrumb-BRpLGeLr.cjs} +1 -1
  162. package/dist/chunks/{NcBreadcrumb-6--UKRl5.cjs.map → NcBreadcrumb-BRpLGeLr.cjs.map} +1 -1
  163. package/dist/chunks/{NcBreadcrumb-Yg1njNwp.mjs → NcBreadcrumb-BxCf2hEA.mjs} +1 -1
  164. package/dist/chunks/{NcBreadcrumb-Yg1njNwp.mjs.map → NcBreadcrumb-BxCf2hEA.mjs.map} +1 -1
  165. package/dist/chunks/{NcBreadcrumbs-CgSLqCmo.cjs → NcBreadcrumbs-BKPXzHC1.cjs} +28 -28
  166. package/dist/chunks/{NcBreadcrumbs-CgSLqCmo.cjs.map → NcBreadcrumbs-BKPXzHC1.cjs.map} +1 -1
  167. package/dist/chunks/{NcBreadcrumbs-DXD2Kiak.mjs → NcBreadcrumbs-BmK-6Q-n.mjs} +25 -25
  168. package/dist/chunks/{NcBreadcrumbs-DXD2Kiak.mjs.map → NcBreadcrumbs-BmK-6Q-n.mjs.map} +1 -1
  169. package/dist/chunks/{NcCheckboxRadioSwitch-BS2C-YSz.cjs → NcCheckboxRadioSwitch-B9w3Znu7.cjs} +2 -2
  170. package/dist/chunks/{NcCheckboxRadioSwitch-BS2C-YSz.cjs.map → NcCheckboxRadioSwitch-B9w3Znu7.cjs.map} +1 -1
  171. package/dist/chunks/{NcCheckboxRadioSwitch-BRPYihez.mjs → NcCheckboxRadioSwitch-BOl1O2zi.mjs} +2 -2
  172. package/dist/chunks/{NcCheckboxRadioSwitch-BRPYihez.mjs.map → NcCheckboxRadioSwitch-BOl1O2zi.mjs.map} +1 -1
  173. package/dist/chunks/{NcCheckboxRadioSwitch.vue_vue_type_style_index_0_scoped_2603be83_lang-CURkxtfw.mjs → NcCheckboxRadioSwitch.vue_vue_type_style_index_0_scoped_2603be83_lang-CCwH-BzH.mjs} +1 -1
  174. package/dist/chunks/NcCheckboxRadioSwitch.vue_vue_type_style_index_0_scoped_2603be83_lang-CCwH-BzH.mjs.map +1 -0
  175. package/dist/chunks/{NcCheckboxRadioSwitch.vue_vue_type_style_index_0_scoped_2603be83_lang-B5QWlofX.cjs → NcCheckboxRadioSwitch.vue_vue_type_style_index_0_scoped_2603be83_lang-DAxGPyzS.cjs} +1 -1
  176. package/dist/chunks/NcCheckboxRadioSwitch.vue_vue_type_style_index_0_scoped_2603be83_lang-DAxGPyzS.cjs.map +1 -0
  177. package/dist/chunks/{NcColorPicker-DNGismgl.mjs → NcColorPicker-CeoImUTC.mjs} +2 -2
  178. package/dist/chunks/{NcColorPicker-DNGismgl.mjs.map → NcColorPicker-CeoImUTC.mjs.map} +1 -1
  179. package/dist/chunks/{NcColorPicker-D0rQKQAy.cjs → NcColorPicker-DOcxlY35.cjs} +1 -1
  180. package/dist/chunks/{NcColorPicker-D0rQKQAy.cjs.map → NcColorPicker-DOcxlY35.cjs.map} +1 -1
  181. package/dist/chunks/{NcContent-DCmLP8Ly.mjs → NcContent-BPA0KfuT.mjs} +1 -1
  182. package/dist/chunks/{NcContent-DCmLP8Ly.mjs.map → NcContent-BPA0KfuT.mjs.map} +1 -1
  183. package/dist/chunks/{NcContent-BXfreK7p.cjs → NcContent-DbFAEdX_.cjs} +1 -1
  184. package/dist/chunks/{NcContent-BXfreK7p.cjs.map → NcContent-DbFAEdX_.cjs.map} +1 -1
  185. package/dist/chunks/{NcDashboardWidget-6UWLF9LM.mjs → NcDashboardWidget-2-nW7dII.mjs} +3 -3
  186. package/dist/chunks/{NcDashboardWidget-6UWLF9LM.mjs.map → NcDashboardWidget-2-nW7dII.mjs.map} +1 -1
  187. package/dist/chunks/{NcDashboardWidget-CPXbrHii.cjs → NcDashboardWidget-auMQiAFt.cjs} +1 -1
  188. package/dist/chunks/{NcDashboardWidget-CPXbrHii.cjs.map → NcDashboardWidget-auMQiAFt.cjs.map} +1 -1
  189. package/dist/chunks/{NcDashboardWidgetItem-bFGf6_R7.mjs → NcDashboardWidgetItem-D2yoF9Oo.mjs} +2 -2
  190. package/dist/chunks/{NcDashboardWidgetItem-bFGf6_R7.mjs.map → NcDashboardWidgetItem-D2yoF9Oo.mjs.map} +1 -1
  191. package/dist/chunks/{NcDashboardWidgetItem-Buh2BPAN.cjs → NcDashboardWidgetItem-xqVAP32n.cjs} +1 -1
  192. package/dist/chunks/{NcDashboardWidgetItem-Buh2BPAN.cjs.map → NcDashboardWidgetItem-xqVAP32n.cjs.map} +1 -1
  193. package/dist/chunks/{NcDateTime-GW15p7yp.mjs → NcDateTime-CeOdKcvC.mjs} +1 -1
  194. package/dist/chunks/{NcDateTime-GW15p7yp.mjs.map → NcDateTime-CeOdKcvC.mjs.map} +1 -1
  195. package/dist/chunks/{NcDateTime-DG_XAvbT.cjs → NcDateTime-DneyKibb.cjs} +1 -1
  196. package/dist/chunks/{NcDateTime-DG_XAvbT.cjs.map → NcDateTime-DneyKibb.cjs.map} +1 -1
  197. package/dist/chunks/{NcDialog-D6YSjidf.mjs → NcDialog-C_1rhUHk.mjs} +2 -2
  198. package/dist/chunks/{NcDialog-D6YSjidf.mjs.map → NcDialog-C_1rhUHk.mjs.map} +1 -1
  199. package/dist/chunks/{NcDialog-C6nYgBDF.cjs → NcDialog-Ciz0hlFn.cjs} +2 -2
  200. package/dist/chunks/{NcDialog-C6nYgBDF.cjs.map → NcDialog-Ciz0hlFn.cjs.map} +1 -1
  201. package/dist/chunks/{NcEmojiPicker-B34sLJKs.mjs → NcEmojiPicker-Cie30NYK.mjs} +4 -4
  202. package/dist/chunks/{NcEmojiPicker-B34sLJKs.mjs.map → NcEmojiPicker-Cie30NYK.mjs.map} +1 -1
  203. package/dist/chunks/{NcEmojiPicker-BDcdqsgr.cjs → NcEmojiPicker-S2pfwxlK.cjs} +1 -1
  204. package/dist/chunks/{NcEmojiPicker-BDcdqsgr.cjs.map → NcEmojiPicker-S2pfwxlK.cjs.map} +1 -1
  205. package/dist/chunks/{NcHeaderMenu-BUeI4DGP.cjs → NcHeaderMenu-58OTmM-5.cjs} +1 -1
  206. package/dist/chunks/{NcHeaderMenu-BUeI4DGP.cjs.map → NcHeaderMenu-58OTmM-5.cjs.map} +1 -1
  207. package/dist/chunks/{NcHeaderMenu-CXBimxcN.mjs → NcHeaderMenu-DOGXti7v.mjs} +1 -1
  208. package/dist/chunks/{NcHeaderMenu-CXBimxcN.mjs.map → NcHeaderMenu-DOGXti7v.mjs.map} +1 -1
  209. package/dist/chunks/{NcInputConfirmCancel-CVgJcgbg.cjs → NcInputConfirmCancel-DVmY85-V.cjs} +1 -1
  210. package/dist/chunks/{NcInputConfirmCancel-CVgJcgbg.cjs.map → NcInputConfirmCancel-DVmY85-V.cjs.map} +1 -1
  211. package/dist/chunks/{NcInputConfirmCancel-GFlH1B9I.mjs → NcInputConfirmCancel-Nn_JgG9d.mjs} +1 -1
  212. package/dist/chunks/{NcInputConfirmCancel-GFlH1B9I.mjs.map → NcInputConfirmCancel-Nn_JgG9d.mjs.map} +1 -1
  213. package/dist/chunks/{NcListItem-BDrxkM0q.cjs → NcListItem-B_MPLJ_8.cjs} +3 -3
  214. package/dist/chunks/{NcListItem-rlwo19vU.mjs.map → NcListItem-B_MPLJ_8.cjs.map} +1 -1
  215. package/dist/chunks/{NcListItem-rlwo19vU.mjs → NcListItem-BopkGRDs.mjs} +4 -4
  216. package/dist/chunks/{NcListItem-BDrxkM0q.cjs.map → NcListItem-BopkGRDs.mjs.map} +1 -1
  217. package/dist/chunks/{NcListItemIcon-Bwl8bKaY.mjs → NcListItemIcon-CI23iFQz.mjs} +2 -2
  218. package/dist/chunks/{NcListItemIcon-Bwl8bKaY.mjs.map → NcListItemIcon-CI23iFQz.mjs.map} +1 -1
  219. package/dist/chunks/{NcListItemIcon-D_cwlGhm.cjs → NcListItemIcon-Dwgi2cPr.cjs} +2 -2
  220. package/dist/chunks/{NcListItemIcon-D_cwlGhm.cjs.map → NcListItemIcon-Dwgi2cPr.cjs.map} +1 -1
  221. package/dist/chunks/{NcPasswordField-D91QgkSR.mjs → NcPasswordField-BgSp7dK4.mjs} +1 -1
  222. package/dist/chunks/{NcPasswordField-D91QgkSR.mjs.map → NcPasswordField-BgSp7dK4.mjs.map} +1 -1
  223. package/dist/chunks/{NcPasswordField-EDrr_9PG.cjs → NcPasswordField-BooDzf0Z.cjs} +1 -1
  224. package/dist/chunks/{NcPasswordField-EDrr_9PG.cjs.map → NcPasswordField-BooDzf0Z.cjs.map} +1 -1
  225. package/dist/chunks/{NcRelatedResourcesPanel-DaLcC_9H.mjs → NcRelatedResourcesPanel-Ch1b_Gl3.mjs} +2 -2
  226. package/dist/chunks/{NcRelatedResourcesPanel-DaLcC_9H.mjs.map → NcRelatedResourcesPanel-Ch1b_Gl3.mjs.map} +1 -1
  227. package/dist/chunks/{NcRelatedResourcesPanel-DDL8rJnB.cjs → NcRelatedResourcesPanel-DaiuNCYU.cjs} +1 -1
  228. package/dist/chunks/{NcRelatedResourcesPanel-DDL8rJnB.cjs.map → NcRelatedResourcesPanel-DaiuNCYU.cjs.map} +1 -1
  229. package/dist/chunks/{NcRichContenteditable-DjUF2Kzl.cjs → NcRichContenteditable-BF3BkdqM.cjs} +10 -14
  230. package/dist/chunks/NcRichContenteditable-BF3BkdqM.cjs.map +1 -0
  231. package/dist/chunks/{NcRichContenteditable-CaeNwWTC.mjs → NcRichContenteditable-CEqdmoem.mjs} +15 -19
  232. package/dist/chunks/NcRichContenteditable-CEqdmoem.mjs.map +1 -0
  233. package/dist/chunks/{NcRichText-DVnS4C_H.mjs → NcRichText-CUKFkHQg.mjs} +72 -62
  234. package/dist/chunks/NcRichText-CUKFkHQg.mjs.map +1 -0
  235. package/dist/chunks/{NcRichText-D_p79y2S.cjs → NcRichText-DCkExl5g.cjs} +65 -55
  236. package/dist/chunks/NcRichText-DCkExl5g.cjs.map +1 -0
  237. package/dist/chunks/{NcSelect-BVCCppX6.cjs → NcSelect-Bn3oTHtq.cjs} +1 -1
  238. package/dist/chunks/{NcSelect-BVCCppX6.cjs.map → NcSelect-Bn3oTHtq.cjs.map} +1 -1
  239. package/dist/chunks/{NcSelect-BjojUUy7.mjs → NcSelect-Bo71Yd6L.mjs} +2 -2
  240. package/dist/chunks/{NcSelect-BjojUUy7.mjs.map → NcSelect-Bo71Yd6L.mjs.map} +1 -1
  241. package/dist/chunks/{NcSelectTags-CIa3RL2u.mjs → NcSelectTags-9aCrLRT0.mjs} +2 -2
  242. package/dist/chunks/{NcSelectTags-CIa3RL2u.mjs.map → NcSelectTags-9aCrLRT0.mjs.map} +1 -1
  243. package/dist/chunks/{NcSelectTags-b_FdAE_d.cjs → NcSelectTags-CgYWiDjX.cjs} +1 -1
  244. package/dist/chunks/{NcSelectTags-b_FdAE_d.cjs.map → NcSelectTags-CgYWiDjX.cjs.map} +1 -1
  245. package/dist/chunks/{NcSettingsInputText-D_wATSbL.cjs → NcSettingsInputText-1i2TqdMB.cjs} +1 -1
  246. package/dist/chunks/{NcSettingsInputText-D_wATSbL.cjs.map → NcSettingsInputText-1i2TqdMB.cjs.map} +1 -1
  247. package/dist/chunks/{NcSettingsInputText-BESxHP0m.mjs → NcSettingsInputText-JboV8u2l.mjs} +1 -1
  248. package/dist/chunks/{NcSettingsInputText-BESxHP0m.mjs.map → NcSettingsInputText-JboV8u2l.mjs.map} +1 -1
  249. package/dist/chunks/{NcSettingsSection-TG0j5-kd.cjs → NcSettingsSection-CNMpCD3o.cjs} +1 -1
  250. package/dist/chunks/{NcSettingsSection-TG0j5-kd.cjs.map → NcSettingsSection-CNMpCD3o.cjs.map} +1 -1
  251. package/dist/chunks/{NcSettingsSection-BzN6JXnV.mjs → NcSettingsSection-Lgwm3w2e.mjs} +1 -1
  252. package/dist/chunks/{NcSettingsSection-BzN6JXnV.mjs.map → NcSettingsSection-Lgwm3w2e.mjs.map} +1 -1
  253. package/dist/chunks/{NcSettingsSelectGroup-JJ4LZALf.cjs → NcSettingsSelectGroup-CgUJmyF7.cjs} +1 -1
  254. package/dist/chunks/{NcSettingsSelectGroup-JJ4LZALf.cjs.map → NcSettingsSelectGroup-CgUJmyF7.cjs.map} +1 -1
  255. package/dist/chunks/{NcSettingsSelectGroup-BRov--RO.mjs → NcSettingsSelectGroup-DUzmbtZx.mjs} +2 -2
  256. package/dist/chunks/{NcSettingsSelectGroup-BRov--RO.mjs.map → NcSettingsSelectGroup-DUzmbtZx.mjs.map} +1 -1
  257. package/dist/chunks/{NcTextField-DgzR5_48.cjs → NcTextField-B5cUYgRy.cjs} +1 -1
  258. package/dist/chunks/{NcTextField-DgzR5_48.cjs.map → NcTextField-B5cUYgRy.cjs.map} +1 -1
  259. package/dist/chunks/{NcTextField-BPGi70PD.mjs → NcTextField-D_eUEl2B.mjs} +1 -1
  260. package/dist/chunks/{NcTextField-BPGi70PD.mjs.map → NcTextField-D_eUEl2B.mjs.map} +1 -1
  261. package/dist/chunks/{NcTimezonePicker-8ZYdOp_g.cjs → NcTimezonePicker-BF5TeadZ.cjs} +1 -1
  262. package/dist/chunks/{NcTimezonePicker-8ZYdOp_g.cjs.map → NcTimezonePicker-BF5TeadZ.cjs.map} +1 -1
  263. package/dist/chunks/{NcTimezonePicker-jCKohlic.mjs → NcTimezonePicker-CH1lkCMF.mjs} +2 -2
  264. package/dist/chunks/{NcTimezonePicker-jCKohlic.mjs.map → NcTimezonePicker-CH1lkCMF.mjs.map} +1 -1
  265. package/dist/chunks/{NcUserBubble-Bfph5VfL.cjs → NcUserBubble-BadEJRgs.cjs} +1 -1
  266. package/dist/chunks/{NcUserBubble-Bfph5VfL.cjs.map → NcUserBubble-BadEJRgs.cjs.map} +1 -1
  267. package/dist/chunks/{NcUserBubble-DwKN1aRa.mjs → NcUserBubble-C0HbPO9p.mjs} +1 -1
  268. package/dist/chunks/{NcUserBubble-DwKN1aRa.mjs.map → NcUserBubble-C0HbPO9p.mjs.map} +1 -1
  269. package/dist/chunks/{NcUserStatusIcon-Bu_nFfO_.cjs → NcUserStatusIcon-B69NZ9Hw.cjs} +1 -1
  270. package/dist/chunks/{NcUserStatusIcon-Bu_nFfO_.cjs.map → NcUserStatusIcon-B69NZ9Hw.cjs.map} +1 -1
  271. package/dist/chunks/{NcUserStatusIcon-Blep5GZX.mjs → NcUserStatusIcon-HOUdT_MR.mjs} +1 -1
  272. package/dist/chunks/{NcUserStatusIcon-Blep5GZX.mjs.map → NcUserStatusIcon-HOUdT_MR.mjs.map} +1 -1
  273. package/dist/chunks/{ScopeComponent-CGJeYf1D.mjs → ScopeComponent-Dz4pyD77.mjs} +1 -1
  274. package/dist/chunks/{ScopeComponent-CGJeYf1D.mjs.map → ScopeComponent-Dz4pyD77.mjs.map} +1 -1
  275. package/dist/chunks/{ScopeComponent-BiLZtJeb.cjs → ScopeComponent-IO407Bzb.cjs} +1 -1
  276. package/dist/chunks/{ScopeComponent-BiLZtJeb.cjs.map → ScopeComponent-IO407Bzb.cjs.map} +1 -1
  277. package/dist/chunks/_l10n-B8iumFKB.cjs +66 -0
  278. package/dist/chunks/_l10n-B8iumFKB.cjs.map +1 -0
  279. package/dist/chunks/_l10n-BaNxGGXy.mjs +68 -0
  280. package/dist/chunks/_l10n-BaNxGGXy.mjs.map +1 -0
  281. package/dist/chunks/autolink-DNGB8YSW.mjs +86 -0
  282. package/dist/chunks/autolink-DNGB8YSW.mjs.map +1 -0
  283. package/dist/chunks/autolink-MMzlO_Ai.cjs +82 -0
  284. package/dist/chunks/autolink-MMzlO_Ai.cjs.map +1 -0
  285. package/dist/chunks/getAvatarUrl-BHpn8LgJ.mjs +32 -0
  286. package/dist/chunks/getAvatarUrl-BHpn8LgJ.mjs.map +1 -0
  287. package/dist/chunks/getAvatarUrl-CjIpoO6I.cjs +31 -0
  288. package/dist/chunks/getAvatarUrl-CjIpoO6I.cjs.map +1 -0
  289. package/dist/chunks/{index-CVsxVZon.cjs → index-CMnR5Pf6.cjs} +7 -12
  290. package/dist/chunks/index-CMnR5Pf6.cjs.map +1 -0
  291. package/dist/chunks/{index-BAVa4G2v.mjs → index-uiNhPYvS.mjs} +23 -28
  292. package/dist/chunks/index-uiNhPYvS.mjs.map +1 -0
  293. package/dist/chunks/{referencePickerModal-ChgMFkNu.mjs → referencePickerModal-AvSHyw1b.mjs} +4 -4
  294. package/dist/chunks/{referencePickerModal-ChgMFkNu.mjs.map → referencePickerModal-AvSHyw1b.mjs.map} +1 -1
  295. package/dist/chunks/{referencePickerModal-DRZH-El6.cjs → referencePickerModal-B_Su3XpN.cjs} +1 -1
  296. package/dist/chunks/{referencePickerModal-DRZH-El6.cjs.map → referencePickerModal-B_Su3XpN.cjs.map} +1 -1
  297. package/dist/chunks/{usernameToColor-DrnKFnLP.mjs → usernameToColor-BHkzj1tb.mjs} +1 -1
  298. package/dist/chunks/{usernameToColor-DrnKFnLP.mjs.map → usernameToColor-BHkzj1tb.mjs.map} +1 -1
  299. package/dist/chunks/{usernameToColor-BG9PjZRM.cjs → usernameToColor-DA36rR48.cjs} +1 -1
  300. package/dist/chunks/{usernameToColor-BG9PjZRM.cjs.map → usernameToColor-DA36rR48.cjs.map} +1 -1
  301. package/dist/index.cjs +5 -5
  302. package/dist/index.mjs +45 -45
  303. package/dist/utils/getAvatarUrl.d.ts +22 -0
  304. package/package.json +2 -1
  305. package/dist/assets/NcListItem--ilRNXci.css +0 -179
  306. package/dist/chunks/NcActionInput-B_upGNjs.mjs.map +0 -1
  307. package/dist/chunks/NcActionInput-C6WR9W8-.cjs.map +0 -1
  308. package/dist/chunks/NcAppSidebar-BbEflEtM.mjs.map +0 -1
  309. package/dist/chunks/NcAppSidebar-DNAgJFfm.cjs.map +0 -1
  310. package/dist/chunks/NcAvatar-CDeuGCns.cjs.map +0 -1
  311. package/dist/chunks/NcAvatar-k_VeT7Vp.mjs.map +0 -1
  312. package/dist/chunks/NcCheckboxRadioSwitch.vue_vue_type_style_index_0_scoped_2603be83_lang-B5QWlofX.cjs.map +0 -1
  313. package/dist/chunks/NcCheckboxRadioSwitch.vue_vue_type_style_index_0_scoped_2603be83_lang-CURkxtfw.mjs.map +0 -1
  314. package/dist/chunks/NcRichContenteditable-CaeNwWTC.mjs.map +0 -1
  315. package/dist/chunks/NcRichContenteditable-DjUF2Kzl.cjs.map +0 -1
  316. package/dist/chunks/NcRichText-DVnS4C_H.mjs.map +0 -1
  317. package/dist/chunks/NcRichText-D_p79y2S.cjs.map +0 -1
  318. package/dist/chunks/_l10n-BG5lXDmm.cjs +0 -66
  319. package/dist/chunks/_l10n-BG5lXDmm.cjs.map +0 -1
  320. package/dist/chunks/_l10n-Cj65IvRp.mjs +0 -68
  321. package/dist/chunks/_l10n-Cj65IvRp.mjs.map +0 -1
  322. package/dist/chunks/autolink-BtgUDDdk.mjs +0 -59
  323. package/dist/chunks/autolink-BtgUDDdk.mjs.map +0 -1
  324. package/dist/chunks/autolink-D0rLUkqm.cjs +0 -55
  325. package/dist/chunks/autolink-D0rLUkqm.cjs.map +0 -1
  326. package/dist/chunks/index-BAVa4G2v.mjs.map +0 -1
  327. package/dist/chunks/index-CVsxVZon.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"NcDashboardWidgetItem-Buh2BPAN.cjs","sources":["../../src/components/NcDashboardWidgetItem/NcDashboardWidgetItem.vue"],"sourcesContent":["<!--\n - @copyright Copyright (c) 2020 Julien Veyssier <eneiluj@posteo.net>\n -\n - @author Julien Veyssier <eneiluj@posteo.net>\n -\n - @license GNU AGPL version 3 or any later version\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n\n### General description\n\nThis component is meant to be used inside a DashboardWidget component.\n\n</docs>\n\n<template>\n\t<div @mouseover=\"hovered = true\" @mouseleave=\"hovered = false\">\n\t\t<component :is=\"targetUrl ? 'a' : 'div'\"\n\t\t\t:href=\"targetUrl || undefined\"\n\t\t\t:target=\"targetUrl ? '_blank' : undefined\"\n\t\t\t:class=\"{ 'item-list__entry': true, 'item-list__entry--has-actions-menu': gotMenu }\"\n\t\t\t@click=\"onLinkClick\">\n\t\t\t<!-- @slot Slot for passing a user avatar. -->\n\t\t\t<slot name=\"avatar\" :avatar-url=\"avatarUrl\" :avatar-username=\"avatarUsername\">\n\t\t\t\t<NcAvatar class=\"item-avatar\"\n\t\t\t\t\t:size=\"44\"\n\t\t\t\t\t:url=\"avatarUrl\"\n\t\t\t\t\t:user=\"avatarUsername\"\n\t\t\t\t\t:is-no-user=\"avatarIsNoUser\"\n\t\t\t\t\t:show-user-status=\"!gotOverlayIcon\" />\n\t\t\t</slot>\n\t\t\t<img v-if=\"overlayIconUrl\"\n\t\t\t\tclass=\"item-icon\"\n\t\t\t\talt=\"\"\n\t\t\t\t:src=\"overlayIconUrl\">\n\t\t\t<div class=\"item__details\">\n\t\t\t\t<h3 :title=\"mainText\">\n\t\t\t\t\t{{ mainText }}\n\t\t\t\t</h3>\n\t\t\t\t<span v-if=\"subText !== ''\" class=\"message\" :title=\"subText\">\n\t\t\t\t\t{{ subText }}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<NcActions v-if=\"gotMenu\" :force-menu=\"forceMenu\">\n\t\t\t\t<!-- @slot This slot can be used to provide actions for each dashboard widget item. -->\n\t\t\t\t<slot name=\"actions\">\n\t\t\t\t\t<NcActionButton v-for=\"(m, menuItemId) in itemMenu\"\n\t\t\t\t\t\t:key=\"menuItemId\"\n\t\t\t\t\t\t:icon=\"m.icon\"\n\t\t\t\t\t\t:close-after-click=\"true\"\n\t\t\t\t\t\t@click.prevent.stop=\"$emit(menuItemId, item)\">\n\t\t\t\t\t\t{{ m.text }}\n\t\t\t\t\t</NcActionButton>\n\t\t\t\t</slot>\n\t\t\t</NcActions>\n\t\t</component>\n\t</div>\n</template>\n\n<script>\nimport NcAvatar from '../NcAvatar/index.js'\nimport NcActions from '../NcActions/index.js'\nimport NcActionButton from '../NcActionButton/index.js'\n\nexport default {\n\tname: 'NcDashboardWidgetItem',\n\tcomponents: {\n\t\tNcAvatar,\n\t\tNcActions,\n\t\tNcActionButton,\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The item id (optional)\n\t\t */\n\t\tid: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * The item element is a link to this URL (optional)\n\t\t */\n\t\ttargetUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Where to get the avatar image. (optional) Used if avatarUsername is not defined.\n\t\t */\n\t\tavatarUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Name to provide to the Avatar. (optional) Used if avatarUrl is not defined.\n\t\t */\n\t\tavatarUsername: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Is the avatarUsername not a user's name? (optional, false by default)\n\t\t */\n\t\tavatarIsNoUser: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t/**\n\t\t * Small icon to display on the bottom-right corner of the avatar (optional)\n\t\t */\n\t\toverlayIconUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Item main text (mandatory)\n\t\t */\n\t\tmainText: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\t\t/**\n\t\t * Item subline text (optional)\n\t\t */\n\t\tsubText: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t\t/**\n\t\t * An object containing context menu entries that will be displayed for each items (optional)\n\t\t */\n\t\titemMenu: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => { return {} },\n\t\t},\n\n\t\t/**\n\t\t * Specify whether the 3 dot menu is forced when only one action is present\n\t\t */\n\t\tforceMenu: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\thovered: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\titem() {\n\t\t\treturn {\n\t\t\t\tid: this.id,\n\t\t\t\ttargetUrl: this.targetUrl,\n\t\t\t\tavatarUrl: this.avatarUrl,\n\t\t\t\tavatarUsername: this.avatarUsername,\n\t\t\t\toverlayIconUrl: this.overlayIconUrl,\n\t\t\t\tmainText: this.mainText,\n\t\t\t\tsubText: this.subText,\n\t\t\t}\n\t\t},\n\t\tgotMenu() {\n\t\t\treturn Object.keys(this.itemMenu).length !== 0 || !!this.$slots.actions\n\t\t},\n\t\tgotOverlayIcon() {\n\t\t\treturn this.overlayIconUrl && this.overlayIconUrl !== ''\n\t\t},\n\t},\n\n\tmethods: {\n\t\tonLinkClick(event) {\n\t\t\tif (event.target.closest('.action-item')) {\n\t\t\t\tevent.preventDefault()\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.item-list__entry {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tposition: relative;\n\tpadding: 8px;\n\n\t&:hover,\n\t&:focus {\n\t\tbackground-color: var(--color-background-hover);\n\t\tborder-radius: var(--border-radius-large);\n\t}\n\t.item-avatar {\n\t\tposition: relative;\n\t\tmargin-top: auto;\n\t\tmargin-bottom: auto;\n\t}\n\t.item__details {\n\t\tpadding-left: 8px;\n\t\tmax-height: 44px;\n\t\tflex-grow: 1;\n\t\toverflow: hidden;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: center;\n\t\tmin-height: 44px;\n\n\t\th3,\n\t\t.message {\n\t\t\twhite-space: nowrap;\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t}\n\t\t.message span {\n\t\t\twidth: 10px;\n\t\t\tdisplay: inline-block;\n\t\t\tmargin-bottom: -3px;\n\t\t}\n\t\th3 {\n\t\t\tfont-size: 100%;\n\t\t\tmargin: 0;\n\t\t}\n\t\t.message {\n\t\t\twidth: 100%;\n\t\t\tcolor: var(--color-text-maxcontrast);\n\t\t}\n\t}\n\n\t.item-icon {\n\t\tposition: relative;\n\t\twidth: 14px;\n\t\theight: 14px;\n\t\tmargin: 27px -3px 0px -7px;\n\t}\n\n\tbutton.primary {\n\t\tpadding: 21px;\n\t\tmargin: 0;\n\t}\n}\n/*\n.content-popover {\n\theight: 0px;\n\twidth: 0px;\n\tmargin-left: auto;\n\tmargin-right: auto;\n}\n.popover-container {\n\twidth: 100%;\n\theight: 0px;\n}\n*/\n</style>\n"],"names":["_sfc_main","NcAvatar","NcActions","NcActionButton","event"],"mappings":";+LA+EAA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,IACA,UAAAC,EAAA;AAAA,IACA,WAAAC,EAAA;AAAA,IACA,gBAAAC;AAAAA,EACA;AAAA,EAEA,OAAA;AAAA;AAAA;AAAA;AAAA,IAIA,IAAA;AAAA,MACA,MAAA,CAAA,QAAA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,gBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,gBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,gBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,UAAA;AAAA,MACA,MAAA;AAAA,MACA,UAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,SAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,UAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA,OAAA;IACA;AAAA;AAAA;AAAA;AAAA,IAKA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,OAAA;AACA,WAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,UAAA;AAAA,IACA,OAAA;AACA,aAAA;AAAA,QACA,IAAA,KAAA;AAAA,QACA,WAAA,KAAA;AAAA,QACA,WAAA,KAAA;AAAA,QACA,gBAAA,KAAA;AAAA,QACA,gBAAA,KAAA;AAAA,QACA,UAAA,KAAA;AAAA,QACA,SAAA,KAAA;AAAA,MACA;AAAA,IACA;AAAA,IACA,UAAA;AACA,aAAA,OAAA,KAAA,KAAA,QAAA,EAAA,WAAA,KAAA,CAAA,CAAA,KAAA,OAAA;AAAA,IACA;AAAA,IACA,iBAAA;AACA,aAAA,KAAA,kBAAA,KAAA,mBAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,SAAA;AAAA,IACA,YAAAC,GAAA;AACA,MAAAA,EAAA,OAAA,QAAA,cAAA,KACAA,EAAA,eAAA;AAAA,IAEA;AAAA,EACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NcDashboardWidgetItem-xqVAP32n.cjs","sources":["../../src/components/NcDashboardWidgetItem/NcDashboardWidgetItem.vue"],"sourcesContent":["<!--\n - @copyright Copyright (c) 2020 Julien Veyssier <eneiluj@posteo.net>\n -\n - @author Julien Veyssier <eneiluj@posteo.net>\n -\n - @license GNU AGPL version 3 or any later version\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n\n### General description\n\nThis component is meant to be used inside a DashboardWidget component.\n\n</docs>\n\n<template>\n\t<div @mouseover=\"hovered = true\" @mouseleave=\"hovered = false\">\n\t\t<component :is=\"targetUrl ? 'a' : 'div'\"\n\t\t\t:href=\"targetUrl || undefined\"\n\t\t\t:target=\"targetUrl ? '_blank' : undefined\"\n\t\t\t:class=\"{ 'item-list__entry': true, 'item-list__entry--has-actions-menu': gotMenu }\"\n\t\t\t@click=\"onLinkClick\">\n\t\t\t<!-- @slot Slot for passing a user avatar. -->\n\t\t\t<slot name=\"avatar\" :avatar-url=\"avatarUrl\" :avatar-username=\"avatarUsername\">\n\t\t\t\t<NcAvatar class=\"item-avatar\"\n\t\t\t\t\t:size=\"44\"\n\t\t\t\t\t:url=\"avatarUrl\"\n\t\t\t\t\t:user=\"avatarUsername\"\n\t\t\t\t\t:is-no-user=\"avatarIsNoUser\"\n\t\t\t\t\t:show-user-status=\"!gotOverlayIcon\" />\n\t\t\t</slot>\n\t\t\t<img v-if=\"overlayIconUrl\"\n\t\t\t\tclass=\"item-icon\"\n\t\t\t\talt=\"\"\n\t\t\t\t:src=\"overlayIconUrl\">\n\t\t\t<div class=\"item__details\">\n\t\t\t\t<h3 :title=\"mainText\">\n\t\t\t\t\t{{ mainText }}\n\t\t\t\t</h3>\n\t\t\t\t<span v-if=\"subText !== ''\" class=\"message\" :title=\"subText\">\n\t\t\t\t\t{{ subText }}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<NcActions v-if=\"gotMenu\" :force-menu=\"forceMenu\">\n\t\t\t\t<!-- @slot This slot can be used to provide actions for each dashboard widget item. -->\n\t\t\t\t<slot name=\"actions\">\n\t\t\t\t\t<NcActionButton v-for=\"(m, menuItemId) in itemMenu\"\n\t\t\t\t\t\t:key=\"menuItemId\"\n\t\t\t\t\t\t:icon=\"m.icon\"\n\t\t\t\t\t\t:close-after-click=\"true\"\n\t\t\t\t\t\t@click.prevent.stop=\"$emit(menuItemId, item)\">\n\t\t\t\t\t\t{{ m.text }}\n\t\t\t\t\t</NcActionButton>\n\t\t\t\t</slot>\n\t\t\t</NcActions>\n\t\t</component>\n\t</div>\n</template>\n\n<script>\nimport NcAvatar from '../NcAvatar/index.js'\nimport NcActions from '../NcActions/index.js'\nimport NcActionButton from '../NcActionButton/index.js'\n\nexport default {\n\tname: 'NcDashboardWidgetItem',\n\tcomponents: {\n\t\tNcAvatar,\n\t\tNcActions,\n\t\tNcActionButton,\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The item id (optional)\n\t\t */\n\t\tid: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * The item element is a link to this URL (optional)\n\t\t */\n\t\ttargetUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Where to get the avatar image. (optional) Used if avatarUsername is not defined.\n\t\t */\n\t\tavatarUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Name to provide to the Avatar. (optional) Used if avatarUrl is not defined.\n\t\t */\n\t\tavatarUsername: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Is the avatarUsername not a user's name? (optional, false by default)\n\t\t */\n\t\tavatarIsNoUser: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t/**\n\t\t * Small icon to display on the bottom-right corner of the avatar (optional)\n\t\t */\n\t\toverlayIconUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Item main text (mandatory)\n\t\t */\n\t\tmainText: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\t\t/**\n\t\t * Item subline text (optional)\n\t\t */\n\t\tsubText: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t\t/**\n\t\t * An object containing context menu entries that will be displayed for each items (optional)\n\t\t */\n\t\titemMenu: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => { return {} },\n\t\t},\n\n\t\t/**\n\t\t * Specify whether the 3 dot menu is forced when only one action is present\n\t\t */\n\t\tforceMenu: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\thovered: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\titem() {\n\t\t\treturn {\n\t\t\t\tid: this.id,\n\t\t\t\ttargetUrl: this.targetUrl,\n\t\t\t\tavatarUrl: this.avatarUrl,\n\t\t\t\tavatarUsername: this.avatarUsername,\n\t\t\t\toverlayIconUrl: this.overlayIconUrl,\n\t\t\t\tmainText: this.mainText,\n\t\t\t\tsubText: this.subText,\n\t\t\t}\n\t\t},\n\t\tgotMenu() {\n\t\t\treturn Object.keys(this.itemMenu).length !== 0 || !!this.$slots.actions\n\t\t},\n\t\tgotOverlayIcon() {\n\t\t\treturn this.overlayIconUrl && this.overlayIconUrl !== ''\n\t\t},\n\t},\n\n\tmethods: {\n\t\tonLinkClick(event) {\n\t\t\tif (event.target.closest('.action-item')) {\n\t\t\t\tevent.preventDefault()\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.item-list__entry {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tposition: relative;\n\tpadding: 8px;\n\n\t&:hover,\n\t&:focus {\n\t\tbackground-color: var(--color-background-hover);\n\t\tborder-radius: var(--border-radius-large);\n\t}\n\t.item-avatar {\n\t\tposition: relative;\n\t\tmargin-top: auto;\n\t\tmargin-bottom: auto;\n\t}\n\t.item__details {\n\t\tpadding-left: 8px;\n\t\tmax-height: 44px;\n\t\tflex-grow: 1;\n\t\toverflow: hidden;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: center;\n\t\tmin-height: 44px;\n\n\t\th3,\n\t\t.message {\n\t\t\twhite-space: nowrap;\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t}\n\t\t.message span {\n\t\t\twidth: 10px;\n\t\t\tdisplay: inline-block;\n\t\t\tmargin-bottom: -3px;\n\t\t}\n\t\th3 {\n\t\t\tfont-size: 100%;\n\t\t\tmargin: 0;\n\t\t}\n\t\t.message {\n\t\t\twidth: 100%;\n\t\t\tcolor: var(--color-text-maxcontrast);\n\t\t}\n\t}\n\n\t.item-icon {\n\t\tposition: relative;\n\t\twidth: 14px;\n\t\theight: 14px;\n\t\tmargin: 27px -3px 0px -7px;\n\t}\n\n\tbutton.primary {\n\t\tpadding: 21px;\n\t\tmargin: 0;\n\t}\n}\n/*\n.content-popover {\n\theight: 0px;\n\twidth: 0px;\n\tmargin-left: auto;\n\tmargin-right: auto;\n}\n.popover-container {\n\twidth: 100%;\n\theight: 0px;\n}\n*/\n</style>\n"],"names":["_sfc_main","NcAvatar","NcActions","NcActionButton","event"],"mappings":";+LA+EAA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,IACA,UAAAC,EAAA;AAAA,IACA,WAAAC,EAAA;AAAA,IACA,gBAAAC;AAAAA,EACA;AAAA,EAEA,OAAA;AAAA;AAAA;AAAA;AAAA,IAIA,IAAA;AAAA,MACA,MAAA,CAAA,QAAA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,gBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,gBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,gBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,UAAA;AAAA,MACA,MAAA;AAAA,MACA,UAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,SAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,UAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA,OAAA;IACA;AAAA;AAAA;AAAA;AAAA,IAKA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,OAAA;AACA,WAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,UAAA;AAAA,IACA,OAAA;AACA,aAAA;AAAA,QACA,IAAA,KAAA;AAAA,QACA,WAAA,KAAA;AAAA,QACA,WAAA,KAAA;AAAA,QACA,gBAAA,KAAA;AAAA,QACA,gBAAA,KAAA;AAAA,QACA,UAAA,KAAA;AAAA,QACA,SAAA,KAAA;AAAA,MACA;AAAA,IACA;AAAA,IACA,UAAA;AACA,aAAA,OAAA,KAAA,KAAA,QAAA,EAAA,WAAA,KAAA,CAAA,CAAA,KAAA,OAAA;AAAA,IACA;AAAA,IACA,iBAAA;AACA,aAAA,KAAA,kBAAA,KAAA,mBAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,SAAA;AAAA,IACA,YAAAC,GAAA;AACA,MAAAA,EAAA,OAAA,QAAA,cAAA,KACAA,EAAA,eAAA;AAAA,IAEA;AAAA,EACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { ref as T, unref as f, computed as i, watch as g, onMounted as y, onUnmounted as D } from "vue";
2
2
  import { getCanonicalLocale as _ } from "@nextcloud/l10n";
3
- import { r as S, j as b, a as c } from "./_l10n-Cj65IvRp.mjs";
3
+ import { r as S, j as b, a as c } from "./_l10n-BaNxGGXy.mjs";
4
4
  import { n as F } from "./_plugin-vue2_normalizer-Bj5bLKV4.mjs";
5
5
  S(b);
6
6
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"NcDateTime-GW15p7yp.mjs","sources":["../../src/composables/useFormatDateTime.js","../../src/components/NcDateTime/NcDateTime.vue"],"sourcesContent":["/**\n * @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @author Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { getCanonicalLocale } from '@nextcloud/l10n'\nimport { computed, onUnmounted, ref, onMounted, watch, unref } from 'vue'\nimport { t } from '../l10n.js'\n\nconst FEW_SECONDS_AGO = {\n\tlong: t('a few seconds ago'),\n\tshort: t('seconds ago'), // FOR TRANSLATORS: Shorter version of 'a few seconds ago'\n\tnarrow: t('sec. ago'), // FOR TRANSLATORS: If possible in your language an even shorter version of 'a few seconds ago'\n}\n\n/**\n * Composable for formatting time stamps using current users locale\n *\n * @param {Date | number | import('vue').Ref<Date> | import('vue').Ref<number>} timestamp Current timestamp\n * @param {object} opts Optional options\n * @param {Intl.DateTimeFormatOptions} opts.format The format used for displaying, or if relative time is used the format used for the title (optional)\n * @param {boolean} opts.ignoreSeconds Ignore seconds when displaying the relative time and just show `a few seconds ago`\n * @param {false | 'long' | 'short' | 'narrow'} opts.relativeTime Wether to display the timestamp as time from now (optional)\n */\nexport function useFormatDateTime(timestamp = Date.now(), opts = {}) {\n\t// Current time as Date.now is not reactive\n\tconst currentTime = ref(Date.now())\n\t// The interval ID for the window\n\tlet intervalId = null\n\n\tconst options = ref({\n\t\ttimeStyle: 'medium',\n\t\tdateStyle: 'short',\n\t\trelativeTime: 'long',\n\t\tignoreSeconds: false,\n\t\t...unref(opts),\n\t})\n\tconst wrappedOptions = computed(() => ({ ...unref(opts), ...options.value }))\n\n\t/** ECMA Date object of the timestamp */\n\tconst date = computed(() => new Date(unref(timestamp)))\n\n\tconst formattedFullTime = computed(() => {\n\t\tconst formatter = new Intl.DateTimeFormat(getCanonicalLocale(), wrappedOptions.value.format)\n\t\treturn formatter.format(date.value)\n\t})\n\n\t/** Time string formatted for main text */\n\tconst formattedTime = computed(() => {\n\t\tif (wrappedOptions.value.relativeTime !== false) {\n\t\t\tconst formatter = new Intl.RelativeTimeFormat(getCanonicalLocale(), { numeric: 'auto', style: wrappedOptions.value.relativeTime })\n\n\t\t\tconst diff = date.value - currentTime.value\n\t\t\tconst seconds = diff / 1000\n\t\t\tif (Math.abs(seconds) <= 90) {\n\t\t\t\tif (wrappedOptions.value.ignoreSeconds) {\n\t\t\t\t\treturn FEW_SECONDS_AGO[wrappedOptions.value.relativeTime]\n\t\t\t\t} else {\n\t\t\t\t\treturn formatter.format(Math.round(seconds), 'second')\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst minutes = seconds / 60\n\t\t\tif (Math.abs(minutes) <= 90) {\n\t\t\t\treturn formatter.format(Math.round(minutes), 'minute')\n\t\t\t}\n\t\t\tconst hours = minutes / 60\n\t\t\tif (Math.abs(hours) <= 24) {\n\t\t\t\treturn formatter.format(Math.round(hours), 'hour')\n\t\t\t}\n\t\t\tconst days = hours / 24\n\t\t\tif (Math.abs(days) <= 6) {\n\t\t\t\treturn formatter.format(Math.round(days), 'day')\n\t\t\t}\n\t\t\tconst weeks = days / 7\n\t\t\tif (Math.abs(weeks) <= 4) {\n\t\t\t\treturn formatter.format(Math.round(weeks), 'week')\n\t\t\t}\n\t\t\tconst months = days / 30\n\t\t\tif (Math.abs(months) <= 12) {\n\t\t\t\treturn formatter.format(Math.round(months), 'month')\n\t\t\t}\n\t\t\treturn formatter.format(Math.round(days / 365), 'year')\n\t\t}\n\t\treturn formattedFullTime\n\t})\n\n\t// Set or clear interval if relative time is dis/enabled\n\twatch([wrappedOptions], (opts) => {\n\t\twindow.clearInterval(intervalId)\n\t\tintervalId = undefined\n\t\tif (opts.relativeTime) {\n\t\t\tintervalId = window.setInterval(() => { currentTime.value = new Date() }, 1000)\n\t\t}\n\t})\n\n\t// Start the interval for setting the current time if relative time is enabled\n\tonMounted(() => {\n\t\tif (wrappedOptions.value.relativeTime !== false) {\n\t\t\tintervalId = window.setInterval(() => { currentTime.value = new Date() }, 1000)\n\t\t}\n\t})\n\n\t// ensure interval is cleared\n\tonUnmounted(() => {\n\t\twindow.clearInterval(intervalId)\n\t})\n\n\treturn {\n\t\tformattedTime,\n\t\tformattedFullTime,\n\t\toptions,\n\t}\n}\n","<!--\n - @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @author Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n\n### General description\n\nThis components purpose is to display a timestamp in the users local time format.\nIt also supports relative time, for examples *6 seconds ago*.\n\n#### Standard usage\n\nWithout any optional parameters the timestamp is displayed as a relative datetime and a title with the full date is added.\n\n```vue\n<template>\n\t<NcDateTime :timestamp=\"timestamp\" />\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n#### Ignore seconds\n\nIf you do not want the seconds to be counted up until minutes are reached you can simply use the `ignore-seconds` property.\n\n```vue\n<template>\n\t<NcDateTime :timestamp=\"timestamp\" :ignore-seconds=\"true\" />\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n#### Custom date or time format\n\nThe component allows to format the full date for the title by settings the `format` property.\nIt is also possible to disable relative time by setting the `relativeTime` property to `false`.\n\n```vue\n<template>\n\t<div>\n\t\t<h4>Short relative time</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" relative-time=\"short\" />\n\n\t\t<h4>Custom title format</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" :format=\"timeFormat\" />\n\n\t\t<h4>Without relative time</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" :format=\"timeFormat\" :relative-time=\"false\" />\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t/** For allowed formats see the Intl.DateTimeFormat options */\n\t\t\t\ttimeFormat: {\n\t\t\t\t\tdateStyle: 'short',\n\t\t\t\t\ttimeStyle: 'full'\n\t\t\t\t},\n\t\t\t}\n\t\t},\n\t}\n</script>\n<style>\nh4 {\n\tfont-weight: bold;\n\tmargin-top: 12px;\n}\n</style>\n```\n</docs>\n\n<template>\n\t<span class=\"nc-datetime\"\n\t\t:data-timestamp=\"timestamp\"\n\t\t:title=\"formattedFullTime\">{{ formattedTime }}</span>\n</template>\n\n<script>\nimport { computed } from 'vue'\nimport { useFormatDateTime } from '../../composables/useFormatDateTime.js'\n\nexport default {\n\tname: 'NcDateTime',\n\n\tprops: {\n\t\t/**\n\t\t * The timestamp to display, either an unix timestamp (in milliseconds) or a Date object\n\t\t */\n\t\ttimestamp: {\n\t\t\ttype: [Date, Number],\n\t\t\trequired: true,\n\t\t},\n\t\t/**\n\t\t * The format used for displaying, or if relative time is used the format used for the title (optional)\n\t\t *\n\t\t * @type {Intl.DateTimeFormatOptions}\n\t\t */\n\t\tformat: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({ timeStyle: 'medium', dateStyle: 'short' }),\n\t\t},\n\t\t/**\n\t\t * Wether to display the timestamp as time from now (optional)\n\t\t *\n\t\t * - `false`: Disable relative time\n\t\t * - `'long'`: Long text, like *2 seconds ago* (default)\n\t\t * - `'short'`: Short text, like *2 sec. ago*\n\t\t * - `'narrow'`: Even shorter text (same as `'short'` on some languages)\n\t\t */\n\t\trelativeTime: {\n\t\t\ttype: [Boolean, String],\n\t\t\tdefault: 'long',\n\t\t\tvalidator: (v) => v === false || ['long', 'short', 'narrow'].includes(v),\n\t\t},\n\t\t/**\n\t\t * Ignore seconds when displaying the relative time and just show `a few seconds ago`\n\t\t */\n\t\tignoreSeconds: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tsetup(props) {\n\t\tconst timestamp = computed(() => props.timestamp)\n\t\tconst { formattedTime, formattedFullTime } = useFormatDateTime(timestamp, props)\n\t\treturn {\n\t\t\tformattedTime,\n\t\t\tformattedFullTime,\n\t\t}\n\t},\n}\n</script>\n"],"names":["FEW_SECONDS_AGO","t","useFormatDateTime","timestamp","opts","currentTime","ref","intervalId","options","unref","wrappedOptions","computed","date","formattedFullTime","getCanonicalLocale","formattedTime","formatter","seconds","minutes","hours","days","weeks","months","watch","onMounted","onUnmounted","_sfc_main","v","props"],"mappings":"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"}
1
+ {"version":3,"file":"NcDateTime-CeOdKcvC.mjs","sources":["../../src/composables/useFormatDateTime.js","../../src/components/NcDateTime/NcDateTime.vue"],"sourcesContent":["/**\n * @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @author Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { getCanonicalLocale } from '@nextcloud/l10n'\nimport { computed, onUnmounted, ref, onMounted, watch, unref } from 'vue'\nimport { t } from '../l10n.js'\n\nconst FEW_SECONDS_AGO = {\n\tlong: t('a few seconds ago'),\n\tshort: t('seconds ago'), // FOR TRANSLATORS: Shorter version of 'a few seconds ago'\n\tnarrow: t('sec. ago'), // FOR TRANSLATORS: If possible in your language an even shorter version of 'a few seconds ago'\n}\n\n/**\n * Composable for formatting time stamps using current users locale\n *\n * @param {Date | number | import('vue').Ref<Date> | import('vue').Ref<number>} timestamp Current timestamp\n * @param {object} opts Optional options\n * @param {Intl.DateTimeFormatOptions} opts.format The format used for displaying, or if relative time is used the format used for the title (optional)\n * @param {boolean} opts.ignoreSeconds Ignore seconds when displaying the relative time and just show `a few seconds ago`\n * @param {false | 'long' | 'short' | 'narrow'} opts.relativeTime Wether to display the timestamp as time from now (optional)\n */\nexport function useFormatDateTime(timestamp = Date.now(), opts = {}) {\n\t// Current time as Date.now is not reactive\n\tconst currentTime = ref(Date.now())\n\t// The interval ID for the window\n\tlet intervalId = null\n\n\tconst options = ref({\n\t\ttimeStyle: 'medium',\n\t\tdateStyle: 'short',\n\t\trelativeTime: 'long',\n\t\tignoreSeconds: false,\n\t\t...unref(opts),\n\t})\n\tconst wrappedOptions = computed(() => ({ ...unref(opts), ...options.value }))\n\n\t/** ECMA Date object of the timestamp */\n\tconst date = computed(() => new Date(unref(timestamp)))\n\n\tconst formattedFullTime = computed(() => {\n\t\tconst formatter = new Intl.DateTimeFormat(getCanonicalLocale(), wrappedOptions.value.format)\n\t\treturn formatter.format(date.value)\n\t})\n\n\t/** Time string formatted for main text */\n\tconst formattedTime = computed(() => {\n\t\tif (wrappedOptions.value.relativeTime !== false) {\n\t\t\tconst formatter = new Intl.RelativeTimeFormat(getCanonicalLocale(), { numeric: 'auto', style: wrappedOptions.value.relativeTime })\n\n\t\t\tconst diff = date.value - currentTime.value\n\t\t\tconst seconds = diff / 1000\n\t\t\tif (Math.abs(seconds) <= 90) {\n\t\t\t\tif (wrappedOptions.value.ignoreSeconds) {\n\t\t\t\t\treturn FEW_SECONDS_AGO[wrappedOptions.value.relativeTime]\n\t\t\t\t} else {\n\t\t\t\t\treturn formatter.format(Math.round(seconds), 'second')\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst minutes = seconds / 60\n\t\t\tif (Math.abs(minutes) <= 90) {\n\t\t\t\treturn formatter.format(Math.round(minutes), 'minute')\n\t\t\t}\n\t\t\tconst hours = minutes / 60\n\t\t\tif (Math.abs(hours) <= 24) {\n\t\t\t\treturn formatter.format(Math.round(hours), 'hour')\n\t\t\t}\n\t\t\tconst days = hours / 24\n\t\t\tif (Math.abs(days) <= 6) {\n\t\t\t\treturn formatter.format(Math.round(days), 'day')\n\t\t\t}\n\t\t\tconst weeks = days / 7\n\t\t\tif (Math.abs(weeks) <= 4) {\n\t\t\t\treturn formatter.format(Math.round(weeks), 'week')\n\t\t\t}\n\t\t\tconst months = days / 30\n\t\t\tif (Math.abs(months) <= 12) {\n\t\t\t\treturn formatter.format(Math.round(months), 'month')\n\t\t\t}\n\t\t\treturn formatter.format(Math.round(days / 365), 'year')\n\t\t}\n\t\treturn formattedFullTime\n\t})\n\n\t// Set or clear interval if relative time is dis/enabled\n\twatch([wrappedOptions], (opts) => {\n\t\twindow.clearInterval(intervalId)\n\t\tintervalId = undefined\n\t\tif (opts.relativeTime) {\n\t\t\tintervalId = window.setInterval(() => { currentTime.value = new Date() }, 1000)\n\t\t}\n\t})\n\n\t// Start the interval for setting the current time if relative time is enabled\n\tonMounted(() => {\n\t\tif (wrappedOptions.value.relativeTime !== false) {\n\t\t\tintervalId = window.setInterval(() => { currentTime.value = new Date() }, 1000)\n\t\t}\n\t})\n\n\t// ensure interval is cleared\n\tonUnmounted(() => {\n\t\twindow.clearInterval(intervalId)\n\t})\n\n\treturn {\n\t\tformattedTime,\n\t\tformattedFullTime,\n\t\toptions,\n\t}\n}\n","<!--\n - @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @author Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n\n### General description\n\nThis components purpose is to display a timestamp in the users local time format.\nIt also supports relative time, for examples *6 seconds ago*.\n\n#### Standard usage\n\nWithout any optional parameters the timestamp is displayed as a relative datetime and a title with the full date is added.\n\n```vue\n<template>\n\t<NcDateTime :timestamp=\"timestamp\" />\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n#### Ignore seconds\n\nIf you do not want the seconds to be counted up until minutes are reached you can simply use the `ignore-seconds` property.\n\n```vue\n<template>\n\t<NcDateTime :timestamp=\"timestamp\" :ignore-seconds=\"true\" />\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n#### Custom date or time format\n\nThe component allows to format the full date for the title by settings the `format` property.\nIt is also possible to disable relative time by setting the `relativeTime` property to `false`.\n\n```vue\n<template>\n\t<div>\n\t\t<h4>Short relative time</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" relative-time=\"short\" />\n\n\t\t<h4>Custom title format</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" :format=\"timeFormat\" />\n\n\t\t<h4>Without relative time</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" :format=\"timeFormat\" :relative-time=\"false\" />\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t/** For allowed formats see the Intl.DateTimeFormat options */\n\t\t\t\ttimeFormat: {\n\t\t\t\t\tdateStyle: 'short',\n\t\t\t\t\ttimeStyle: 'full'\n\t\t\t\t},\n\t\t\t}\n\t\t},\n\t}\n</script>\n<style>\nh4 {\n\tfont-weight: bold;\n\tmargin-top: 12px;\n}\n</style>\n```\n</docs>\n\n<template>\n\t<span class=\"nc-datetime\"\n\t\t:data-timestamp=\"timestamp\"\n\t\t:title=\"formattedFullTime\">{{ formattedTime }}</span>\n</template>\n\n<script>\nimport { computed } from 'vue'\nimport { useFormatDateTime } from '../../composables/useFormatDateTime.js'\n\nexport default {\n\tname: 'NcDateTime',\n\n\tprops: {\n\t\t/**\n\t\t * The timestamp to display, either an unix timestamp (in milliseconds) or a Date object\n\t\t */\n\t\ttimestamp: {\n\t\t\ttype: [Date, Number],\n\t\t\trequired: true,\n\t\t},\n\t\t/**\n\t\t * The format used for displaying, or if relative time is used the format used for the title (optional)\n\t\t *\n\t\t * @type {Intl.DateTimeFormatOptions}\n\t\t */\n\t\tformat: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({ timeStyle: 'medium', dateStyle: 'short' }),\n\t\t},\n\t\t/**\n\t\t * Wether to display the timestamp as time from now (optional)\n\t\t *\n\t\t * - `false`: Disable relative time\n\t\t * - `'long'`: Long text, like *2 seconds ago* (default)\n\t\t * - `'short'`: Short text, like *2 sec. ago*\n\t\t * - `'narrow'`: Even shorter text (same as `'short'` on some languages)\n\t\t */\n\t\trelativeTime: {\n\t\t\ttype: [Boolean, String],\n\t\t\tdefault: 'long',\n\t\t\tvalidator: (v) => v === false || ['long', 'short', 'narrow'].includes(v),\n\t\t},\n\t\t/**\n\t\t * Ignore seconds when displaying the relative time and just show `a few seconds ago`\n\t\t */\n\t\tignoreSeconds: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tsetup(props) {\n\t\tconst timestamp = computed(() => props.timestamp)\n\t\tconst { formattedTime, formattedFullTime } = useFormatDateTime(timestamp, props)\n\t\treturn {\n\t\t\tformattedTime,\n\t\t\tformattedFullTime,\n\t\t}\n\t},\n}\n</script>\n"],"names":["FEW_SECONDS_AGO","t","useFormatDateTime","timestamp","opts","currentTime","ref","intervalId","options","unref","wrappedOptions","computed","date","formattedFullTime","getCanonicalLocale","formattedTime","formatter","seconds","minutes","hours","days","weeks","months","watch","onMounted","onUnmounted","_sfc_main","v","props"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const e = require("vue"), w = require("@nextcloud/l10n"), l = require("./_l10n-BG5lXDmm.cjs"), g = require("./_plugin-vue2_normalizer-GXKvuwrq.cjs");
2
+ const e = require("vue"), w = require("@nextcloud/l10n"), l = require("./_l10n-B8iumFKB.cjs"), g = require("./_plugin-vue2_normalizer-GXKvuwrq.cjs");
3
3
  l.register(l.t2);
4
4
  /**
5
5
  * @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de>
@@ -1 +1 @@
1
- {"version":3,"file":"NcDateTime-DG_XAvbT.cjs","sources":["../../src/composables/useFormatDateTime.js","../../src/components/NcDateTime/NcDateTime.vue"],"sourcesContent":["/**\n * @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @author Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { getCanonicalLocale } from '@nextcloud/l10n'\nimport { computed, onUnmounted, ref, onMounted, watch, unref } from 'vue'\nimport { t } from '../l10n.js'\n\nconst FEW_SECONDS_AGO = {\n\tlong: t('a few seconds ago'),\n\tshort: t('seconds ago'), // FOR TRANSLATORS: Shorter version of 'a few seconds ago'\n\tnarrow: t('sec. ago'), // FOR TRANSLATORS: If possible in your language an even shorter version of 'a few seconds ago'\n}\n\n/**\n * Composable for formatting time stamps using current users locale\n *\n * @param {Date | number | import('vue').Ref<Date> | import('vue').Ref<number>} timestamp Current timestamp\n * @param {object} opts Optional options\n * @param {Intl.DateTimeFormatOptions} opts.format The format used for displaying, or if relative time is used the format used for the title (optional)\n * @param {boolean} opts.ignoreSeconds Ignore seconds when displaying the relative time and just show `a few seconds ago`\n * @param {false | 'long' | 'short' | 'narrow'} opts.relativeTime Wether to display the timestamp as time from now (optional)\n */\nexport function useFormatDateTime(timestamp = Date.now(), opts = {}) {\n\t// Current time as Date.now is not reactive\n\tconst currentTime = ref(Date.now())\n\t// The interval ID for the window\n\tlet intervalId = null\n\n\tconst options = ref({\n\t\ttimeStyle: 'medium',\n\t\tdateStyle: 'short',\n\t\trelativeTime: 'long',\n\t\tignoreSeconds: false,\n\t\t...unref(opts),\n\t})\n\tconst wrappedOptions = computed(() => ({ ...unref(opts), ...options.value }))\n\n\t/** ECMA Date object of the timestamp */\n\tconst date = computed(() => new Date(unref(timestamp)))\n\n\tconst formattedFullTime = computed(() => {\n\t\tconst formatter = new Intl.DateTimeFormat(getCanonicalLocale(), wrappedOptions.value.format)\n\t\treturn formatter.format(date.value)\n\t})\n\n\t/** Time string formatted for main text */\n\tconst formattedTime = computed(() => {\n\t\tif (wrappedOptions.value.relativeTime !== false) {\n\t\t\tconst formatter = new Intl.RelativeTimeFormat(getCanonicalLocale(), { numeric: 'auto', style: wrappedOptions.value.relativeTime })\n\n\t\t\tconst diff = date.value - currentTime.value\n\t\t\tconst seconds = diff / 1000\n\t\t\tif (Math.abs(seconds) <= 90) {\n\t\t\t\tif (wrappedOptions.value.ignoreSeconds) {\n\t\t\t\t\treturn FEW_SECONDS_AGO[wrappedOptions.value.relativeTime]\n\t\t\t\t} else {\n\t\t\t\t\treturn formatter.format(Math.round(seconds), 'second')\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst minutes = seconds / 60\n\t\t\tif (Math.abs(minutes) <= 90) {\n\t\t\t\treturn formatter.format(Math.round(minutes), 'minute')\n\t\t\t}\n\t\t\tconst hours = minutes / 60\n\t\t\tif (Math.abs(hours) <= 24) {\n\t\t\t\treturn formatter.format(Math.round(hours), 'hour')\n\t\t\t}\n\t\t\tconst days = hours / 24\n\t\t\tif (Math.abs(days) <= 6) {\n\t\t\t\treturn formatter.format(Math.round(days), 'day')\n\t\t\t}\n\t\t\tconst weeks = days / 7\n\t\t\tif (Math.abs(weeks) <= 4) {\n\t\t\t\treturn formatter.format(Math.round(weeks), 'week')\n\t\t\t}\n\t\t\tconst months = days / 30\n\t\t\tif (Math.abs(months) <= 12) {\n\t\t\t\treturn formatter.format(Math.round(months), 'month')\n\t\t\t}\n\t\t\treturn formatter.format(Math.round(days / 365), 'year')\n\t\t}\n\t\treturn formattedFullTime\n\t})\n\n\t// Set or clear interval if relative time is dis/enabled\n\twatch([wrappedOptions], (opts) => {\n\t\twindow.clearInterval(intervalId)\n\t\tintervalId = undefined\n\t\tif (opts.relativeTime) {\n\t\t\tintervalId = window.setInterval(() => { currentTime.value = new Date() }, 1000)\n\t\t}\n\t})\n\n\t// Start the interval for setting the current time if relative time is enabled\n\tonMounted(() => {\n\t\tif (wrappedOptions.value.relativeTime !== false) {\n\t\t\tintervalId = window.setInterval(() => { currentTime.value = new Date() }, 1000)\n\t\t}\n\t})\n\n\t// ensure interval is cleared\n\tonUnmounted(() => {\n\t\twindow.clearInterval(intervalId)\n\t})\n\n\treturn {\n\t\tformattedTime,\n\t\tformattedFullTime,\n\t\toptions,\n\t}\n}\n","<!--\n - @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @author Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n\n### General description\n\nThis components purpose is to display a timestamp in the users local time format.\nIt also supports relative time, for examples *6 seconds ago*.\n\n#### Standard usage\n\nWithout any optional parameters the timestamp is displayed as a relative datetime and a title with the full date is added.\n\n```vue\n<template>\n\t<NcDateTime :timestamp=\"timestamp\" />\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n#### Ignore seconds\n\nIf you do not want the seconds to be counted up until minutes are reached you can simply use the `ignore-seconds` property.\n\n```vue\n<template>\n\t<NcDateTime :timestamp=\"timestamp\" :ignore-seconds=\"true\" />\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n#### Custom date or time format\n\nThe component allows to format the full date for the title by settings the `format` property.\nIt is also possible to disable relative time by setting the `relativeTime` property to `false`.\n\n```vue\n<template>\n\t<div>\n\t\t<h4>Short relative time</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" relative-time=\"short\" />\n\n\t\t<h4>Custom title format</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" :format=\"timeFormat\" />\n\n\t\t<h4>Without relative time</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" :format=\"timeFormat\" :relative-time=\"false\" />\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t/** For allowed formats see the Intl.DateTimeFormat options */\n\t\t\t\ttimeFormat: {\n\t\t\t\t\tdateStyle: 'short',\n\t\t\t\t\ttimeStyle: 'full'\n\t\t\t\t},\n\t\t\t}\n\t\t},\n\t}\n</script>\n<style>\nh4 {\n\tfont-weight: bold;\n\tmargin-top: 12px;\n}\n</style>\n```\n</docs>\n\n<template>\n\t<span class=\"nc-datetime\"\n\t\t:data-timestamp=\"timestamp\"\n\t\t:title=\"formattedFullTime\">{{ formattedTime }}</span>\n</template>\n\n<script>\nimport { computed } from 'vue'\nimport { useFormatDateTime } from '../../composables/useFormatDateTime.js'\n\nexport default {\n\tname: 'NcDateTime',\n\n\tprops: {\n\t\t/**\n\t\t * The timestamp to display, either an unix timestamp (in milliseconds) or a Date object\n\t\t */\n\t\ttimestamp: {\n\t\t\ttype: [Date, Number],\n\t\t\trequired: true,\n\t\t},\n\t\t/**\n\t\t * The format used for displaying, or if relative time is used the format used for the title (optional)\n\t\t *\n\t\t * @type {Intl.DateTimeFormatOptions}\n\t\t */\n\t\tformat: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({ timeStyle: 'medium', dateStyle: 'short' }),\n\t\t},\n\t\t/**\n\t\t * Wether to display the timestamp as time from now (optional)\n\t\t *\n\t\t * - `false`: Disable relative time\n\t\t * - `'long'`: Long text, like *2 seconds ago* (default)\n\t\t * - `'short'`: Short text, like *2 sec. ago*\n\t\t * - `'narrow'`: Even shorter text (same as `'short'` on some languages)\n\t\t */\n\t\trelativeTime: {\n\t\t\ttype: [Boolean, String],\n\t\t\tdefault: 'long',\n\t\t\tvalidator: (v) => v === false || ['long', 'short', 'narrow'].includes(v),\n\t\t},\n\t\t/**\n\t\t * Ignore seconds when displaying the relative time and just show `a few seconds ago`\n\t\t */\n\t\tignoreSeconds: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tsetup(props) {\n\t\tconst timestamp = computed(() => props.timestamp)\n\t\tconst { formattedTime, formattedFullTime } = useFormatDateTime(timestamp, props)\n\t\treturn {\n\t\t\tformattedTime,\n\t\t\tformattedFullTime,\n\t\t}\n\t},\n}\n</script>\n"],"names":["FEW_SECONDS_AGO","t","useFormatDateTime","timestamp","opts","currentTime","ref","intervalId","options","unref","wrappedOptions","computed","date","formattedFullTime","getCanonicalLocale","formattedTime","formatter","seconds","minutes","hours","days","weeks","months","watch","onMounted","onUnmounted","_sfc_main","v","props"],"mappings":";;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BA,MAAMA,IAAkB;AAAA,EACvB,MAAMC,EAAC,EAAC,mBAAmB;AAAA,EAC3B,OAAOA,EAAC,EAAC,aAAa;AAAA;AAAA,EACtB,QAAQA,EAAC,EAAC,UAAU;AAAA;AACrB;AAWO,SAASC,EAAkBC,IAAY,KAAK,IAAG,GAAIC,IAAO,CAAA,GAAI;AAEpE,QAAMC,IAAcC,EAAAA,IAAI,KAAK,IAAG,CAAE;AAElC,MAAIC,IAAa;AAEjB,QAAMC,IAAUF,EAAAA,IAAI;AAAA,IACnB,WAAW;AAAA,IACX,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf,GAAGG,EAAAA,MAAML,CAAI;AAAA,EACf,CAAE,GACKM,IAAiBC,WAAS,OAAO,EAAE,GAAGF,EAAAA,MAAML,CAAI,GAAG,GAAGI,EAAQ,MAAK,EAAG,GAGtEI,IAAOD,EAAAA,SAAS,MAAM,IAAI,KAAKF,EAAK,MAACN,CAAS,CAAC,CAAC,GAEhDU,IAAoBF,EAAAA,SAAS,MAChB,IAAI,KAAK,eAAeG,EAAkB,mBAAA,GAAIJ,EAAe,MAAM,MAAM,EAC1E,OAAOE,EAAK,KAAK,CAClC,GAGKG,IAAgBJ,EAAAA,SAAS,MAAM;AACpC,QAAID,EAAe,MAAM,iBAAiB,IAAO;AAChD,YAAMM,IAAY,IAAI,KAAK,mBAAmBF,EAAkB,mBAAA,GAAI,EAAE,SAAS,QAAQ,OAAOJ,EAAe,MAAM,aAAY,CAAE,GAG3HO,KADOL,EAAK,QAAQP,EAAY,SACf;AACvB,UAAI,KAAK,IAAIY,CAAO,KAAK;AACxB,eAAIP,EAAe,MAAM,gBACjBV,EAAgBU,EAAe,MAAM,YAAY,IAEjDM,EAAU,OAAO,KAAK,MAAMC,CAAO,GAAG,QAAQ;AAGvD,YAAMC,IAAUD,IAAU;AAC1B,UAAI,KAAK,IAAIC,CAAO,KAAK;AACxB,eAAOF,EAAU,OAAO,KAAK,MAAME,CAAO,GAAG,QAAQ;AAEtD,YAAMC,IAAQD,IAAU;AACxB,UAAI,KAAK,IAAIC,CAAK,KAAK;AACtB,eAAOH,EAAU,OAAO,KAAK,MAAMG,CAAK,GAAG,MAAM;AAElD,YAAMC,IAAOD,IAAQ;AACrB,UAAI,KAAK,IAAIC,CAAI,KAAK;AACrB,eAAOJ,EAAU,OAAO,KAAK,MAAMI,CAAI,GAAG,KAAK;AAEhD,YAAMC,IAAQD,IAAO;AACrB,UAAI,KAAK,IAAIC,CAAK,KAAK;AACtB,eAAOL,EAAU,OAAO,KAAK,MAAMK,CAAK,GAAG,MAAM;AAElD,YAAMC,IAASF,IAAO;AACtB,aAAI,KAAK,IAAIE,CAAM,KAAK,KAChBN,EAAU,OAAO,KAAK,MAAMM,CAAM,GAAG,OAAO,IAE7CN,EAAU,OAAO,KAAK,MAAMI,IAAO,GAAG,GAAG,MAAM;AAAA,IACtD;AACD,WAAOP;AAAA,EACT,CAAE;AAGDU,SAAAA,EAAAA,MAAM,CAACb,CAAc,GAAG,CAACN,MAAS;AACjC,WAAO,cAAcG,CAAU,GAC/BA,IAAa,QACTH,EAAK,iBACRG,IAAa,OAAO,YAAY,MAAM;AAAE,MAAAF,EAAY,QAAQ,oBAAI;IAAQ,GAAE,GAAI;AAAA,EAEjF,CAAE,GAGDmB,EAAAA,UAAU,MAAM;AACf,IAAId,EAAe,MAAM,iBAAiB,OACzCH,IAAa,OAAO,YAAY,MAAM;AAAE,MAAAF,EAAY,QAAQ,oBAAI;IAAQ,GAAE,GAAI;AAAA,EAEjF,CAAE,GAGDoB,EAAAA,YAAY,MAAM;AACjB,WAAO,cAAclB,CAAU;AAAA,EACjC,CAAE,GAEM;AAAA,IACN,eAAAQ;AAAA,IACA,mBAAAF;AAAA,IACA,SAAAL;AAAA,EACA;AACF;ACXA,MAAAkB,IAAA;AAAA,EACA,MAAA;AAAA,EAEA,OAAA;AAAA;AAAA;AAAA;AAAA,IAIA,WAAA;AAAA,MACA,MAAA,CAAA,MAAA,MAAA;AAAA,MACA,UAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,QAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA,OAAA,EAAA,WAAA,UAAA,WAAA,QAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,cAAA;AAAA,MACA,MAAA,CAAA,SAAA,MAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAA,CAAAC,MAAAA,MAAA,MAAA,CAAA,QAAA,SAAA,QAAA,EAAA,SAAAA,CAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,eAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,MAAAC,GAAA;AACA,UAAAzB,IAAAQ,EAAAA,SAAA,MAAAiB,EAAA,SAAA,GACA,EAAA,eAAAb,GAAA,mBAAAF,EAAA,IAAAX,EAAAC,GAAAyB,CAAA;AACA,WAAA;AAAA,MACA,eAAAb;AAAA,MACA,mBAAAF;AAAA,IACA;AAAA,EACA;AACA;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NcDateTime-DneyKibb.cjs","sources":["../../src/composables/useFormatDateTime.js","../../src/components/NcDateTime/NcDateTime.vue"],"sourcesContent":["/**\n * @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @author Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { getCanonicalLocale } from '@nextcloud/l10n'\nimport { computed, onUnmounted, ref, onMounted, watch, unref } from 'vue'\nimport { t } from '../l10n.js'\n\nconst FEW_SECONDS_AGO = {\n\tlong: t('a few seconds ago'),\n\tshort: t('seconds ago'), // FOR TRANSLATORS: Shorter version of 'a few seconds ago'\n\tnarrow: t('sec. ago'), // FOR TRANSLATORS: If possible in your language an even shorter version of 'a few seconds ago'\n}\n\n/**\n * Composable for formatting time stamps using current users locale\n *\n * @param {Date | number | import('vue').Ref<Date> | import('vue').Ref<number>} timestamp Current timestamp\n * @param {object} opts Optional options\n * @param {Intl.DateTimeFormatOptions} opts.format The format used for displaying, or if relative time is used the format used for the title (optional)\n * @param {boolean} opts.ignoreSeconds Ignore seconds when displaying the relative time and just show `a few seconds ago`\n * @param {false | 'long' | 'short' | 'narrow'} opts.relativeTime Wether to display the timestamp as time from now (optional)\n */\nexport function useFormatDateTime(timestamp = Date.now(), opts = {}) {\n\t// Current time as Date.now is not reactive\n\tconst currentTime = ref(Date.now())\n\t// The interval ID for the window\n\tlet intervalId = null\n\n\tconst options = ref({\n\t\ttimeStyle: 'medium',\n\t\tdateStyle: 'short',\n\t\trelativeTime: 'long',\n\t\tignoreSeconds: false,\n\t\t...unref(opts),\n\t})\n\tconst wrappedOptions = computed(() => ({ ...unref(opts), ...options.value }))\n\n\t/** ECMA Date object of the timestamp */\n\tconst date = computed(() => new Date(unref(timestamp)))\n\n\tconst formattedFullTime = computed(() => {\n\t\tconst formatter = new Intl.DateTimeFormat(getCanonicalLocale(), wrappedOptions.value.format)\n\t\treturn formatter.format(date.value)\n\t})\n\n\t/** Time string formatted for main text */\n\tconst formattedTime = computed(() => {\n\t\tif (wrappedOptions.value.relativeTime !== false) {\n\t\t\tconst formatter = new Intl.RelativeTimeFormat(getCanonicalLocale(), { numeric: 'auto', style: wrappedOptions.value.relativeTime })\n\n\t\t\tconst diff = date.value - currentTime.value\n\t\t\tconst seconds = diff / 1000\n\t\t\tif (Math.abs(seconds) <= 90) {\n\t\t\t\tif (wrappedOptions.value.ignoreSeconds) {\n\t\t\t\t\treturn FEW_SECONDS_AGO[wrappedOptions.value.relativeTime]\n\t\t\t\t} else {\n\t\t\t\t\treturn formatter.format(Math.round(seconds), 'second')\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst minutes = seconds / 60\n\t\t\tif (Math.abs(minutes) <= 90) {\n\t\t\t\treturn formatter.format(Math.round(minutes), 'minute')\n\t\t\t}\n\t\t\tconst hours = minutes / 60\n\t\t\tif (Math.abs(hours) <= 24) {\n\t\t\t\treturn formatter.format(Math.round(hours), 'hour')\n\t\t\t}\n\t\t\tconst days = hours / 24\n\t\t\tif (Math.abs(days) <= 6) {\n\t\t\t\treturn formatter.format(Math.round(days), 'day')\n\t\t\t}\n\t\t\tconst weeks = days / 7\n\t\t\tif (Math.abs(weeks) <= 4) {\n\t\t\t\treturn formatter.format(Math.round(weeks), 'week')\n\t\t\t}\n\t\t\tconst months = days / 30\n\t\t\tif (Math.abs(months) <= 12) {\n\t\t\t\treturn formatter.format(Math.round(months), 'month')\n\t\t\t}\n\t\t\treturn formatter.format(Math.round(days / 365), 'year')\n\t\t}\n\t\treturn formattedFullTime\n\t})\n\n\t// Set or clear interval if relative time is dis/enabled\n\twatch([wrappedOptions], (opts) => {\n\t\twindow.clearInterval(intervalId)\n\t\tintervalId = undefined\n\t\tif (opts.relativeTime) {\n\t\t\tintervalId = window.setInterval(() => { currentTime.value = new Date() }, 1000)\n\t\t}\n\t})\n\n\t// Start the interval for setting the current time if relative time is enabled\n\tonMounted(() => {\n\t\tif (wrappedOptions.value.relativeTime !== false) {\n\t\t\tintervalId = window.setInterval(() => { currentTime.value = new Date() }, 1000)\n\t\t}\n\t})\n\n\t// ensure interval is cleared\n\tonUnmounted(() => {\n\t\twindow.clearInterval(intervalId)\n\t})\n\n\treturn {\n\t\tformattedTime,\n\t\tformattedFullTime,\n\t\toptions,\n\t}\n}\n","<!--\n - @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @author Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n\n### General description\n\nThis components purpose is to display a timestamp in the users local time format.\nIt also supports relative time, for examples *6 seconds ago*.\n\n#### Standard usage\n\nWithout any optional parameters the timestamp is displayed as a relative datetime and a title with the full date is added.\n\n```vue\n<template>\n\t<NcDateTime :timestamp=\"timestamp\" />\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n#### Ignore seconds\n\nIf you do not want the seconds to be counted up until minutes are reached you can simply use the `ignore-seconds` property.\n\n```vue\n<template>\n\t<NcDateTime :timestamp=\"timestamp\" :ignore-seconds=\"true\" />\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n#### Custom date or time format\n\nThe component allows to format the full date for the title by settings the `format` property.\nIt is also possible to disable relative time by setting the `relativeTime` property to `false`.\n\n```vue\n<template>\n\t<div>\n\t\t<h4>Short relative time</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" relative-time=\"short\" />\n\n\t\t<h4>Custom title format</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" :format=\"timeFormat\" />\n\n\t\t<h4>Without relative time</h4>\n\t\t<NcDateTime :timestamp=\"timestamp\" :format=\"timeFormat\" :relative-time=\"false\" />\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t/** For allowed formats see the Intl.DateTimeFormat options */\n\t\t\t\ttimeFormat: {\n\t\t\t\t\tdateStyle: 'short',\n\t\t\t\t\ttimeStyle: 'full'\n\t\t\t\t},\n\t\t\t}\n\t\t},\n\t}\n</script>\n<style>\nh4 {\n\tfont-weight: bold;\n\tmargin-top: 12px;\n}\n</style>\n```\n</docs>\n\n<template>\n\t<span class=\"nc-datetime\"\n\t\t:data-timestamp=\"timestamp\"\n\t\t:title=\"formattedFullTime\">{{ formattedTime }}</span>\n</template>\n\n<script>\nimport { computed } from 'vue'\nimport { useFormatDateTime } from '../../composables/useFormatDateTime.js'\n\nexport default {\n\tname: 'NcDateTime',\n\n\tprops: {\n\t\t/**\n\t\t * The timestamp to display, either an unix timestamp (in milliseconds) or a Date object\n\t\t */\n\t\ttimestamp: {\n\t\t\ttype: [Date, Number],\n\t\t\trequired: true,\n\t\t},\n\t\t/**\n\t\t * The format used for displaying, or if relative time is used the format used for the title (optional)\n\t\t *\n\t\t * @type {Intl.DateTimeFormatOptions}\n\t\t */\n\t\tformat: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({ timeStyle: 'medium', dateStyle: 'short' }),\n\t\t},\n\t\t/**\n\t\t * Wether to display the timestamp as time from now (optional)\n\t\t *\n\t\t * - `false`: Disable relative time\n\t\t * - `'long'`: Long text, like *2 seconds ago* (default)\n\t\t * - `'short'`: Short text, like *2 sec. ago*\n\t\t * - `'narrow'`: Even shorter text (same as `'short'` on some languages)\n\t\t */\n\t\trelativeTime: {\n\t\t\ttype: [Boolean, String],\n\t\t\tdefault: 'long',\n\t\t\tvalidator: (v) => v === false || ['long', 'short', 'narrow'].includes(v),\n\t\t},\n\t\t/**\n\t\t * Ignore seconds when displaying the relative time and just show `a few seconds ago`\n\t\t */\n\t\tignoreSeconds: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tsetup(props) {\n\t\tconst timestamp = computed(() => props.timestamp)\n\t\tconst { formattedTime, formattedFullTime } = useFormatDateTime(timestamp, props)\n\t\treturn {\n\t\t\tformattedTime,\n\t\t\tformattedFullTime,\n\t\t}\n\t},\n}\n</script>\n"],"names":["FEW_SECONDS_AGO","t","useFormatDateTime","timestamp","opts","currentTime","ref","intervalId","options","unref","wrappedOptions","computed","date","formattedFullTime","getCanonicalLocale","formattedTime","formatter","seconds","minutes","hours","days","weeks","months","watch","onMounted","onUnmounted","_sfc_main","v","props"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import '../assets/NcDialog-M36tj7nk.css';
1
+ import '../assets/NcDialog-DEKSpcnR.css';
2
2
  import { useElementSize as m } from "@vueuse/core";
3
3
  import { defineComponent as y, ref as s, computed as n } from "vue";
4
4
  import C from "../Components/NcModal.mjs";
@@ -204,7 +204,7 @@ var w = function() {
204
204
  L,
205
205
  !1,
206
206
  null,
207
- "40a87f52",
207
+ "b0b5e355",
208
208
  null,
209
209
  null
210
210
  );
@@ -1 +1 @@
1
- {"version":3,"file":"NcDialog-D6YSjidf.mjs","sources":["../../src/components/NcDialog/NcDialog.vue"],"sourcesContent":["<!--\n - @copyright Copyright (c) 2023 Ferdinand Thiessen\n -\n - @author Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n### General description\n\nThis component uses the `NcModal` under the hood for allowing users to create generic dialogs.\n\n### Basic example\n```vue\n<template>\n\t<div>\n\t\t<NcButton @click=\"showDialog = true\">Show dialog</NcButton>\n\t\t<NcDialog :open.sync=\"showDialog\" name=\"Confirmation\" message=\"Are you sure to proceed?\" :buttons=\"buttons\" />\n\t\t<p>Last response: {{ lastResponse }}</p>\n\t</div>\n</template>\n<script>\nimport IconCancel from '@mdi/svg/svg/cancel.svg?raw'\nimport IconCheck from '@mdi/svg/svg/check.svg?raw'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tshowDialog: false,\n\t\t\tlastResponse: 'None',\n\t\t\tbuttons: [\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Cancel',\n\t\t\t\t\ticon: IconCancel,\n\t\t\t\t\tcallback: () => { this.lastResponse = 'Pressed \"Cancel\"' },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Ok',\n\t\t\t\t\ttype: 'primary',\n\t\t\t\t\ticon: IconCheck,\n\t\t\t\t\tcallback: () => { this.lastResponse = 'Pressed \"Ok\"' },\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t},\n}\n</script>\n```\n\n### Use custom actions and content\nInstead of using the buttons property, you can also inject your custom actions using a named slot.\nYou can also use the default slot to inject custom content.\n\n```vue\n<template>\n\t<div style=\"display: flex; gap: 12px;\">\n\t\t<NcButton @click=\"showDialog = true\">Show dialog</NcButton>\n\t\t<NcButton @click=\"showLongDialog = true\">Show long dialog</NcButton>\n\t\t<NcDialog v-if=\"showDialog\" name=\"Warning\" :can-close=\"false\">\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"showDialog = false\">Ok</NcButton>\n\t\t\t</template>\n\t\t\t<div style=\"color: red; font-weight: bold;\">This is serious</div>\n\t\t</NcDialog>\n\t\t<NcDialog :open.sync=\"showLongDialog\" name=\"Lorem Ipsum\">\n\t\t\t<p v-for=\"i in new Array(63)\" :key=\"i\">Lorem ipsum dolor sit amet.</p>\n\t\t</NcDialog>\n\t</div>\n</template>\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tshowDialog: false,\n\t\t\tshowLongDialog: false,\n\t\t}\n\t},\n}\n</script>\n```\n</docs>\n\n<template>\n\t<NcModal v-if=\"open\"\n\t\tclass=\"dialog__modal\"\n\t\t:enable-slideshow=\"false\"\n\t\t:enable-swipe=\"false\"\n\t\tv-bind=\"modalProps\"\n\t\t@close=\"handleClosed\"\n\t\t@update:show=\"handleClosing\">\n\t\t<!-- The dialog name / header -->\n\t\t<h2 :id=\"navigationId\" class=\"dialog__name\" v-text=\"name\" />\n\t\t<div class=\"dialog\" :class=\"dialogClasses\">\n\t\t\t<div ref=\"wrapper\" :class=\"['dialog__wrapper', { 'dialog__wrapper--collapsed': isNavigationCollapsed }]\">\n\t\t\t\t<!-- When the navigation is collapsed (too small dialog) it is displayed above the main content, otherwise on the inline start -->\n\t\t\t\t<nav v-if=\"hasNavigation\"\n\t\t\t\t\tclass=\"dialog__navigation\"\n\t\t\t\t\t:class=\"navigationClasses\"\n\t\t\t\t\t:aria-label=\"navigationAriaLabelAttr\"\n\t\t\t\t\t:aria-labelledby=\"navigationAriaLabelledbyAttr\">\n\t\t\t\t\t<slot name=\"navigation\" :is-collapsed=\"isNavigationCollapsed\" />\n\t\t\t\t</nav>\n\t\t\t\t<!-- Main dialog content -->\n\t\t\t\t<div class=\"dialog__content\" :class=\"contentClasses\">\n\t\t\t\t\t<slot>\n\t\t\t\t\t\t<p class=\"dialog__text\">\n\t\t\t\t\t\t\t{{ message }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</slot>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- The dialog actions aka the buttons -->\n\t\t\t<div class=\"dialog__actions\">\n\t\t\t\t<slot name=\"actions\">\n\t\t\t\t\t<NcDialogButton v-for=\"(button, idx) in buttons\"\n\t\t\t\t\t\t:key=\"idx\"\n\t\t\t\t\t\tv-bind=\"button\"\n\t\t\t\t\t\t@click=\"handleButtonClose\" />\n\t\t\t\t</slot>\n\t\t\t</div>\n\t\t</div>\n\t</NcModal>\n</template>\n\n<script>\nimport { useElementSize } from '@vueuse/core'\nimport { computed, defineComponent, ref } from 'vue'\n\nimport NcModal from '../NcModal/index.js'\nimport NcDialogButton from '../NcDialogButton/index.js'\n\nimport GenRandomId from '../../utils/GenRandomId.js'\n\nexport default defineComponent({\n\tname: 'NcDialog',\n\n\tcomponents: {\n\t\tNcDialogButton,\n\t\tNcModal,\n\t},\n\n\tprops: {\n\t\t/** Name of the dialog (the heading) */\n\t\tname: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** Text of the dialog */\n\t\tmessage: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Additional elements to add to the focus trap */\n\t\tadditionalTrapElements: {\n\t\t\ttype: Array,\n\t\t\tvalidator: (arr) => {\n\t\t\t\treturn (\n\t\t\t\t\tArray.isArray(arr) && arr.every(\n\t\t\t\t\t\t(element) =>\n\t\t\t\t\t\t\ttypeof element === 'string' || element instanceof HTMLElement,\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t},\n\t\t\tdefault: () => ([]),\n\t\t},\n\n\t\t/**\n\t\t * The element where to mount the dialog, if `null` is passed the dialog is mounted in place\n\t\t * @default 'body'\n\t\t */\n\t\tcontainer: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: 'body',\n\t\t},\n\n\t\t/**\n\t\t * Whether the dialog should be shown\n\t\t * @default true\n\t\t */\n\t\topen: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Size of the underlying NcModal\n\t\t * @default 'small'\n\t\t * @type {'small'|'normal'|'large'|'full'}\n\t\t */\n\t\tsize: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: 'small',\n\t\t\tvalidator: (value) => typeof value === 'string' && ['small', 'normal', 'large', 'full'].includes(value),\n\t\t},\n\n\t\t/**\n\t\t * Buttons to display\n\t\t * @default []\n\t\t */\n\t\tbuttons: {\n\t\t\ttype: Array,\n\t\t\trequired: false,\n\t\t\tdefault: () => ([]),\n\t\t\tvalidator: (value) => Array.isArray(value) && value.every((element) => typeof element === 'object'),\n\t\t},\n\n\t\t/**\n\t\t * Set to false to no show a close button on the dialog\n\t\t * @default true\n\t\t */\n\t\tcanClose: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Close the dialog if the user clicked outside of the dialog\n\t\t * Only relevant if `canClose` is set to true.\n\t\t */\n\t\tcloseOnClickOutside: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Declare if hiding the modal should be animated\n\t\t * @default false\n\t\t */\n\t\toutTransition: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the navigation for custom styling\n\t\t * @default ''\n\t\t * @example\n\t\t * ```html\n\t\t * <DialogBase :navigation-classes=\"['mydialog-navigation']\"><!-- --></DialogBase>\n\t\t * <!-- ... -->\n\t\t * <style lang=\"scss\">\n\t\t * :deep(.mydialog-navigation) {\n\t\t * flex-direction: row-reverse;\n\t\t * }\n\t\t * </style>\n\t\t * ```\n\t\t */\n\t\tnavigationClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * aria-label for the dialog navigation.\n\t\t * Use it when you want to provide a more meaningful label than the dialog name.\n\t\t *\n\t\t * By default, navigation is labeled by the dialog name.\n\t\t */\n\t\tnavigationAriaLabel: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * aria-labelledby for the dialog navigation.\n\t\t * Use it when you have an implicit navigation label (e.g. a heading).\n\t\t *\n\t\t * By default, navigation is labeled by the dialog name.\n\t\t */\n\t\tnavigationAriaLabelledby: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the content wrapper for custom styling\n\t\t * @default ''\n\t\t */\n\t\tcontentClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the dialog itself\n\t\t * (the default `class` attribute will be set on the modal wrapper)\n\t\t * @default ''\n\t\t */\n\t\tdialogClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['closing', 'update:open'],\n\n\tsetup(props, { emit, slots }) {\n\t\t/**\n\t\t * The dialog wrapper element\n\t\t * @type {import('vue').Ref<HTMLDivElement>}\n\t\t */\n\t\tconst wrapper = ref()\n\n\t\t/**\n\t\t * We use the dialog width to decide if we collapse the navigation (flex direction row)\n\t\t */\n\t\tconst { width: dialogWidth } = useElementSize(wrapper, { width: 900 })\n\n\t\t/**\n\t\t * Whether the navigation is collapsed due to dialog and window size\n\t\t * (collapses when modal is below: 900px modal width - 2x 12px margin)\n\t\t */\n\t\tconst isNavigationCollapsed = computed(() => dialogWidth.value < 876)\n\n\t\t/**\n\t\t * Whether a navigation was passed and the element should be displayed\n\t\t */\n\t\tconst hasNavigation = computed(() => slots?.navigation !== undefined)\n\n\t\t/**\n\t\t * The unique id of the nav element\n\t\t */\n\t\tconst navigationId = ref(GenRandomId())\n\n\t\t/**\n\t\t * aria-label attribute for the nav element\n\t\t */\n\t\tconst navigationAriaLabelAttr = computed(() => props.navigationAriaLabel || undefined)\n\n\t\t/**\n\t\t * aria-labelledby attribute for the nav element\n\t\t */\n\t\tconst navigationAriaLabelledbyAttr = computed(() => {\n\t\t\tif (props.navigationAriaLabel) {\n\t\t\t\t// Not needed, already labelled by aria-label\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\t// Use dialog name as a fallback label for navigation\n\t\t\treturn props.navigationAriaLabelledby || navigationId.value\n\t\t})\n\n\t\t/**\n\t\t * If the underlaying modal is shown\n\t\t */\n\t\tconst showModal = ref(true)\n\n\t\t// Because NcModal does not emit `close` when show prop is changed\n\t\t/**\n\t\t * Handle clicking a dialog button -> should close\n\t\t */\n\t\tconst handleButtonClose = () => {\n\t\t\thandleClosing()\n\t\t\twindow.setTimeout(() => handleClosed(), 300)\n\t\t}\n\n\t\t/**\n\t\t * Handle closing the dialog, optional out transition did not run yet\n\t\t */\n\t\tconst handleClosing = () => {\n\t\t\tshowModal.value = false\n\t\t\t/**\n\t\t\t * Emitted when the dialog is closing, so the out transition did not finish yet\n\t\t\t */\n\t\t\temit('closing')\n\t\t}\n\n\t\t/**\n\t\t * Handle dialog closed (out transition finished)\n\t\t */\n\t\tconst handleClosed = () => {\n\t\t\tshowModal.value = true\n\t\t\t/**\n\t\t\t * Emitted then the dialog is fully closed and the out transition run\n\t\t\t */\n\t\t\temit('update:open', false)\n\t\t}\n\n\t\t/**\n\t\t * Properties to pass to the underlying NcModal\n\t\t */\n\t\tconst modalProps = computed(() => ({\n\t\t\tcanClose: props.canClose,\n\t\t\tcontainer: props.container === undefined ? 'body' : props.container,\n\t\t\t// we do not pass the name as we already have the name as the headline\n\t\t\t// name: props.name,\n\t\t\tsize: props.size,\n\t\t\tshow: props.open && showModal.value,\n\t\t\toutTransition: props.outTransition,\n\t\t\tcloseOnClickOutside: props.closeOnClickOutside,\n\t\t\tadditionalTrapElements: props.additionalTrapElements,\n\t\t}))\n\n\t\treturn {\n\t\t\thandleButtonClose,\n\t\t\thandleClosing,\n\t\t\thandleClosed,\n\t\t\thasNavigation,\n\t\t\tnavigationId,\n\t\t\tnavigationAriaLabelAttr,\n\t\t\tnavigationAriaLabelledbyAttr,\n\t\t\tisNavigationCollapsed,\n\t\t\tmodalProps,\n\t\t\twrapper,\n\t\t}\n\t},\n})\n</script>\n\n<style lang=\"scss\">\n/** When having the small dialog style we override the modal styling so dialogs look more dialog like */\n@media only screen and (max-width: $breakpoint-small-mobile) {\n\t.dialog__modal .modal-wrapper--small .modal-container {\n\t\twidth: fit-content;\n\t\theight: unset;\n\t\tmax-height: 90%;\n\t\tposition: relative;\n\t\ttop: unset;\n\t\tborder-radius: var(--border-radius-large);\n\t}\n}\n</style>\n\n<style lang=\"scss\" scoped>\n.dialog {\n\theight: 100%;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: space-between;\n\toverflow: hidden;\n\n\t&__modal {\n\t\t:deep(.modal-wrapper .modal-container) {\n\t\t\tdisplay: flex !important;\n\t\t\tpadding-block: 4px 0; // 4px to align with close button, 0 block-end to make overflowing content on scroll look nice\n\t\t\tpadding-inline: 12px 0; // Same as with padding-block, we need the actions to have a margin of 4px for the button outline\n\t\t}\n\t\t:deep(.modal-wrapper .modal-container__content) {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\toverflow: hidden; // Only overflow on the .dialog__content\n\t\t}\n\t}\n\n\t&__wrapper {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\t// Auto scale to fit\n\t\tflex: 1;\n\t\tmin-height: 0;\n\t\toverflow: hidden;\n\n\t\t&--collapsed {\n\t\t\tflex-direction: column;\n\t\t}\n\t}\n\n\t&__navigation {\n\t\tdisplay: flex;\n\t\tflex-shrink: 0;\n\t}\n\n\t// Navigation styling when side-by-side with content\n\t&__wrapper:not(&__wrapper--collapsed) &__navigation {\n\t\tflex-direction: column;\n\n\t\toverflow: hidden auto;\n\t\theight: 100%;\n\t\tmin-width: 200px;\n\t\tmargin-inline-end: 20px;\n\t}\n\n\t// Navigation styling when on top of content\n\t&__wrapper#{&}__wrapper--collapsed &__navigation {\n\t\tflex-direction: row;\n\t\tjustify-content: space-between;\n\n\t\toverflow: auto hidden;\n\t\twidth: 100%;\n\t\tmin-width: 100%;\n\t}\n\n\t&__name {\n\t\ttext-align: center;\n\t\theight: fit-content;\n\t\tmin-height: var(--default-clickable-area);\n\t\tline-height: var(--default-clickable-area);\n\t\toverflow-wrap: break-word;\n\t\tmargin-block-end: 12px;\n\t}\n\n\t&__content {\n\t\t// Auto fit\n\t\tflex: 1;\n\t\tmin-height: 0;\n\t\toverflow: auto;\n\t\t// see .dialog__modal, we can not set the padding there to prevent floating scroll bars\n\t\tpadding-inline-end: 12px;\n\t}\n\n\t// In case only text content is show\n\t&__text {\n\t\t// Also add padding to the bottom to make it more readable\n\t\tpadding-block-end: 6px;\n\t}\n\n\t&__actions {\n\t\tdisplay: flex;\n\t\tgap: 6px;\n\t\talign-content: center;\n\t\twidth: fit-content;\n\t\tmargin-inline: auto 12px; // 12px to align with the overall modal padding\n\t\tmargin-block: 0;\n\n\t\t&:not(:empty) {\n\t\t\tmargin-block: 6px 12px; // only if there are actions, we add margin so if it is empty scroll content looks nice\n\t\t}\n\t}\n}\n\n@media only screen and (max-width: $breakpoint-small-mobile) {\n\t// Ensure the dialog name does not interfere with the close button\n\t.dialog__name {\n\t\ttext-align: start;\n\t\tmargin-inline-end: var(--default-clickable-area);\n\t}\n}\n</style>\n"],"names":["_sfc_main","defineComponent","NcDialogButton","NcModal","arr","element","value","props","emit","slots","wrapper","ref","dialogWidth","useElementSize","isNavigationCollapsed","computed","hasNavigation","navigationId","GenRandomId","navigationAriaLabelAttr","navigationAriaLabelledbyAttr","showModal","handleButtonClose","handleClosing","handleClosed","modalProps"],"mappings":"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"}
1
+ {"version":3,"file":"NcDialog-C_1rhUHk.mjs","sources":["../../src/components/NcDialog/NcDialog.vue"],"sourcesContent":["<!--\n - @copyright Copyright (c) 2023 Ferdinand Thiessen\n -\n - @author Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n### General description\n\nThis component uses the `NcModal` under the hood for allowing users to create generic dialogs.\n\n### Basic example\n```vue\n<template>\n\t<div>\n\t\t<NcButton @click=\"showDialog = true\">Show dialog</NcButton>\n\t\t<NcDialog :open.sync=\"showDialog\" name=\"Confirmation\" message=\"Are you sure to proceed?\" :buttons=\"buttons\" />\n\t\t<p>Last response: {{ lastResponse }}</p>\n\t</div>\n</template>\n<script>\nimport IconCancel from '@mdi/svg/svg/cancel.svg?raw'\nimport IconCheck from '@mdi/svg/svg/check.svg?raw'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tshowDialog: false,\n\t\t\tlastResponse: 'None',\n\t\t\tbuttons: [\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Cancel',\n\t\t\t\t\ticon: IconCancel,\n\t\t\t\t\tcallback: () => { this.lastResponse = 'Pressed \"Cancel\"' },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Ok',\n\t\t\t\t\ttype: 'primary',\n\t\t\t\t\ticon: IconCheck,\n\t\t\t\t\tcallback: () => { this.lastResponse = 'Pressed \"Ok\"' },\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t},\n}\n</script>\n```\n\n### Use custom actions and content\nInstead of using the buttons property, you can also inject your custom actions using a named slot.\nYou can also use the default slot to inject custom content.\n\n```vue\n<template>\n\t<div style=\"display: flex; gap: 12px;\">\n\t\t<NcButton @click=\"showDialog = true\">Show dialog</NcButton>\n\t\t<NcButton @click=\"showLongDialog = true\">Show long dialog</NcButton>\n\t\t<NcDialog v-if=\"showDialog\" name=\"Warning\" :can-close=\"false\">\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"showDialog = false\">Ok</NcButton>\n\t\t\t</template>\n\t\t\t<div style=\"color: red; font-weight: bold;\">This is serious</div>\n\t\t</NcDialog>\n\t\t<NcDialog :open.sync=\"showLongDialog\" name=\"Lorem Ipsum\">\n\t\t\t<p v-for=\"i in new Array(63)\" :key=\"i\">Lorem ipsum dolor sit amet.</p>\n\t\t</NcDialog>\n\t</div>\n</template>\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tshowDialog: false,\n\t\t\tshowLongDialog: false,\n\t\t}\n\t},\n}\n</script>\n```\n</docs>\n\n<template>\n\t<NcModal v-if=\"open\"\n\t\tclass=\"dialog__modal\"\n\t\t:enable-slideshow=\"false\"\n\t\t:enable-swipe=\"false\"\n\t\tv-bind=\"modalProps\"\n\t\t@close=\"handleClosed\"\n\t\t@update:show=\"handleClosing\">\n\t\t<!-- The dialog name / header -->\n\t\t<h2 :id=\"navigationId\" class=\"dialog__name\" v-text=\"name\" />\n\t\t<div class=\"dialog\" :class=\"dialogClasses\">\n\t\t\t<div ref=\"wrapper\" :class=\"['dialog__wrapper', { 'dialog__wrapper--collapsed': isNavigationCollapsed }]\">\n\t\t\t\t<!-- When the navigation is collapsed (too small dialog) it is displayed above the main content, otherwise on the inline start -->\n\t\t\t\t<nav v-if=\"hasNavigation\"\n\t\t\t\t\tclass=\"dialog__navigation\"\n\t\t\t\t\t:class=\"navigationClasses\"\n\t\t\t\t\t:aria-label=\"navigationAriaLabelAttr\"\n\t\t\t\t\t:aria-labelledby=\"navigationAriaLabelledbyAttr\">\n\t\t\t\t\t<slot name=\"navigation\" :is-collapsed=\"isNavigationCollapsed\" />\n\t\t\t\t</nav>\n\t\t\t\t<!-- Main dialog content -->\n\t\t\t\t<div class=\"dialog__content\" :class=\"contentClasses\">\n\t\t\t\t\t<slot>\n\t\t\t\t\t\t<p class=\"dialog__text\">\n\t\t\t\t\t\t\t{{ message }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</slot>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- The dialog actions aka the buttons -->\n\t\t\t<div class=\"dialog__actions\">\n\t\t\t\t<slot name=\"actions\">\n\t\t\t\t\t<NcDialogButton v-for=\"(button, idx) in buttons\"\n\t\t\t\t\t\t:key=\"idx\"\n\t\t\t\t\t\tv-bind=\"button\"\n\t\t\t\t\t\t@click=\"handleButtonClose\" />\n\t\t\t\t</slot>\n\t\t\t</div>\n\t\t</div>\n\t</NcModal>\n</template>\n\n<script>\nimport { useElementSize } from '@vueuse/core'\nimport { computed, defineComponent, ref } from 'vue'\n\nimport NcModal from '../NcModal/index.js'\nimport NcDialogButton from '../NcDialogButton/index.js'\n\nimport GenRandomId from '../../utils/GenRandomId.js'\n\nexport default defineComponent({\n\tname: 'NcDialog',\n\n\tcomponents: {\n\t\tNcDialogButton,\n\t\tNcModal,\n\t},\n\n\tprops: {\n\t\t/** Name of the dialog (the heading) */\n\t\tname: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** Text of the dialog */\n\t\tmessage: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Additional elements to add to the focus trap */\n\t\tadditionalTrapElements: {\n\t\t\ttype: Array,\n\t\t\tvalidator: (arr) => {\n\t\t\t\treturn (\n\t\t\t\t\tArray.isArray(arr) && arr.every(\n\t\t\t\t\t\t(element) =>\n\t\t\t\t\t\t\ttypeof element === 'string' || element instanceof HTMLElement,\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t},\n\t\t\tdefault: () => ([]),\n\t\t},\n\n\t\t/**\n\t\t * The element where to mount the dialog, if `null` is passed the dialog is mounted in place\n\t\t * @default 'body'\n\t\t */\n\t\tcontainer: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: 'body',\n\t\t},\n\n\t\t/**\n\t\t * Whether the dialog should be shown\n\t\t * @default true\n\t\t */\n\t\topen: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Size of the underlying NcModal\n\t\t * @default 'small'\n\t\t * @type {'small'|'normal'|'large'|'full'}\n\t\t */\n\t\tsize: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: 'small',\n\t\t\tvalidator: (value) => typeof value === 'string' && ['small', 'normal', 'large', 'full'].includes(value),\n\t\t},\n\n\t\t/**\n\t\t * Buttons to display\n\t\t * @default []\n\t\t */\n\t\tbuttons: {\n\t\t\ttype: Array,\n\t\t\trequired: false,\n\t\t\tdefault: () => ([]),\n\t\t\tvalidator: (value) => Array.isArray(value) && value.every((element) => typeof element === 'object'),\n\t\t},\n\n\t\t/**\n\t\t * Set to false to no show a close button on the dialog\n\t\t * @default true\n\t\t */\n\t\tcanClose: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Close the dialog if the user clicked outside of the dialog\n\t\t * Only relevant if `canClose` is set to true.\n\t\t */\n\t\tcloseOnClickOutside: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Declare if hiding the modal should be animated\n\t\t * @default false\n\t\t */\n\t\toutTransition: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the navigation for custom styling\n\t\t * @default ''\n\t\t * @example\n\t\t * ```html\n\t\t * <DialogBase :navigation-classes=\"['mydialog-navigation']\"><!-- --></DialogBase>\n\t\t * <!-- ... -->\n\t\t * <style lang=\"scss\">\n\t\t * :deep(.mydialog-navigation) {\n\t\t * flex-direction: row-reverse;\n\t\t * }\n\t\t * </style>\n\t\t * ```\n\t\t */\n\t\tnavigationClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * aria-label for the dialog navigation.\n\t\t * Use it when you want to provide a more meaningful label than the dialog name.\n\t\t *\n\t\t * By default, navigation is labeled by the dialog name.\n\t\t */\n\t\tnavigationAriaLabel: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * aria-labelledby for the dialog navigation.\n\t\t * Use it when you have an implicit navigation label (e.g. a heading).\n\t\t *\n\t\t * By default, navigation is labeled by the dialog name.\n\t\t */\n\t\tnavigationAriaLabelledby: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the content wrapper for custom styling\n\t\t * @default ''\n\t\t */\n\t\tcontentClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the dialog itself\n\t\t * (the default `class` attribute will be set on the modal wrapper)\n\t\t * @default ''\n\t\t */\n\t\tdialogClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['closing', 'update:open'],\n\n\tsetup(props, { emit, slots }) {\n\t\t/**\n\t\t * The dialog wrapper element\n\t\t * @type {import('vue').Ref<HTMLDivElement>}\n\t\t */\n\t\tconst wrapper = ref()\n\n\t\t/**\n\t\t * We use the dialog width to decide if we collapse the navigation (flex direction row)\n\t\t */\n\t\tconst { width: dialogWidth } = useElementSize(wrapper, { width: 900 })\n\n\t\t/**\n\t\t * Whether the navigation is collapsed due to dialog and window size\n\t\t * (collapses when modal is below: 900px modal width - 2x 12px margin)\n\t\t */\n\t\tconst isNavigationCollapsed = computed(() => dialogWidth.value < 876)\n\n\t\t/**\n\t\t * Whether a navigation was passed and the element should be displayed\n\t\t */\n\t\tconst hasNavigation = computed(() => slots?.navigation !== undefined)\n\n\t\t/**\n\t\t * The unique id of the nav element\n\t\t */\n\t\tconst navigationId = ref(GenRandomId())\n\n\t\t/**\n\t\t * aria-label attribute for the nav element\n\t\t */\n\t\tconst navigationAriaLabelAttr = computed(() => props.navigationAriaLabel || undefined)\n\n\t\t/**\n\t\t * aria-labelledby attribute for the nav element\n\t\t */\n\t\tconst navigationAriaLabelledbyAttr = computed(() => {\n\t\t\tif (props.navigationAriaLabel) {\n\t\t\t\t// Not needed, already labelled by aria-label\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\t// Use dialog name as a fallback label for navigation\n\t\t\treturn props.navigationAriaLabelledby || navigationId.value\n\t\t})\n\n\t\t/**\n\t\t * If the underlaying modal is shown\n\t\t */\n\t\tconst showModal = ref(true)\n\n\t\t// Because NcModal does not emit `close` when show prop is changed\n\t\t/**\n\t\t * Handle clicking a dialog button -> should close\n\t\t */\n\t\tconst handleButtonClose = () => {\n\t\t\thandleClosing()\n\t\t\twindow.setTimeout(() => handleClosed(), 300)\n\t\t}\n\n\t\t/**\n\t\t * Handle closing the dialog, optional out transition did not run yet\n\t\t */\n\t\tconst handleClosing = () => {\n\t\t\tshowModal.value = false\n\t\t\t/**\n\t\t\t * Emitted when the dialog is closing, so the out transition did not finish yet\n\t\t\t */\n\t\t\temit('closing')\n\t\t}\n\n\t\t/**\n\t\t * Handle dialog closed (out transition finished)\n\t\t */\n\t\tconst handleClosed = () => {\n\t\t\tshowModal.value = true\n\t\t\t/**\n\t\t\t * Emitted then the dialog is fully closed and the out transition run\n\t\t\t */\n\t\t\temit('update:open', false)\n\t\t}\n\n\t\t/**\n\t\t * Properties to pass to the underlying NcModal\n\t\t */\n\t\tconst modalProps = computed(() => ({\n\t\t\tcanClose: props.canClose,\n\t\t\tcontainer: props.container === undefined ? 'body' : props.container,\n\t\t\t// we do not pass the name as we already have the name as the headline\n\t\t\t// name: props.name,\n\t\t\tsize: props.size,\n\t\t\tshow: props.open && showModal.value,\n\t\t\toutTransition: props.outTransition,\n\t\t\tcloseOnClickOutside: props.closeOnClickOutside,\n\t\t\tadditionalTrapElements: props.additionalTrapElements,\n\t\t}))\n\n\t\treturn {\n\t\t\thandleButtonClose,\n\t\t\thandleClosing,\n\t\t\thandleClosed,\n\t\t\thasNavigation,\n\t\t\tnavigationId,\n\t\t\tnavigationAriaLabelAttr,\n\t\t\tnavigationAriaLabelledbyAttr,\n\t\t\tisNavigationCollapsed,\n\t\t\tmodalProps,\n\t\t\twrapper,\n\t\t}\n\t},\n})\n</script>\n\n<style lang=\"scss\">\n/** When having the small dialog style we override the modal styling so dialogs look more dialog like */\n@media only screen and (max-width: $breakpoint-small-mobile) {\n\t.dialog__modal .modal-wrapper--small .modal-container {\n\t\twidth: fit-content;\n\t\theight: unset;\n\t\tmax-height: 90%;\n\t\tposition: relative;\n\t\ttop: unset;\n\t\tborder-radius: var(--border-radius-large);\n\t}\n}\n</style>\n\n<style lang=\"scss\" scoped>\n.dialog {\n\theight: 100%;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: space-between;\n\toverflow: hidden;\n\n\t&__modal {\n\t\t:deep(.modal-wrapper .modal-container) {\n\t\t\tdisplay: flex !important;\n\t\t\tpadding-block: 4px 0; // 4px to align with close button, 0 block-end to make overflowing content on scroll look nice\n\t\t\tpadding-inline: 12px 0; // Same as with padding-block, we need the actions to have a margin of 4px for the button outline\n\t\t}\n\t\t:deep(.modal-wrapper .modal-container__content) {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\toverflow: hidden; // Only overflow on the .dialog__content\n\t\t}\n\t}\n\n\t&__wrapper {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\t// Auto scale to fit\n\t\tflex: 1;\n\t\tmin-height: 0;\n\t\toverflow: hidden;\n\n\t\t&--collapsed {\n\t\t\tflex-direction: column;\n\t\t}\n\t}\n\n\t&__navigation {\n\t\tdisplay: flex;\n\t\tflex-shrink: 0;\n\t}\n\n\t// Navigation styling when side-by-side with content\n\t&__wrapper:not(&__wrapper--collapsed) &__navigation {\n\t\tflex-direction: column;\n\n\t\toverflow: hidden auto;\n\t\theight: 100%;\n\t\tmin-width: 200px;\n\t\tmargin-inline-end: 20px;\n\t}\n\n\t// Navigation styling when on top of content\n\t&__wrapper#{&}__wrapper--collapsed &__navigation {\n\t\tflex-direction: row;\n\t\tjustify-content: space-between;\n\n\t\toverflow: auto hidden;\n\t\twidth: 100%;\n\t\tmin-width: 100%;\n\t}\n\n\t&__name {\n\t\tfont-size: 21px;\n\n\t\ttext-align: center;\n\t\theight: fit-content;\n\t\tmin-height: var(--default-clickable-area);\n\t\tline-height: var(--default-clickable-area);\n\t\toverflow-wrap: break-word;\n\t\tmargin-block: 0 12px;\n\t}\n\n\t&__content {\n\t\t// Auto fit\n\t\tflex: 1;\n\t\tmin-height: 0;\n\t\toverflow: auto;\n\t\t// see .dialog__modal, we can not set the padding there to prevent floating scroll bars\n\t\tpadding-inline-end: 12px;\n\t}\n\n\t// In case only text content is show\n\t&__text {\n\t\t// Also add padding to the bottom to make it more readable\n\t\tpadding-block-end: 6px;\n\t}\n\n\t&__actions {\n\t\tdisplay: flex;\n\t\tgap: 6px;\n\t\talign-content: center;\n\t\twidth: fit-content;\n\t\tmargin-inline: auto 12px; // 12px to align with the overall modal padding\n\t\tmargin-block: 0;\n\n\t\t&:not(:empty) {\n\t\t\tmargin-block: 6px 12px; // only if there are actions, we add margin so if it is empty scroll content looks nice\n\t\t}\n\t}\n}\n\n@media only screen and (max-width: $breakpoint-small-mobile) {\n\t// Ensure the dialog name does not interfere with the close button\n\t.dialog__name {\n\t\ttext-align: start;\n\t\tmargin-inline-end: var(--default-clickable-area);\n\t}\n}\n</style>\n"],"names":["_sfc_main","defineComponent","NcDialogButton","NcModal","arr","element","value","props","emit","slots","wrapper","ref","dialogWidth","useElementSize","isNavigationCollapsed","computed","hasNavigation","navigationId","GenRandomId","navigationAriaLabelAttr","navigationAriaLabelledbyAttr","showModal","handleButtonClose","handleClosing","handleClosed","modalProps"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- require('../assets/NcDialog-M36tj7nk.css');
1
+ require('../assets/NcDialog-DEKSpcnR.css');
2
2
  "use strict";
3
3
  const v = require("@vueuse/core"), n = require("vue"), y = require("../Components/NcModal.cjs"), m = require("./NcDialogButton-D7ibBxsQ.cjs"), C = require("./GenRandomId-B2O1GMbH.cjs"), b = require("./_plugin-vue2_normalizer-GXKvuwrq.cjs"), A = n.defineComponent({
4
4
  name: "NcDialog",
@@ -199,7 +199,7 @@ var h = function() {
199
199
  N,
200
200
  !1,
201
201
  null,
202
- "40a87f52",
202
+ "b0b5e355",
203
203
  null,
204
204
  null
205
205
  );
@@ -1 +1 @@
1
- {"version":3,"file":"NcDialog-C6nYgBDF.cjs","sources":["../../src/components/NcDialog/NcDialog.vue"],"sourcesContent":["<!--\n - @copyright Copyright (c) 2023 Ferdinand Thiessen\n -\n - @author Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n### General description\n\nThis component uses the `NcModal` under the hood for allowing users to create generic dialogs.\n\n### Basic example\n```vue\n<template>\n\t<div>\n\t\t<NcButton @click=\"showDialog = true\">Show dialog</NcButton>\n\t\t<NcDialog :open.sync=\"showDialog\" name=\"Confirmation\" message=\"Are you sure to proceed?\" :buttons=\"buttons\" />\n\t\t<p>Last response: {{ lastResponse }}</p>\n\t</div>\n</template>\n<script>\nimport IconCancel from '@mdi/svg/svg/cancel.svg?raw'\nimport IconCheck from '@mdi/svg/svg/check.svg?raw'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tshowDialog: false,\n\t\t\tlastResponse: 'None',\n\t\t\tbuttons: [\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Cancel',\n\t\t\t\t\ticon: IconCancel,\n\t\t\t\t\tcallback: () => { this.lastResponse = 'Pressed \"Cancel\"' },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Ok',\n\t\t\t\t\ttype: 'primary',\n\t\t\t\t\ticon: IconCheck,\n\t\t\t\t\tcallback: () => { this.lastResponse = 'Pressed \"Ok\"' },\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t},\n}\n</script>\n```\n\n### Use custom actions and content\nInstead of using the buttons property, you can also inject your custom actions using a named slot.\nYou can also use the default slot to inject custom content.\n\n```vue\n<template>\n\t<div style=\"display: flex; gap: 12px;\">\n\t\t<NcButton @click=\"showDialog = true\">Show dialog</NcButton>\n\t\t<NcButton @click=\"showLongDialog = true\">Show long dialog</NcButton>\n\t\t<NcDialog v-if=\"showDialog\" name=\"Warning\" :can-close=\"false\">\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"showDialog = false\">Ok</NcButton>\n\t\t\t</template>\n\t\t\t<div style=\"color: red; font-weight: bold;\">This is serious</div>\n\t\t</NcDialog>\n\t\t<NcDialog :open.sync=\"showLongDialog\" name=\"Lorem Ipsum\">\n\t\t\t<p v-for=\"i in new Array(63)\" :key=\"i\">Lorem ipsum dolor sit amet.</p>\n\t\t</NcDialog>\n\t</div>\n</template>\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tshowDialog: false,\n\t\t\tshowLongDialog: false,\n\t\t}\n\t},\n}\n</script>\n```\n</docs>\n\n<template>\n\t<NcModal v-if=\"open\"\n\t\tclass=\"dialog__modal\"\n\t\t:enable-slideshow=\"false\"\n\t\t:enable-swipe=\"false\"\n\t\tv-bind=\"modalProps\"\n\t\t@close=\"handleClosed\"\n\t\t@update:show=\"handleClosing\">\n\t\t<!-- The dialog name / header -->\n\t\t<h2 :id=\"navigationId\" class=\"dialog__name\" v-text=\"name\" />\n\t\t<div class=\"dialog\" :class=\"dialogClasses\">\n\t\t\t<div ref=\"wrapper\" :class=\"['dialog__wrapper', { 'dialog__wrapper--collapsed': isNavigationCollapsed }]\">\n\t\t\t\t<!-- When the navigation is collapsed (too small dialog) it is displayed above the main content, otherwise on the inline start -->\n\t\t\t\t<nav v-if=\"hasNavigation\"\n\t\t\t\t\tclass=\"dialog__navigation\"\n\t\t\t\t\t:class=\"navigationClasses\"\n\t\t\t\t\t:aria-label=\"navigationAriaLabelAttr\"\n\t\t\t\t\t:aria-labelledby=\"navigationAriaLabelledbyAttr\">\n\t\t\t\t\t<slot name=\"navigation\" :is-collapsed=\"isNavigationCollapsed\" />\n\t\t\t\t</nav>\n\t\t\t\t<!-- Main dialog content -->\n\t\t\t\t<div class=\"dialog__content\" :class=\"contentClasses\">\n\t\t\t\t\t<slot>\n\t\t\t\t\t\t<p class=\"dialog__text\">\n\t\t\t\t\t\t\t{{ message }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</slot>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- The dialog actions aka the buttons -->\n\t\t\t<div class=\"dialog__actions\">\n\t\t\t\t<slot name=\"actions\">\n\t\t\t\t\t<NcDialogButton v-for=\"(button, idx) in buttons\"\n\t\t\t\t\t\t:key=\"idx\"\n\t\t\t\t\t\tv-bind=\"button\"\n\t\t\t\t\t\t@click=\"handleButtonClose\" />\n\t\t\t\t</slot>\n\t\t\t</div>\n\t\t</div>\n\t</NcModal>\n</template>\n\n<script>\nimport { useElementSize } from '@vueuse/core'\nimport { computed, defineComponent, ref } from 'vue'\n\nimport NcModal from '../NcModal/index.js'\nimport NcDialogButton from '../NcDialogButton/index.js'\n\nimport GenRandomId from '../../utils/GenRandomId.js'\n\nexport default defineComponent({\n\tname: 'NcDialog',\n\n\tcomponents: {\n\t\tNcDialogButton,\n\t\tNcModal,\n\t},\n\n\tprops: {\n\t\t/** Name of the dialog (the heading) */\n\t\tname: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** Text of the dialog */\n\t\tmessage: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Additional elements to add to the focus trap */\n\t\tadditionalTrapElements: {\n\t\t\ttype: Array,\n\t\t\tvalidator: (arr) => {\n\t\t\t\treturn (\n\t\t\t\t\tArray.isArray(arr) && arr.every(\n\t\t\t\t\t\t(element) =>\n\t\t\t\t\t\t\ttypeof element === 'string' || element instanceof HTMLElement,\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t},\n\t\t\tdefault: () => ([]),\n\t\t},\n\n\t\t/**\n\t\t * The element where to mount the dialog, if `null` is passed the dialog is mounted in place\n\t\t * @default 'body'\n\t\t */\n\t\tcontainer: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: 'body',\n\t\t},\n\n\t\t/**\n\t\t * Whether the dialog should be shown\n\t\t * @default true\n\t\t */\n\t\topen: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Size of the underlying NcModal\n\t\t * @default 'small'\n\t\t * @type {'small'|'normal'|'large'|'full'}\n\t\t */\n\t\tsize: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: 'small',\n\t\t\tvalidator: (value) => typeof value === 'string' && ['small', 'normal', 'large', 'full'].includes(value),\n\t\t},\n\n\t\t/**\n\t\t * Buttons to display\n\t\t * @default []\n\t\t */\n\t\tbuttons: {\n\t\t\ttype: Array,\n\t\t\trequired: false,\n\t\t\tdefault: () => ([]),\n\t\t\tvalidator: (value) => Array.isArray(value) && value.every((element) => typeof element === 'object'),\n\t\t},\n\n\t\t/**\n\t\t * Set to false to no show a close button on the dialog\n\t\t * @default true\n\t\t */\n\t\tcanClose: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Close the dialog if the user clicked outside of the dialog\n\t\t * Only relevant if `canClose` is set to true.\n\t\t */\n\t\tcloseOnClickOutside: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Declare if hiding the modal should be animated\n\t\t * @default false\n\t\t */\n\t\toutTransition: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the navigation for custom styling\n\t\t * @default ''\n\t\t * @example\n\t\t * ```html\n\t\t * <DialogBase :navigation-classes=\"['mydialog-navigation']\"><!-- --></DialogBase>\n\t\t * <!-- ... -->\n\t\t * <style lang=\"scss\">\n\t\t * :deep(.mydialog-navigation) {\n\t\t * flex-direction: row-reverse;\n\t\t * }\n\t\t * </style>\n\t\t * ```\n\t\t */\n\t\tnavigationClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * aria-label for the dialog navigation.\n\t\t * Use it when you want to provide a more meaningful label than the dialog name.\n\t\t *\n\t\t * By default, navigation is labeled by the dialog name.\n\t\t */\n\t\tnavigationAriaLabel: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * aria-labelledby for the dialog navigation.\n\t\t * Use it when you have an implicit navigation label (e.g. a heading).\n\t\t *\n\t\t * By default, navigation is labeled by the dialog name.\n\t\t */\n\t\tnavigationAriaLabelledby: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the content wrapper for custom styling\n\t\t * @default ''\n\t\t */\n\t\tcontentClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the dialog itself\n\t\t * (the default `class` attribute will be set on the modal wrapper)\n\t\t * @default ''\n\t\t */\n\t\tdialogClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['closing', 'update:open'],\n\n\tsetup(props, { emit, slots }) {\n\t\t/**\n\t\t * The dialog wrapper element\n\t\t * @type {import('vue').Ref<HTMLDivElement>}\n\t\t */\n\t\tconst wrapper = ref()\n\n\t\t/**\n\t\t * We use the dialog width to decide if we collapse the navigation (flex direction row)\n\t\t */\n\t\tconst { width: dialogWidth } = useElementSize(wrapper, { width: 900 })\n\n\t\t/**\n\t\t * Whether the navigation is collapsed due to dialog and window size\n\t\t * (collapses when modal is below: 900px modal width - 2x 12px margin)\n\t\t */\n\t\tconst isNavigationCollapsed = computed(() => dialogWidth.value < 876)\n\n\t\t/**\n\t\t * Whether a navigation was passed and the element should be displayed\n\t\t */\n\t\tconst hasNavigation = computed(() => slots?.navigation !== undefined)\n\n\t\t/**\n\t\t * The unique id of the nav element\n\t\t */\n\t\tconst navigationId = ref(GenRandomId())\n\n\t\t/**\n\t\t * aria-label attribute for the nav element\n\t\t */\n\t\tconst navigationAriaLabelAttr = computed(() => props.navigationAriaLabel || undefined)\n\n\t\t/**\n\t\t * aria-labelledby attribute for the nav element\n\t\t */\n\t\tconst navigationAriaLabelledbyAttr = computed(() => {\n\t\t\tif (props.navigationAriaLabel) {\n\t\t\t\t// Not needed, already labelled by aria-label\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\t// Use dialog name as a fallback label for navigation\n\t\t\treturn props.navigationAriaLabelledby || navigationId.value\n\t\t})\n\n\t\t/**\n\t\t * If the underlaying modal is shown\n\t\t */\n\t\tconst showModal = ref(true)\n\n\t\t// Because NcModal does not emit `close` when show prop is changed\n\t\t/**\n\t\t * Handle clicking a dialog button -> should close\n\t\t */\n\t\tconst handleButtonClose = () => {\n\t\t\thandleClosing()\n\t\t\twindow.setTimeout(() => handleClosed(), 300)\n\t\t}\n\n\t\t/**\n\t\t * Handle closing the dialog, optional out transition did not run yet\n\t\t */\n\t\tconst handleClosing = () => {\n\t\t\tshowModal.value = false\n\t\t\t/**\n\t\t\t * Emitted when the dialog is closing, so the out transition did not finish yet\n\t\t\t */\n\t\t\temit('closing')\n\t\t}\n\n\t\t/**\n\t\t * Handle dialog closed (out transition finished)\n\t\t */\n\t\tconst handleClosed = () => {\n\t\t\tshowModal.value = true\n\t\t\t/**\n\t\t\t * Emitted then the dialog is fully closed and the out transition run\n\t\t\t */\n\t\t\temit('update:open', false)\n\t\t}\n\n\t\t/**\n\t\t * Properties to pass to the underlying NcModal\n\t\t */\n\t\tconst modalProps = computed(() => ({\n\t\t\tcanClose: props.canClose,\n\t\t\tcontainer: props.container === undefined ? 'body' : props.container,\n\t\t\t// we do not pass the name as we already have the name as the headline\n\t\t\t// name: props.name,\n\t\t\tsize: props.size,\n\t\t\tshow: props.open && showModal.value,\n\t\t\toutTransition: props.outTransition,\n\t\t\tcloseOnClickOutside: props.closeOnClickOutside,\n\t\t\tadditionalTrapElements: props.additionalTrapElements,\n\t\t}))\n\n\t\treturn {\n\t\t\thandleButtonClose,\n\t\t\thandleClosing,\n\t\t\thandleClosed,\n\t\t\thasNavigation,\n\t\t\tnavigationId,\n\t\t\tnavigationAriaLabelAttr,\n\t\t\tnavigationAriaLabelledbyAttr,\n\t\t\tisNavigationCollapsed,\n\t\t\tmodalProps,\n\t\t\twrapper,\n\t\t}\n\t},\n})\n</script>\n\n<style lang=\"scss\">\n/** When having the small dialog style we override the modal styling so dialogs look more dialog like */\n@media only screen and (max-width: $breakpoint-small-mobile) {\n\t.dialog__modal .modal-wrapper--small .modal-container {\n\t\twidth: fit-content;\n\t\theight: unset;\n\t\tmax-height: 90%;\n\t\tposition: relative;\n\t\ttop: unset;\n\t\tborder-radius: var(--border-radius-large);\n\t}\n}\n</style>\n\n<style lang=\"scss\" scoped>\n.dialog {\n\theight: 100%;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: space-between;\n\toverflow: hidden;\n\n\t&__modal {\n\t\t:deep(.modal-wrapper .modal-container) {\n\t\t\tdisplay: flex !important;\n\t\t\tpadding-block: 4px 0; // 4px to align with close button, 0 block-end to make overflowing content on scroll look nice\n\t\t\tpadding-inline: 12px 0; // Same as with padding-block, we need the actions to have a margin of 4px for the button outline\n\t\t}\n\t\t:deep(.modal-wrapper .modal-container__content) {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\toverflow: hidden; // Only overflow on the .dialog__content\n\t\t}\n\t}\n\n\t&__wrapper {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\t// Auto scale to fit\n\t\tflex: 1;\n\t\tmin-height: 0;\n\t\toverflow: hidden;\n\n\t\t&--collapsed {\n\t\t\tflex-direction: column;\n\t\t}\n\t}\n\n\t&__navigation {\n\t\tdisplay: flex;\n\t\tflex-shrink: 0;\n\t}\n\n\t// Navigation styling when side-by-side with content\n\t&__wrapper:not(&__wrapper--collapsed) &__navigation {\n\t\tflex-direction: column;\n\n\t\toverflow: hidden auto;\n\t\theight: 100%;\n\t\tmin-width: 200px;\n\t\tmargin-inline-end: 20px;\n\t}\n\n\t// Navigation styling when on top of content\n\t&__wrapper#{&}__wrapper--collapsed &__navigation {\n\t\tflex-direction: row;\n\t\tjustify-content: space-between;\n\n\t\toverflow: auto hidden;\n\t\twidth: 100%;\n\t\tmin-width: 100%;\n\t}\n\n\t&__name {\n\t\ttext-align: center;\n\t\theight: fit-content;\n\t\tmin-height: var(--default-clickable-area);\n\t\tline-height: var(--default-clickable-area);\n\t\toverflow-wrap: break-word;\n\t\tmargin-block-end: 12px;\n\t}\n\n\t&__content {\n\t\t// Auto fit\n\t\tflex: 1;\n\t\tmin-height: 0;\n\t\toverflow: auto;\n\t\t// see .dialog__modal, we can not set the padding there to prevent floating scroll bars\n\t\tpadding-inline-end: 12px;\n\t}\n\n\t// In case only text content is show\n\t&__text {\n\t\t// Also add padding to the bottom to make it more readable\n\t\tpadding-block-end: 6px;\n\t}\n\n\t&__actions {\n\t\tdisplay: flex;\n\t\tgap: 6px;\n\t\talign-content: center;\n\t\twidth: fit-content;\n\t\tmargin-inline: auto 12px; // 12px to align with the overall modal padding\n\t\tmargin-block: 0;\n\n\t\t&:not(:empty) {\n\t\t\tmargin-block: 6px 12px; // only if there are actions, we add margin so if it is empty scroll content looks nice\n\t\t}\n\t}\n}\n\n@media only screen and (max-width: $breakpoint-small-mobile) {\n\t// Ensure the dialog name does not interfere with the close button\n\t.dialog__name {\n\t\ttext-align: start;\n\t\tmargin-inline-end: var(--default-clickable-area);\n\t}\n}\n</style>\n"],"names":["_sfc_main","defineComponent","NcDialogButton","NcModal","arr","element","value","props","emit","slots","wrapper","ref","dialogWidth","useElementSize","isNavigationCollapsed","computed","hasNavigation","navigationId","GenRandomId","navigationAriaLabelAttr","navigationAriaLabelledbyAttr","showModal","handleButtonClose","handleClosing","handleClosed","modalProps"],"mappings":"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"}
1
+ {"version":3,"file":"NcDialog-Ciz0hlFn.cjs","sources":["../../src/components/NcDialog/NcDialog.vue"],"sourcesContent":["<!--\n - @copyright Copyright (c) 2023 Ferdinand Thiessen\n -\n - @author Ferdinand Thiessen <opensource@fthiessen.de>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n### General description\n\nThis component uses the `NcModal` under the hood for allowing users to create generic dialogs.\n\n### Basic example\n```vue\n<template>\n\t<div>\n\t\t<NcButton @click=\"showDialog = true\">Show dialog</NcButton>\n\t\t<NcDialog :open.sync=\"showDialog\" name=\"Confirmation\" message=\"Are you sure to proceed?\" :buttons=\"buttons\" />\n\t\t<p>Last response: {{ lastResponse }}</p>\n\t</div>\n</template>\n<script>\nimport IconCancel from '@mdi/svg/svg/cancel.svg?raw'\nimport IconCheck from '@mdi/svg/svg/check.svg?raw'\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tshowDialog: false,\n\t\t\tlastResponse: 'None',\n\t\t\tbuttons: [\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Cancel',\n\t\t\t\t\ticon: IconCancel,\n\t\t\t\t\tcallback: () => { this.lastResponse = 'Pressed \"Cancel\"' },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Ok',\n\t\t\t\t\ttype: 'primary',\n\t\t\t\t\ticon: IconCheck,\n\t\t\t\t\tcallback: () => { this.lastResponse = 'Pressed \"Ok\"' },\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t},\n}\n</script>\n```\n\n### Use custom actions and content\nInstead of using the buttons property, you can also inject your custom actions using a named slot.\nYou can also use the default slot to inject custom content.\n\n```vue\n<template>\n\t<div style=\"display: flex; gap: 12px;\">\n\t\t<NcButton @click=\"showDialog = true\">Show dialog</NcButton>\n\t\t<NcButton @click=\"showLongDialog = true\">Show long dialog</NcButton>\n\t\t<NcDialog v-if=\"showDialog\" name=\"Warning\" :can-close=\"false\">\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"showDialog = false\">Ok</NcButton>\n\t\t\t</template>\n\t\t\t<div style=\"color: red; font-weight: bold;\">This is serious</div>\n\t\t</NcDialog>\n\t\t<NcDialog :open.sync=\"showLongDialog\" name=\"Lorem Ipsum\">\n\t\t\t<p v-for=\"i in new Array(63)\" :key=\"i\">Lorem ipsum dolor sit amet.</p>\n\t\t</NcDialog>\n\t</div>\n</template>\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tshowDialog: false,\n\t\t\tshowLongDialog: false,\n\t\t}\n\t},\n}\n</script>\n```\n</docs>\n\n<template>\n\t<NcModal v-if=\"open\"\n\t\tclass=\"dialog__modal\"\n\t\t:enable-slideshow=\"false\"\n\t\t:enable-swipe=\"false\"\n\t\tv-bind=\"modalProps\"\n\t\t@close=\"handleClosed\"\n\t\t@update:show=\"handleClosing\">\n\t\t<!-- The dialog name / header -->\n\t\t<h2 :id=\"navigationId\" class=\"dialog__name\" v-text=\"name\" />\n\t\t<div class=\"dialog\" :class=\"dialogClasses\">\n\t\t\t<div ref=\"wrapper\" :class=\"['dialog__wrapper', { 'dialog__wrapper--collapsed': isNavigationCollapsed }]\">\n\t\t\t\t<!-- When the navigation is collapsed (too small dialog) it is displayed above the main content, otherwise on the inline start -->\n\t\t\t\t<nav v-if=\"hasNavigation\"\n\t\t\t\t\tclass=\"dialog__navigation\"\n\t\t\t\t\t:class=\"navigationClasses\"\n\t\t\t\t\t:aria-label=\"navigationAriaLabelAttr\"\n\t\t\t\t\t:aria-labelledby=\"navigationAriaLabelledbyAttr\">\n\t\t\t\t\t<slot name=\"navigation\" :is-collapsed=\"isNavigationCollapsed\" />\n\t\t\t\t</nav>\n\t\t\t\t<!-- Main dialog content -->\n\t\t\t\t<div class=\"dialog__content\" :class=\"contentClasses\">\n\t\t\t\t\t<slot>\n\t\t\t\t\t\t<p class=\"dialog__text\">\n\t\t\t\t\t\t\t{{ message }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</slot>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- The dialog actions aka the buttons -->\n\t\t\t<div class=\"dialog__actions\">\n\t\t\t\t<slot name=\"actions\">\n\t\t\t\t\t<NcDialogButton v-for=\"(button, idx) in buttons\"\n\t\t\t\t\t\t:key=\"idx\"\n\t\t\t\t\t\tv-bind=\"button\"\n\t\t\t\t\t\t@click=\"handleButtonClose\" />\n\t\t\t\t</slot>\n\t\t\t</div>\n\t\t</div>\n\t</NcModal>\n</template>\n\n<script>\nimport { useElementSize } from '@vueuse/core'\nimport { computed, defineComponent, ref } from 'vue'\n\nimport NcModal from '../NcModal/index.js'\nimport NcDialogButton from '../NcDialogButton/index.js'\n\nimport GenRandomId from '../../utils/GenRandomId.js'\n\nexport default defineComponent({\n\tname: 'NcDialog',\n\n\tcomponents: {\n\t\tNcDialogButton,\n\t\tNcModal,\n\t},\n\n\tprops: {\n\t\t/** Name of the dialog (the heading) */\n\t\tname: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** Text of the dialog */\n\t\tmessage: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Additional elements to add to the focus trap */\n\t\tadditionalTrapElements: {\n\t\t\ttype: Array,\n\t\t\tvalidator: (arr) => {\n\t\t\t\treturn (\n\t\t\t\t\tArray.isArray(arr) && arr.every(\n\t\t\t\t\t\t(element) =>\n\t\t\t\t\t\t\ttypeof element === 'string' || element instanceof HTMLElement,\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t},\n\t\t\tdefault: () => ([]),\n\t\t},\n\n\t\t/**\n\t\t * The element where to mount the dialog, if `null` is passed the dialog is mounted in place\n\t\t * @default 'body'\n\t\t */\n\t\tcontainer: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: 'body',\n\t\t},\n\n\t\t/**\n\t\t * Whether the dialog should be shown\n\t\t * @default true\n\t\t */\n\t\topen: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Size of the underlying NcModal\n\t\t * @default 'small'\n\t\t * @type {'small'|'normal'|'large'|'full'}\n\t\t */\n\t\tsize: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: 'small',\n\t\t\tvalidator: (value) => typeof value === 'string' && ['small', 'normal', 'large', 'full'].includes(value),\n\t\t},\n\n\t\t/**\n\t\t * Buttons to display\n\t\t * @default []\n\t\t */\n\t\tbuttons: {\n\t\t\ttype: Array,\n\t\t\trequired: false,\n\t\t\tdefault: () => ([]),\n\t\t\tvalidator: (value) => Array.isArray(value) && value.every((element) => typeof element === 'object'),\n\t\t},\n\n\t\t/**\n\t\t * Set to false to no show a close button on the dialog\n\t\t * @default true\n\t\t */\n\t\tcanClose: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Close the dialog if the user clicked outside of the dialog\n\t\t * Only relevant if `canClose` is set to true.\n\t\t */\n\t\tcloseOnClickOutside: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Declare if hiding the modal should be animated\n\t\t * @default false\n\t\t */\n\t\toutTransition: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the navigation for custom styling\n\t\t * @default ''\n\t\t * @example\n\t\t * ```html\n\t\t * <DialogBase :navigation-classes=\"['mydialog-navigation']\"><!-- --></DialogBase>\n\t\t * <!-- ... -->\n\t\t * <style lang=\"scss\">\n\t\t * :deep(.mydialog-navigation) {\n\t\t * flex-direction: row-reverse;\n\t\t * }\n\t\t * </style>\n\t\t * ```\n\t\t */\n\t\tnavigationClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * aria-label for the dialog navigation.\n\t\t * Use it when you want to provide a more meaningful label than the dialog name.\n\t\t *\n\t\t * By default, navigation is labeled by the dialog name.\n\t\t */\n\t\tnavigationAriaLabel: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * aria-labelledby for the dialog navigation.\n\t\t * Use it when you have an implicit navigation label (e.g. a heading).\n\t\t *\n\t\t * By default, navigation is labeled by the dialog name.\n\t\t */\n\t\tnavigationAriaLabelledby: {\n\t\t\ttype: String,\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the content wrapper for custom styling\n\t\t * @default ''\n\t\t */\n\t\tcontentClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Optionally pass additionaly classes which will be set on the dialog itself\n\t\t * (the default `class` attribute will be set on the modal wrapper)\n\t\t * @default ''\n\t\t */\n\t\tdialogClasses: {\n\t\t\ttype: [String, Array, Object],\n\t\t\trequired: false,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['closing', 'update:open'],\n\n\tsetup(props, { emit, slots }) {\n\t\t/**\n\t\t * The dialog wrapper element\n\t\t * @type {import('vue').Ref<HTMLDivElement>}\n\t\t */\n\t\tconst wrapper = ref()\n\n\t\t/**\n\t\t * We use the dialog width to decide if we collapse the navigation (flex direction row)\n\t\t */\n\t\tconst { width: dialogWidth } = useElementSize(wrapper, { width: 900 })\n\n\t\t/**\n\t\t * Whether the navigation is collapsed due to dialog and window size\n\t\t * (collapses when modal is below: 900px modal width - 2x 12px margin)\n\t\t */\n\t\tconst isNavigationCollapsed = computed(() => dialogWidth.value < 876)\n\n\t\t/**\n\t\t * Whether a navigation was passed and the element should be displayed\n\t\t */\n\t\tconst hasNavigation = computed(() => slots?.navigation !== undefined)\n\n\t\t/**\n\t\t * The unique id of the nav element\n\t\t */\n\t\tconst navigationId = ref(GenRandomId())\n\n\t\t/**\n\t\t * aria-label attribute for the nav element\n\t\t */\n\t\tconst navigationAriaLabelAttr = computed(() => props.navigationAriaLabel || undefined)\n\n\t\t/**\n\t\t * aria-labelledby attribute for the nav element\n\t\t */\n\t\tconst navigationAriaLabelledbyAttr = computed(() => {\n\t\t\tif (props.navigationAriaLabel) {\n\t\t\t\t// Not needed, already labelled by aria-label\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\t// Use dialog name as a fallback label for navigation\n\t\t\treturn props.navigationAriaLabelledby || navigationId.value\n\t\t})\n\n\t\t/**\n\t\t * If the underlaying modal is shown\n\t\t */\n\t\tconst showModal = ref(true)\n\n\t\t// Because NcModal does not emit `close` when show prop is changed\n\t\t/**\n\t\t * Handle clicking a dialog button -> should close\n\t\t */\n\t\tconst handleButtonClose = () => {\n\t\t\thandleClosing()\n\t\t\twindow.setTimeout(() => handleClosed(), 300)\n\t\t}\n\n\t\t/**\n\t\t * Handle closing the dialog, optional out transition did not run yet\n\t\t */\n\t\tconst handleClosing = () => {\n\t\t\tshowModal.value = false\n\t\t\t/**\n\t\t\t * Emitted when the dialog is closing, so the out transition did not finish yet\n\t\t\t */\n\t\t\temit('closing')\n\t\t}\n\n\t\t/**\n\t\t * Handle dialog closed (out transition finished)\n\t\t */\n\t\tconst handleClosed = () => {\n\t\t\tshowModal.value = true\n\t\t\t/**\n\t\t\t * Emitted then the dialog is fully closed and the out transition run\n\t\t\t */\n\t\t\temit('update:open', false)\n\t\t}\n\n\t\t/**\n\t\t * Properties to pass to the underlying NcModal\n\t\t */\n\t\tconst modalProps = computed(() => ({\n\t\t\tcanClose: props.canClose,\n\t\t\tcontainer: props.container === undefined ? 'body' : props.container,\n\t\t\t// we do not pass the name as we already have the name as the headline\n\t\t\t// name: props.name,\n\t\t\tsize: props.size,\n\t\t\tshow: props.open && showModal.value,\n\t\t\toutTransition: props.outTransition,\n\t\t\tcloseOnClickOutside: props.closeOnClickOutside,\n\t\t\tadditionalTrapElements: props.additionalTrapElements,\n\t\t}))\n\n\t\treturn {\n\t\t\thandleButtonClose,\n\t\t\thandleClosing,\n\t\t\thandleClosed,\n\t\t\thasNavigation,\n\t\t\tnavigationId,\n\t\t\tnavigationAriaLabelAttr,\n\t\t\tnavigationAriaLabelledbyAttr,\n\t\t\tisNavigationCollapsed,\n\t\t\tmodalProps,\n\t\t\twrapper,\n\t\t}\n\t},\n})\n</script>\n\n<style lang=\"scss\">\n/** When having the small dialog style we override the modal styling so dialogs look more dialog like */\n@media only screen and (max-width: $breakpoint-small-mobile) {\n\t.dialog__modal .modal-wrapper--small .modal-container {\n\t\twidth: fit-content;\n\t\theight: unset;\n\t\tmax-height: 90%;\n\t\tposition: relative;\n\t\ttop: unset;\n\t\tborder-radius: var(--border-radius-large);\n\t}\n}\n</style>\n\n<style lang=\"scss\" scoped>\n.dialog {\n\theight: 100%;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: space-between;\n\toverflow: hidden;\n\n\t&__modal {\n\t\t:deep(.modal-wrapper .modal-container) {\n\t\t\tdisplay: flex !important;\n\t\t\tpadding-block: 4px 0; // 4px to align with close button, 0 block-end to make overflowing content on scroll look nice\n\t\t\tpadding-inline: 12px 0; // Same as with padding-block, we need the actions to have a margin of 4px for the button outline\n\t\t}\n\t\t:deep(.modal-wrapper .modal-container__content) {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\toverflow: hidden; // Only overflow on the .dialog__content\n\t\t}\n\t}\n\n\t&__wrapper {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\t// Auto scale to fit\n\t\tflex: 1;\n\t\tmin-height: 0;\n\t\toverflow: hidden;\n\n\t\t&--collapsed {\n\t\t\tflex-direction: column;\n\t\t}\n\t}\n\n\t&__navigation {\n\t\tdisplay: flex;\n\t\tflex-shrink: 0;\n\t}\n\n\t// Navigation styling when side-by-side with content\n\t&__wrapper:not(&__wrapper--collapsed) &__navigation {\n\t\tflex-direction: column;\n\n\t\toverflow: hidden auto;\n\t\theight: 100%;\n\t\tmin-width: 200px;\n\t\tmargin-inline-end: 20px;\n\t}\n\n\t// Navigation styling when on top of content\n\t&__wrapper#{&}__wrapper--collapsed &__navigation {\n\t\tflex-direction: row;\n\t\tjustify-content: space-between;\n\n\t\toverflow: auto hidden;\n\t\twidth: 100%;\n\t\tmin-width: 100%;\n\t}\n\n\t&__name {\n\t\tfont-size: 21px;\n\n\t\ttext-align: center;\n\t\theight: fit-content;\n\t\tmin-height: var(--default-clickable-area);\n\t\tline-height: var(--default-clickable-area);\n\t\toverflow-wrap: break-word;\n\t\tmargin-block: 0 12px;\n\t}\n\n\t&__content {\n\t\t// Auto fit\n\t\tflex: 1;\n\t\tmin-height: 0;\n\t\toverflow: auto;\n\t\t// see .dialog__modal, we can not set the padding there to prevent floating scroll bars\n\t\tpadding-inline-end: 12px;\n\t}\n\n\t// In case only text content is show\n\t&__text {\n\t\t// Also add padding to the bottom to make it more readable\n\t\tpadding-block-end: 6px;\n\t}\n\n\t&__actions {\n\t\tdisplay: flex;\n\t\tgap: 6px;\n\t\talign-content: center;\n\t\twidth: fit-content;\n\t\tmargin-inline: auto 12px; // 12px to align with the overall modal padding\n\t\tmargin-block: 0;\n\n\t\t&:not(:empty) {\n\t\t\tmargin-block: 6px 12px; // only if there are actions, we add margin so if it is empty scroll content looks nice\n\t\t}\n\t}\n}\n\n@media only screen and (max-width: $breakpoint-small-mobile) {\n\t// Ensure the dialog name does not interfere with the close button\n\t.dialog__name {\n\t\ttext-align: start;\n\t\tmargin-inline-end: var(--default-clickable-area);\n\t}\n}\n</style>\n"],"names":["_sfc_main","defineComponent","NcDialogButton","NcModal","arr","element","value","props","emit","slots","wrapper","ref","dialogWidth","useElementSize","isNavigationCollapsed","computed","hasNavigation","navigationId","GenRandomId","navigationAriaLabelAttr","navigationAriaLabelledbyAttr","showModal","handleButtonClose","handleClosing","handleClosed","modalProps"],"mappings":"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"}
@@ -1,14 +1,14 @@
1
1
  import '../assets/NcEmojiPicker-B-4WNYcx.css';
2
2
  import { Emoji as u, Picker as f, EmojiIndex as p } from "emoji-mart-vue-fast";
3
- import { r as m, u as d, v as h, w as k, a as n } from "./_l10n-Cj65IvRp.mjs";
3
+ import { r as m, u as d, v as h, w as k, a as n } from "./_l10n-BaNxGGXy.mjs";
4
4
  import { g as v, s as _ } from "./emoji-k4gWHxrE.mjs";
5
- import { C as o } from "./GenColors-SRrPRTFN.mjs";
5
+ import { C as o } from "./GenColors-Dceu3ds2.mjs";
6
6
  import y from "emoji-mart-vue-fast/data/all.json";
7
7
  import { n as c } from "./_plugin-vue2_normalizer-Bj5bLKV4.mjs";
8
8
  import g from "../Components/NcButton.mjs";
9
- import { N as S } from "./NcColorPicker-DNGismgl.mjs";
9
+ import { N as S } from "./NcColorPicker-CeoImUTC.mjs";
10
10
  import { N as w } from "./NcPopover--V3R3EKV.mjs";
11
- import { N as C } from "./NcTextField-BPGi70PD.mjs";
11
+ import { N as C } from "./NcTextField-D_eUEl2B.mjs";
12
12
  m(k, h, d);
13
13
  const b = {
14
14
  name: "CircleIcon",
@@ -1 +1 @@
1
- {"version":3,"file":"NcEmojiPicker-B34sLJKs.mjs","sources":["../../node_modules/vue-material-design-icons/Circle.vue","../../src/components/NcEmojiPicker/NcEmojiPicker.vue"],"sourcesContent":["<template>\n <span v-bind=\"$attrs\"\n :aria-hidden=\"title ? null : true\"\n :aria-label=\"title\"\n class=\"material-design-icon circle-icon\"\n role=\"img\"\n @click=\"$emit('click', $event)\">\n <svg :fill=\"fillColor\"\n class=\"material-design-icon__svg\"\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\">\n <path d=\"M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\">\n <title v-if=\"title\">{{ title }}</title>\n </path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: \"CircleIcon\",\n emits: ['click'],\n props: {\n title: {\n type: String,\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n}\n</script>","<!--\n - @copyright Copyright (c) 2020 Georg Ehrke <oc.list@georgehrke.com>\n -\n - @author 2020 Georg Ehrke <oc.list@georgehrke.com>\n -\n - @license GNU AGPL version 3 or any later version\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n### General description\n\nThis component allows the user to pick an emoji.\n\n### Usage\n\n* Listen to the select event and pass in an HTML element that will be treated as a trigger:\n\n```vue\n<template>\n\t<div>\n\t\t<NcEmojiPicker @select=\"select\" style=\"display: inline-block\">\n\t\t\t<NcButton> Click Me </NcButton>\n\t\t</NcEmojiPicker>\n\t\t<span>selected emoji: {{ emoji }}</span>\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\temoji: '',\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tselect(emoji) {\n\t\t\t\tthis.emoji = emoji\n\t\t\t},\n\t\t},\n\t}\n</script>\n```\n\n* Showing a preview and keeping it open after a user selected an emoji\n\n```vue\n<template>\n\t<div>\n\t\t<NcEmojiPicker\n\t\t\t:close-on-select=\"false\"\n\t\t\t:show-preview=\"true\"\n\t\t\t@select=\"select\"\n\t\t\tstyle=\"display: inline-block\">\n\t\t\t<NcButton> Click Me </NcButton>\n\t\t</NcEmojiPicker>\n\t\t<span>selected emoji: {{ emoji }}</span>\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\temoji: '',\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tselect(emoji) {\n\t\t\t\tthis.emoji = emoji\n\t\t\t},\n\t\t},\n\t}\n</script>\n```\n\n* Allow unselecting a previously set emoji.\n\n```vue\n<template>\n\t<div>\n\t\t<NcEmojiPicker\n\t\t\t:show-preview=\"true\"\n\t\t\t:allow-unselect=\"true\"\n\t\t\t:selected-emoji=\"emoji\"\n\t\t\t@select=\"select\"\n\t\t\t@unselect=\"unselect\"\n\t\t\tstyle=\"display: inline-block\">\n\t\t\t<NcButton> Click Me </NcButton>\n\t\t</NcEmojiPicker>\n\t\t<span>selected emoji: {{ emoji }}</span>\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\temoji: '',\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tselect(emoji) {\n\t\t\t\tthis.emoji = emoji\n\t\t\t},\n\t\t\tunselect() {\n\t\t\t\tthis.emoji = ''\n\t\t\t},\n\t\t},\n\t}\n</script>\n```\n\n</docs>\n\n<template>\n\t<NcPopover :shown.sync=\"open\"\n\t\t:container=\"container\"\n\t\tpopup-role=\"dialog\"\n\t\tv-bind=\"$attrs\"\n\t\tv-on=\"$listeners\"\n\t\t@after-show=\"afterShow\"\n\t\t@after-hide=\"afterHide\">\n\t\t<template #trigger=\"slotProps\">\n\t\t\t<slot v-bind=\"slotProps\" />\n\t\t</template>\n\t\t<Picker ref=\"picker\"\n\t\t\t:auto-focus=\"false /* We manage the input focus ourselves */\"\n\t\t\tcolor=\"var(--color-primary-element)\"\n\t\t\t:data=\"emojiIndex\"\n\t\t\t:emoji=\"previewFallbackEmoji\"\n\t\t\t:i18n=\"i18n\"\n\t\t\t:native=\"native\"\n\t\t\t:emoji-size=\"20\"\n\t\t\t:per-line=\"8\"\n\t\t\t:picker-styles=\"{ width: '320px' }\"\n\t\t\t:show-preview=\"showPreview\"\n\t\t\t:skin=\"currentSkinTone\"\n\t\t\t:show-skin-tones=\"false\"\n\t\t\t:title=\"previewFallbackName\"\n\t\t\trole=\"dialog\"\n\t\t\taria-modal=\"true\"\n\t\t\t:aria-label=\"t('Emoji picker')\"\n\t\t\tv-bind=\"$attrs\"\n\t\t\t@select=\"select\">\n\t\t\t<template #searchTemplate=\"slotProps\">\n\t\t\t\t<div class=\"search__wrapper\">\n\t\t\t\t\t<NcTextField ref=\"search\"\n\t\t\t\t\t\tclass=\"search\"\n\t\t\t\t\t\t:value.sync=\"search\"\n\t\t\t\t\t\t:label=\"t('Search')\"\n\t\t\t\t\t\t:label-visible=\"true\"\n\t\t\t\t\t\t:placeholder=\"i18n.search\"\n\t\t\t\t\t\ttrailing-button-icon=\"close\"\n\t\t\t\t\t\t:trailing-button-label=\"t('Clear search')\"\n\t\t\t\t\t\t:show-trailing-button=\"search !== ''\"\n\t\t\t\t\t\t@trailing-button-click=\"clearSearch(); slotProps.onSearch(search);\"\n\t\t\t\t\t\t@update:value=\"slotProps.onSearch(search)\" />\n\t\t\t\t\t<NcColorPicker palette-only\n\t\t\t\t\t\t:container=\"container\"\n\t\t\t\t\t\t:palette=\"skinTonePalette\"\n\t\t\t\t\t\t:value=\"currentColor.color\"\n\t\t\t\t\t\t@update:value=\"onChangeSkinTone\">\n\t\t\t\t\t\t<NcButton :aria-label=\"t('Skin tone')\" type=\"tertiary-no-background\">\n\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t<IconCircle :style=\"{ color: currentColor.color }\" :title=\"currentColor.name\" :size=\"20\" />\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t</NcColorPicker>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t\t<template v-if=\"allowUnselect && selectedEmoji\" #customCategory>\n\t\t\t\t<div class=\"emoji-mart-category-label\">\n\t\t\t\t\t<h3 class=\"emoji-mart-category-label\">\n\t\t\t\t\t\t{{ t('Selected') }}\n\t\t\t\t\t</h3>\n\t\t\t\t</div>\n\t\t\t\t<Emoji class=\"emoji-selected\"\n\t\t\t\t\t:data=\"emojiIndex\"\n\t\t\t\t\t:emoji=\"selectedEmoji\"\n\t\t\t\t\t:native=\"true\"\n\t\t\t\t\t:size=\"32\"\n\t\t\t\t\t@click=\"unselect\" />\n\t\t\t\t<Emoji class=\"emoji-delete\"\n\t\t\t\t\t:data=\"emojiIndex\"\n\t\t\t\t\temoji=\":x:\"\n\t\t\t\t\t:native=\"true\"\n\t\t\t\t\t:size=\"10\"\n\t\t\t\t\t@click=\"unselect\" />\n\t\t\t</template>\n\t\t</Picker>\n\t</NcPopover>\n</template>\n\n<script>\nimport { Picker, Emoji, EmojiIndex } from 'emoji-mart-vue-fast'\nimport { t } from '../../l10n.js'\nimport { getCurrentSkinTone, setCurrentSkinTone } from '../../functions/emoji/emoji.ts'\nimport { Color } from '../../utils/GenColors.js'\n\nimport data from 'emoji-mart-vue-fast/data/all.json'\nimport IconCircle from 'vue-material-design-icons/Circle.vue'\nimport NcButton from '../NcButton/index.js'\nimport NcColorPicker from '../NcColorPicker/NcColorPicker.vue'\nimport NcPopover from '../NcPopover/index.js'\nimport NcTextField from '../NcTextField/index.js'\n\n// Shared emoji index and skinTone for all NcEmojiPicker instances\n// Will be initialized on the first NcEmojiPicker creating\nlet emojiIndex\n\nconst i18n = {\n\tsearch: t('Search emoji'),\n\tnotfound: t('No emoji found'),\n\tcategories: {\n\t\tsearch: t('Search results'),\n\t\trecent: t('Frequently used'),\n\t\tsmileys: t('Smileys & Emotion'),\n\t\tpeople: t('People & Body'),\n\t\tnature: t('Animals & Nature'),\n\t\tfoods: t('Food & Drink'),\n\t\tactivity: t('Activities'),\n\t\tplaces: t('Travel & Places'),\n\t\tobjects: t('Objects'),\n\t\tsymbols: t('Symbols'),\n\t\tflags: t('Flags'),\n\t\tcustom: t('Custom'),\n\t},\n}\n\nconst skinTonePalette = [\n\tnew Color(255, 222, 52, t('Neutral skin color')),\n\tnew Color(228, 205, 166, t('Light skin tone')),\n\tnew Color(250, 221, 192, t('Medium light skin tone')),\n\tnew Color(174, 129, 87, t('Medium skin tone')),\n\tnew Color(158, 113, 88, t('Medium dark skin tone')),\n\tnew Color(96, 79, 69, t('Dark skin tone')),\n]\n\nexport default {\n\tname: 'NcEmojiPicker',\n\n\tcomponents: {\n\t\tEmoji,\n\t\tIconCircle,\n\t\tNcButton,\n\t\tNcColorPicker,\n\t\tNcPopover,\n\t\tNcTextField,\n\t\tPicker,\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The emoji-set\n\t\t */\n\t\tactiveSet: {\n\t\t\ttype: String,\n\t\t\tdefault: 'native',\n\t\t},\n\t\t/**\n\t\t * Show preview section when hovering emoji\n\t\t */\n\t\tshowPreview: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t/**\n\t\t * Allow unselecting the selected emoji\n\t\t */\n\t\tallowUnselect: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t/**\n\t\t * Selected emoji to allow unselecting\n\t\t */\n\t\tselectedEmoji: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t\t/**\n\t\t * The fallback emoji in the preview section\n\t\t */\n\t\tpreviewFallbackEmoji: {\n\t\t\ttype: String,\n\t\t\tdefault: 'grinning',\n\t\t},\n\t\t/**\n\t\t * The fallback text in the preview section\n\t\t */\n\t\tpreviewFallbackName: {\n\t\t\ttype: String,\n\t\t\tdefault: t('Pick an emoji'),\n\t\t},\n\t\t/**\n\t\t * Whether to close the emoji picker after picking one\n\t\t */\n\t\tcloseOnSelect: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Selector for the popover container\n\t\t */\n\t\tcontainer: {\n\t\t\ttype: [String, Object, Element, Boolean],\n\t\t\tdefault: 'body',\n\t\t},\n\t},\n\temits: [\n\t\t'select',\n\t\t'select-data',\n\t\t'unselect',\n\t],\n\n\tsetup() {\n\t\t// If this is the first instance of NcEmojiPicker - setup EmojiIndex\n\t\tif (!emojiIndex) {\n\t\t\temojiIndex = new EmojiIndex(data)\n\t\t}\n\n\t\treturn {\n\t\t\t// Non-reactive constants\n\t\t\temojiIndex,\n\t\t\tskinTonePalette,\n\t\t\ti18n,\n\t\t}\n\t},\n\n\tdata() {\n\t\tconst currentSkinTone = getCurrentSkinTone()\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * The current active color from the skin tone palette\n\t\t\t */\n\t\t\tcurrentColor: skinTonePalette[currentSkinTone - 1],\n\t\t\t/**\n\t\t\t * The current active skin tone\n\t\t\t * @type {1|2|3|4|5|6}\n\t\t\t */\n\t\t\tcurrentSkinTone,\n\t\t\tsearch: '',\n\t\t\topen: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tnative() {\n\t\t\treturn this.activeSet === 'native'\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\tclearSearch() {\n\t\t\tthis.search = ''\n\t\t\tconst input = this.$refs.search?.$refs.inputField?.$refs.input\n\t\t\tif (input) {\n\t\t\t\tinput.focus()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Update the current skin tone by the result of the color picker\n\t\t * @param {string} color Color set\n\t\t */\n\t\tonChangeSkinTone(color) {\n\t\t\tconst index = this.skinTonePalette.findIndex((tone) => tone.color.toLowerCase() === color.toLowerCase())\n\t\t\tif (index > -1) {\n\t\t\t\tthis.currentSkinTone = index + 1\n\t\t\t\tthis.currentColor = this.skinTonePalette[index]\n\t\t\t\tsetCurrentSkinTone(this.currentSkinTone)\n\t\t\t}\n\t\t},\n\n\t\tselect(emojiObject) {\n\t\t\t/**\n\t\t\t * Emits a string containing the emoji e.g. '👩🏿‍💻'\n\t\t\t */\n\t\t\tthis.$emit('select', emojiObject.native)\n\n\t\t\t/**\n\t\t\t * Emits a object with more data about the picked emoji\n\t\t\t */\n\t\t\tthis.$emit('select-data', emojiObject)\n\n\t\t\tif (this.closeOnSelect) {\n\t\t\t\tthis.open = false\n\t\t\t}\n\t\t},\n\n\t\tunselect() {\n\t\t\tthis.$emit('unselect')\n\t\t},\n\n\t\tafterShow() {\n\t\t\t// add focus trap in modal\n\t\t\tconst picker = this.$refs.picker\n\t\t\tpicker.$el.addEventListener('keydown', this.checkKeyEvent)\n\n\t\t\t// set focus on input search field\n\t\t\tconst input = this.$refs.search?.$refs.inputField?.$refs.input\n\t\t\tif (input) {\n\t\t\t\tinput.focus()\n\t\t\t}\n\t\t},\n\n\t\tafterHide() {\n\t\t\t// remove keydown listner if popover is hidden\n\t\t\tconst picker = this.$refs.picker\n\t\t\tpicker.$el.removeEventListener('keydown', this.checkKeyEvent)\n\t\t},\n\n\t\tcheckKeyEvent(event) {\n\t\t\tif (event.key !== 'Tab') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst picker = this.$refs.picker\n\t\t\tconst focusableList = picker.$el.querySelectorAll(\n\t\t\t\t'button, input',\n\t\t\t)\n\t\t\tconst last = focusableList.length - 1\n\t\t\t// escape early if only 1 or no elements to focus\n\t\t\tif (focusableList.length <= 1) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (event.shiftKey === false && event.target === focusableList[last]) {\n\t\t\t\t// Jump to first item when pressing tab on the latest item\n\t\t\t\tevent.preventDefault()\n\t\t\t\tfocusableList[0].focus()\n\t\t\t} else if (event.shiftKey === true && event.target === focusableList[0]) {\n\t\t\t\t// Jump to the last item if pressing shift+tab on the first item\n\t\t\t\tevent.preventDefault()\n\t\t\t\tfocusableList[last].focus()\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style lang=\"scss\">\n@import 'emoji-mart-vue-fast/css/emoji-mart.css';\n\n.emoji-mart {\n\tbackground-color: var(--color-main-background) !important;\n\tborder: 0;\n\tcolor: var(--color-main-text) !important;\n\n\t// default style reset\n\tbutton {\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t\tborder: none;\n\t\tbackground: transparent;\n\t\tfont-size: inherit;\n\t\theight: 36px;\n\t\twidth: auto;\n\n\t\t* {\n\t\t\tcursor: pointer !important;\n\t\t}\n\t}\n\n\t.emoji-mart-bar,\n\t.emoji-mart-anchors,\n\t.emoji-mart-search,\n\t.emoji-mart-search input,\n\t.emoji-mart-category,\n\t.emoji-mart-category-label,\n\t.emoji-mart-category-label span,\n\t.emoji-mart-skin-swatches {\n\t\tbackground-color: transparent !important;\n\t\tborder-color: var(--color-border) !important;\n\t\tcolor: inherit !important;\n\t}\n\n\t.emoji-mart-search input:focus-visible {\n\t\tbox-shadow: inset 0 0 0 2px var(--color-primary-element);\n\t\toutline: none;\n\t}\n\n\t.emoji-mart-bar {\n\t\t&:first-child {\n\t\t\tborder-top-left-radius: var(--border-radius) !important;\n\t\t\tborder-top-right-radius: var(--border-radius) !important;\n\t\t}\n\t}\n\n\t.emoji-mart-anchors {\n\t\tbutton {\n\t\t\tborder-radius: 0;\n\t\t\tpadding: 12px 4px;\n\t\t\theight: auto;\n\t\t\t&:focus-visible {\n\t\t\t\t/* box-shadow: inset 0 0 0 2px var(--color-primary-element); */\n\t\t\t\toutline: 2px solid var(--color-primary-element);\n\t\t\t}\n\t\t}\n\t}\n\n\t.emoji-mart-category {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tflex-wrap: wrap;\n\t\tjustify-content: start;\n\n\t\t.emoji-mart-category-label,\n\t\t.emoji-mart-emoji {\n\t\t\tuser-select: none;\n\t\t\tflex-grow: 0;\n\t\t\tflex-shrink: 0;\n\t\t}\n\n\t\t.emoji-mart-category-label {\n\t\t\tflex-basis: 100%;\n\t\t\tmargin: 0;\n\t\t}\n\n\t\t.emoji-mart-emoji {\n\t\t\t// 8 emoji per row\n\t\t\tflex-basis: calc(100% / 8);\n\t\t\ttext-align: center;\n\n\t\t\t&:hover::before,\n\t\t\t&.emoji-mart-emoji-selected::before{\n\t\t\t\tbackground-color: var(--color-background-hover) !important;\n\t\t\t\toutline: 2px solid var(--color-primary-element);\n\t\t\t}\n\t\t}\n\t\tbutton {\n\n\t\t\t&:focus-visible {\n\t\t\t\tbackground-color: var(--color-background-hover);\n\t\t\t\tborder: 2px solid var(--color-primary-element) !important;\n\t\t\t\tborder-radius: 50%;\n\t\t\t}\n\t\t}\n\t}\n\n}\n</style>\n\n<style scoped lang=\"scss\">\n.search {\n\t&__wrapper {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tgap: 4px; // for focus-visible outlines\n\t\talign-items: end;\n\t\tpadding: 4px 8px;\n\t}\n}\n\n.row-selected {\n\tbutton, span {\n\t\tvertical-align: middle;\n\t}\n}\n\n.emoji-delete {\n\tvertical-align: top;\n\tmargin-left: -21px;\n\tmargin-top: -3px;\n}\n</style>\n"],"names":["_sfc_main","emojiIndex","i18n","t","skinTonePalette","Color","Emoji","IconCircle","NcButton","NcColorPicker","NcPopover","NcTextField","Picker","EmojiIndex","data","currentSkinTone","getCurrentSkinTone","input","_b","_a","color","index","tone","setCurrentSkinTone","emojiObject","event","focusableList","last"],"mappings":";;;;;;;;;;;AAoBA,MAAAA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA,CAAA,OAAA;AAAA,EACA,OAAA;AAAA,IACA,OAAA;AAAA,MACA,MAAA;AAAA,IACA;AAAA,IACA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA,IACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA,EACA;AACA;;;;;;;;;;;;;;;;;ACuLA,IAAAC;AAEA,MAAAC,IAAA;AAAA,EACA,QAAAC,EAAA,cAAA;AAAA,EACA,UAAAA,EAAA,gBAAA;AAAA,EACA,YAAA;AAAA,IACA,QAAAA,EAAA,gBAAA;AAAA,IACA,QAAAA,EAAA,iBAAA;AAAA,IACA,SAAAA,EAAA,mBAAA;AAAA,IACA,QAAAA,EAAA,eAAA;AAAA,IACA,QAAAA,EAAA,kBAAA;AAAA,IACA,OAAAA,EAAA,cAAA;AAAA,IACA,UAAAA,EAAA,YAAA;AAAA,IACA,QAAAA,EAAA,iBAAA;AAAA,IACA,SAAAA,EAAA,SAAA;AAAA,IACA,SAAAA,EAAA,SAAA;AAAA,IACA,OAAAA,EAAA,OAAA;AAAA,IACA,QAAAA,EAAA,QAAA;AAAA,EACA;AACA,GAEAC,IAAA;AAAA,EACA,IAAAC,EAAA,KAAA,KAAA,IAAAF,EAAA,oBAAA,CAAA;AAAA,EACA,IAAAE,EAAA,KAAA,KAAA,KAAAF,EAAA,iBAAA,CAAA;AAAA,EACA,IAAAE,EAAA,KAAA,KAAA,KAAAF,EAAA,wBAAA,CAAA;AAAA,EACA,IAAAE,EAAA,KAAA,KAAA,IAAAF,EAAA,kBAAA,CAAA;AAAA,EACA,IAAAE,EAAA,KAAA,KAAA,IAAAF,EAAA,uBAAA,CAAA;AAAA,EACA,IAAAE,EAAA,IAAA,IAAA,IAAAF,EAAA,gBAAA,CAAA;AACA,GAEAH,IAAA;AAAA,EACA,MAAA;AAAA,EAEA,YAAA;AAAA,IACA,OAAAM;AAAA,IACA,YAAAC;AAAA,IACA,UAAAC;AAAA,IACA,eAAAC;AAAA,IACA,WAAAC;AAAA,IACA,aAAAC;AAAA,IACA,QAAAC;AAAA,EACA;AAAA,EAEA,OAAA;AAAA;AAAA;AAAA;AAAA,IAIA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,aAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,eAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,eAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,sBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,qBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAAT,EAAA,eAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA,eAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,WAAA;AAAA,MACA,MAAA,CAAA,QAAA,QAAA,SAAA,OAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA,EACA;AAAA,EACA,OAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,QAAA;AAEA,WAAAF,MACAA,IAAA,IAAAY,EAAAC,CAAA,IAGA;AAAA;AAAA,MAEA,YAAAb;AAAA,MACA,iBAAAG;AAAA,MACA,MAAAF;AAAA,IACA;AAAA,EACA;AAAA,EAEA,OAAA;AACA,UAAAa,IAAAC,EAAA;AAEA,WAAA;AAAA;AAAA;AAAA;AAAA,MAIA,cAAAZ,EAAAW,IAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKA,iBAAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,UAAA;AAAA,IACA,SAAA;AACA,aAAA,KAAA,cAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,SAAA;AAAA,IACA,GAAAZ;AAAA,IAEA,cAAA;;AACA,WAAA,SAAA;AACA,YAAAc,KAAAC,KAAAC,IAAA,KAAA,MAAA,WAAA,gBAAAA,EAAA,MAAA,eAAA,gBAAAD,EAAA,MAAA;AACA,MAAAD,KACAA,EAAA,MAAA;AAAA,IAEA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,iBAAAG,GAAA;AACA,YAAAC,IAAA,KAAA,gBAAA,UAAA,CAAAC,MAAAA,EAAA,MAAA,YAAA,MAAAF,EAAA,YAAA,CAAA;AACA,MAAAC,IAAA,OACA,KAAA,kBAAAA,IAAA,GACA,KAAA,eAAA,KAAA,gBAAAA,CAAA,GACAE,EAAA,KAAA,eAAA;AAAA,IAEA;AAAA,IAEA,OAAAC,GAAA;AAIA,WAAA,MAAA,UAAAA,EAAA,MAAA,GAKA,KAAA,MAAA,eAAAA,CAAA,GAEA,KAAA,kBACA,KAAA,OAAA;AAAA,IAEA;AAAA,IAEA,WAAA;AACA,WAAA,MAAA,UAAA;AAAA,IACA;AAAA,IAEA,YAAA;;AAGA,MADA,KAAA,MAAA,OACA,IAAA,iBAAA,WAAA,KAAA,aAAA;AAGA,YAAAP,KAAAC,KAAAC,IAAA,KAAA,MAAA,WAAA,gBAAAA,EAAA,MAAA,eAAA,gBAAAD,EAAA,MAAA;AACA,MAAAD,KACAA,EAAA,MAAA;AAAA,IAEA;AAAA,IAEA,YAAA;AAGA,MADA,KAAA,MAAA,OACA,IAAA,oBAAA,WAAA,KAAA,aAAA;AAAA,IACA;AAAA,IAEA,cAAAQ,GAAA;AACA,UAAAA,EAAA,QAAA;AACA;AAGA,YAAAC,IADA,KAAA,MAAA,OACA,IAAA;AAAA,QACA;AAAA,MACA,GACAC,IAAAD,EAAA,SAAA;AAEA,UAAAA,EAAA,UAAA,GAAA;AACA,QAAAD,EAAA,eAAA;AACA;AAAA,MACA;AACA,MAAAA,EAAA,aAAA,MAAAA,EAAA,WAAAC,EAAAC,CAAA,KAEAF,EAAA,eAAA,GACAC,EAAA,CAAA,EAAA,MAAA,KACAD,EAAA,aAAA,MAAAA,EAAA,WAAAC,EAAA,CAAA,MAEAD,EAAA,eAAA,GACAC,EAAAC,CAAA,EAAA,MAAA;AAAA,IAEA;AAAA,EACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"NcEmojiPicker-Cie30NYK.mjs","sources":["../../node_modules/vue-material-design-icons/Circle.vue","../../src/components/NcEmojiPicker/NcEmojiPicker.vue"],"sourcesContent":["<template>\n <span v-bind=\"$attrs\"\n :aria-hidden=\"title ? null : true\"\n :aria-label=\"title\"\n class=\"material-design-icon circle-icon\"\n role=\"img\"\n @click=\"$emit('click', $event)\">\n <svg :fill=\"fillColor\"\n class=\"material-design-icon__svg\"\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\">\n <path d=\"M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\">\n <title v-if=\"title\">{{ title }}</title>\n </path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: \"CircleIcon\",\n emits: ['click'],\n props: {\n title: {\n type: String,\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n}\n</script>","<!--\n - @copyright Copyright (c) 2020 Georg Ehrke <oc.list@georgehrke.com>\n -\n - @author 2020 Georg Ehrke <oc.list@georgehrke.com>\n -\n - @license GNU AGPL version 3 or any later version\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<docs>\n### General description\n\nThis component allows the user to pick an emoji.\n\n### Usage\n\n* Listen to the select event and pass in an HTML element that will be treated as a trigger:\n\n```vue\n<template>\n\t<div>\n\t\t<NcEmojiPicker @select=\"select\" style=\"display: inline-block\">\n\t\t\t<NcButton> Click Me </NcButton>\n\t\t</NcEmojiPicker>\n\t\t<span>selected emoji: {{ emoji }}</span>\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\temoji: '',\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tselect(emoji) {\n\t\t\t\tthis.emoji = emoji\n\t\t\t},\n\t\t},\n\t}\n</script>\n```\n\n* Showing a preview and keeping it open after a user selected an emoji\n\n```vue\n<template>\n\t<div>\n\t\t<NcEmojiPicker\n\t\t\t:close-on-select=\"false\"\n\t\t\t:show-preview=\"true\"\n\t\t\t@select=\"select\"\n\t\t\tstyle=\"display: inline-block\">\n\t\t\t<NcButton> Click Me </NcButton>\n\t\t</NcEmojiPicker>\n\t\t<span>selected emoji: {{ emoji }}</span>\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\temoji: '',\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tselect(emoji) {\n\t\t\t\tthis.emoji = emoji\n\t\t\t},\n\t\t},\n\t}\n</script>\n```\n\n* Allow unselecting a previously set emoji.\n\n```vue\n<template>\n\t<div>\n\t\t<NcEmojiPicker\n\t\t\t:show-preview=\"true\"\n\t\t\t:allow-unselect=\"true\"\n\t\t\t:selected-emoji=\"emoji\"\n\t\t\t@select=\"select\"\n\t\t\t@unselect=\"unselect\"\n\t\t\tstyle=\"display: inline-block\">\n\t\t\t<NcButton> Click Me </NcButton>\n\t\t</NcEmojiPicker>\n\t\t<span>selected emoji: {{ emoji }}</span>\n\t</div>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\temoji: '',\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tselect(emoji) {\n\t\t\t\tthis.emoji = emoji\n\t\t\t},\n\t\t\tunselect() {\n\t\t\t\tthis.emoji = ''\n\t\t\t},\n\t\t},\n\t}\n</script>\n```\n\n</docs>\n\n<template>\n\t<NcPopover :shown.sync=\"open\"\n\t\t:container=\"container\"\n\t\tpopup-role=\"dialog\"\n\t\tv-bind=\"$attrs\"\n\t\tv-on=\"$listeners\"\n\t\t@after-show=\"afterShow\"\n\t\t@after-hide=\"afterHide\">\n\t\t<template #trigger=\"slotProps\">\n\t\t\t<slot v-bind=\"slotProps\" />\n\t\t</template>\n\t\t<Picker ref=\"picker\"\n\t\t\t:auto-focus=\"false /* We manage the input focus ourselves */\"\n\t\t\tcolor=\"var(--color-primary-element)\"\n\t\t\t:data=\"emojiIndex\"\n\t\t\t:emoji=\"previewFallbackEmoji\"\n\t\t\t:i18n=\"i18n\"\n\t\t\t:native=\"native\"\n\t\t\t:emoji-size=\"20\"\n\t\t\t:per-line=\"8\"\n\t\t\t:picker-styles=\"{ width: '320px' }\"\n\t\t\t:show-preview=\"showPreview\"\n\t\t\t:skin=\"currentSkinTone\"\n\t\t\t:show-skin-tones=\"false\"\n\t\t\t:title=\"previewFallbackName\"\n\t\t\trole=\"dialog\"\n\t\t\taria-modal=\"true\"\n\t\t\t:aria-label=\"t('Emoji picker')\"\n\t\t\tv-bind=\"$attrs\"\n\t\t\t@select=\"select\">\n\t\t\t<template #searchTemplate=\"slotProps\">\n\t\t\t\t<div class=\"search__wrapper\">\n\t\t\t\t\t<NcTextField ref=\"search\"\n\t\t\t\t\t\tclass=\"search\"\n\t\t\t\t\t\t:value.sync=\"search\"\n\t\t\t\t\t\t:label=\"t('Search')\"\n\t\t\t\t\t\t:label-visible=\"true\"\n\t\t\t\t\t\t:placeholder=\"i18n.search\"\n\t\t\t\t\t\ttrailing-button-icon=\"close\"\n\t\t\t\t\t\t:trailing-button-label=\"t('Clear search')\"\n\t\t\t\t\t\t:show-trailing-button=\"search !== ''\"\n\t\t\t\t\t\t@trailing-button-click=\"clearSearch(); slotProps.onSearch(search);\"\n\t\t\t\t\t\t@update:value=\"slotProps.onSearch(search)\" />\n\t\t\t\t\t<NcColorPicker palette-only\n\t\t\t\t\t\t:container=\"container\"\n\t\t\t\t\t\t:palette=\"skinTonePalette\"\n\t\t\t\t\t\t:value=\"currentColor.color\"\n\t\t\t\t\t\t@update:value=\"onChangeSkinTone\">\n\t\t\t\t\t\t<NcButton :aria-label=\"t('Skin tone')\" type=\"tertiary-no-background\">\n\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t<IconCircle :style=\"{ color: currentColor.color }\" :title=\"currentColor.name\" :size=\"20\" />\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t</NcColorPicker>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t\t<template v-if=\"allowUnselect && selectedEmoji\" #customCategory>\n\t\t\t\t<div class=\"emoji-mart-category-label\">\n\t\t\t\t\t<h3 class=\"emoji-mart-category-label\">\n\t\t\t\t\t\t{{ t('Selected') }}\n\t\t\t\t\t</h3>\n\t\t\t\t</div>\n\t\t\t\t<Emoji class=\"emoji-selected\"\n\t\t\t\t\t:data=\"emojiIndex\"\n\t\t\t\t\t:emoji=\"selectedEmoji\"\n\t\t\t\t\t:native=\"true\"\n\t\t\t\t\t:size=\"32\"\n\t\t\t\t\t@click=\"unselect\" />\n\t\t\t\t<Emoji class=\"emoji-delete\"\n\t\t\t\t\t:data=\"emojiIndex\"\n\t\t\t\t\temoji=\":x:\"\n\t\t\t\t\t:native=\"true\"\n\t\t\t\t\t:size=\"10\"\n\t\t\t\t\t@click=\"unselect\" />\n\t\t\t</template>\n\t\t</Picker>\n\t</NcPopover>\n</template>\n\n<script>\nimport { Picker, Emoji, EmojiIndex } from 'emoji-mart-vue-fast'\nimport { t } from '../../l10n.js'\nimport { getCurrentSkinTone, setCurrentSkinTone } from '../../functions/emoji/emoji.ts'\nimport { Color } from '../../utils/GenColors.js'\n\nimport data from 'emoji-mart-vue-fast/data/all.json'\nimport IconCircle from 'vue-material-design-icons/Circle.vue'\nimport NcButton from '../NcButton/index.js'\nimport NcColorPicker from '../NcColorPicker/NcColorPicker.vue'\nimport NcPopover from '../NcPopover/index.js'\nimport NcTextField from '../NcTextField/index.js'\n\n// Shared emoji index and skinTone for all NcEmojiPicker instances\n// Will be initialized on the first NcEmojiPicker creating\nlet emojiIndex\n\nconst i18n = {\n\tsearch: t('Search emoji'),\n\tnotfound: t('No emoji found'),\n\tcategories: {\n\t\tsearch: t('Search results'),\n\t\trecent: t('Frequently used'),\n\t\tsmileys: t('Smileys & Emotion'),\n\t\tpeople: t('People & Body'),\n\t\tnature: t('Animals & Nature'),\n\t\tfoods: t('Food & Drink'),\n\t\tactivity: t('Activities'),\n\t\tplaces: t('Travel & Places'),\n\t\tobjects: t('Objects'),\n\t\tsymbols: t('Symbols'),\n\t\tflags: t('Flags'),\n\t\tcustom: t('Custom'),\n\t},\n}\n\nconst skinTonePalette = [\n\tnew Color(255, 222, 52, t('Neutral skin color')),\n\tnew Color(228, 205, 166, t('Light skin tone')),\n\tnew Color(250, 221, 192, t('Medium light skin tone')),\n\tnew Color(174, 129, 87, t('Medium skin tone')),\n\tnew Color(158, 113, 88, t('Medium dark skin tone')),\n\tnew Color(96, 79, 69, t('Dark skin tone')),\n]\n\nexport default {\n\tname: 'NcEmojiPicker',\n\n\tcomponents: {\n\t\tEmoji,\n\t\tIconCircle,\n\t\tNcButton,\n\t\tNcColorPicker,\n\t\tNcPopover,\n\t\tNcTextField,\n\t\tPicker,\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The emoji-set\n\t\t */\n\t\tactiveSet: {\n\t\t\ttype: String,\n\t\t\tdefault: 'native',\n\t\t},\n\t\t/**\n\t\t * Show preview section when hovering emoji\n\t\t */\n\t\tshowPreview: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t/**\n\t\t * Allow unselecting the selected emoji\n\t\t */\n\t\tallowUnselect: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t/**\n\t\t * Selected emoji to allow unselecting\n\t\t */\n\t\tselectedEmoji: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t\t/**\n\t\t * The fallback emoji in the preview section\n\t\t */\n\t\tpreviewFallbackEmoji: {\n\t\t\ttype: String,\n\t\t\tdefault: 'grinning',\n\t\t},\n\t\t/**\n\t\t * The fallback text in the preview section\n\t\t */\n\t\tpreviewFallbackName: {\n\t\t\ttype: String,\n\t\t\tdefault: t('Pick an emoji'),\n\t\t},\n\t\t/**\n\t\t * Whether to close the emoji picker after picking one\n\t\t */\n\t\tcloseOnSelect: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Selector for the popover container\n\t\t */\n\t\tcontainer: {\n\t\t\ttype: [String, Object, Element, Boolean],\n\t\t\tdefault: 'body',\n\t\t},\n\t},\n\temits: [\n\t\t'select',\n\t\t'select-data',\n\t\t'unselect',\n\t],\n\n\tsetup() {\n\t\t// If this is the first instance of NcEmojiPicker - setup EmojiIndex\n\t\tif (!emojiIndex) {\n\t\t\temojiIndex = new EmojiIndex(data)\n\t\t}\n\n\t\treturn {\n\t\t\t// Non-reactive constants\n\t\t\temojiIndex,\n\t\t\tskinTonePalette,\n\t\t\ti18n,\n\t\t}\n\t},\n\n\tdata() {\n\t\tconst currentSkinTone = getCurrentSkinTone()\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * The current active color from the skin tone palette\n\t\t\t */\n\t\t\tcurrentColor: skinTonePalette[currentSkinTone - 1],\n\t\t\t/**\n\t\t\t * The current active skin tone\n\t\t\t * @type {1|2|3|4|5|6}\n\t\t\t */\n\t\t\tcurrentSkinTone,\n\t\t\tsearch: '',\n\t\t\topen: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tnative() {\n\t\t\treturn this.activeSet === 'native'\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\tclearSearch() {\n\t\t\tthis.search = ''\n\t\t\tconst input = this.$refs.search?.$refs.inputField?.$refs.input\n\t\t\tif (input) {\n\t\t\t\tinput.focus()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Update the current skin tone by the result of the color picker\n\t\t * @param {string} color Color set\n\t\t */\n\t\tonChangeSkinTone(color) {\n\t\t\tconst index = this.skinTonePalette.findIndex((tone) => tone.color.toLowerCase() === color.toLowerCase())\n\t\t\tif (index > -1) {\n\t\t\t\tthis.currentSkinTone = index + 1\n\t\t\t\tthis.currentColor = this.skinTonePalette[index]\n\t\t\t\tsetCurrentSkinTone(this.currentSkinTone)\n\t\t\t}\n\t\t},\n\n\t\tselect(emojiObject) {\n\t\t\t/**\n\t\t\t * Emits a string containing the emoji e.g. '👩🏿‍💻'\n\t\t\t */\n\t\t\tthis.$emit('select', emojiObject.native)\n\n\t\t\t/**\n\t\t\t * Emits a object with more data about the picked emoji\n\t\t\t */\n\t\t\tthis.$emit('select-data', emojiObject)\n\n\t\t\tif (this.closeOnSelect) {\n\t\t\t\tthis.open = false\n\t\t\t}\n\t\t},\n\n\t\tunselect() {\n\t\t\tthis.$emit('unselect')\n\t\t},\n\n\t\tafterShow() {\n\t\t\t// add focus trap in modal\n\t\t\tconst picker = this.$refs.picker\n\t\t\tpicker.$el.addEventListener('keydown', this.checkKeyEvent)\n\n\t\t\t// set focus on input search field\n\t\t\tconst input = this.$refs.search?.$refs.inputField?.$refs.input\n\t\t\tif (input) {\n\t\t\t\tinput.focus()\n\t\t\t}\n\t\t},\n\n\t\tafterHide() {\n\t\t\t// remove keydown listner if popover is hidden\n\t\t\tconst picker = this.$refs.picker\n\t\t\tpicker.$el.removeEventListener('keydown', this.checkKeyEvent)\n\t\t},\n\n\t\tcheckKeyEvent(event) {\n\t\t\tif (event.key !== 'Tab') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst picker = this.$refs.picker\n\t\t\tconst focusableList = picker.$el.querySelectorAll(\n\t\t\t\t'button, input',\n\t\t\t)\n\t\t\tconst last = focusableList.length - 1\n\t\t\t// escape early if only 1 or no elements to focus\n\t\t\tif (focusableList.length <= 1) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (event.shiftKey === false && event.target === focusableList[last]) {\n\t\t\t\t// Jump to first item when pressing tab on the latest item\n\t\t\t\tevent.preventDefault()\n\t\t\t\tfocusableList[0].focus()\n\t\t\t} else if (event.shiftKey === true && event.target === focusableList[0]) {\n\t\t\t\t// Jump to the last item if pressing shift+tab on the first item\n\t\t\t\tevent.preventDefault()\n\t\t\t\tfocusableList[last].focus()\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style lang=\"scss\">\n@import 'emoji-mart-vue-fast/css/emoji-mart.css';\n\n.emoji-mart {\n\tbackground-color: var(--color-main-background) !important;\n\tborder: 0;\n\tcolor: var(--color-main-text) !important;\n\n\t// default style reset\n\tbutton {\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t\tborder: none;\n\t\tbackground: transparent;\n\t\tfont-size: inherit;\n\t\theight: 36px;\n\t\twidth: auto;\n\n\t\t* {\n\t\t\tcursor: pointer !important;\n\t\t}\n\t}\n\n\t.emoji-mart-bar,\n\t.emoji-mart-anchors,\n\t.emoji-mart-search,\n\t.emoji-mart-search input,\n\t.emoji-mart-category,\n\t.emoji-mart-category-label,\n\t.emoji-mart-category-label span,\n\t.emoji-mart-skin-swatches {\n\t\tbackground-color: transparent !important;\n\t\tborder-color: var(--color-border) !important;\n\t\tcolor: inherit !important;\n\t}\n\n\t.emoji-mart-search input:focus-visible {\n\t\tbox-shadow: inset 0 0 0 2px var(--color-primary-element);\n\t\toutline: none;\n\t}\n\n\t.emoji-mart-bar {\n\t\t&:first-child {\n\t\t\tborder-top-left-radius: var(--border-radius) !important;\n\t\t\tborder-top-right-radius: var(--border-radius) !important;\n\t\t}\n\t}\n\n\t.emoji-mart-anchors {\n\t\tbutton {\n\t\t\tborder-radius: 0;\n\t\t\tpadding: 12px 4px;\n\t\t\theight: auto;\n\t\t\t&:focus-visible {\n\t\t\t\t/* box-shadow: inset 0 0 0 2px var(--color-primary-element); */\n\t\t\t\toutline: 2px solid var(--color-primary-element);\n\t\t\t}\n\t\t}\n\t}\n\n\t.emoji-mart-category {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tflex-wrap: wrap;\n\t\tjustify-content: start;\n\n\t\t.emoji-mart-category-label,\n\t\t.emoji-mart-emoji {\n\t\t\tuser-select: none;\n\t\t\tflex-grow: 0;\n\t\t\tflex-shrink: 0;\n\t\t}\n\n\t\t.emoji-mart-category-label {\n\t\t\tflex-basis: 100%;\n\t\t\tmargin: 0;\n\t\t}\n\n\t\t.emoji-mart-emoji {\n\t\t\t// 8 emoji per row\n\t\t\tflex-basis: calc(100% / 8);\n\t\t\ttext-align: center;\n\n\t\t\t&:hover::before,\n\t\t\t&.emoji-mart-emoji-selected::before{\n\t\t\t\tbackground-color: var(--color-background-hover) !important;\n\t\t\t\toutline: 2px solid var(--color-primary-element);\n\t\t\t}\n\t\t}\n\t\tbutton {\n\n\t\t\t&:focus-visible {\n\t\t\t\tbackground-color: var(--color-background-hover);\n\t\t\t\tborder: 2px solid var(--color-primary-element) !important;\n\t\t\t\tborder-radius: 50%;\n\t\t\t}\n\t\t}\n\t}\n\n}\n</style>\n\n<style scoped lang=\"scss\">\n.search {\n\t&__wrapper {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tgap: 4px; // for focus-visible outlines\n\t\talign-items: end;\n\t\tpadding: 4px 8px;\n\t}\n}\n\n.row-selected {\n\tbutton, span {\n\t\tvertical-align: middle;\n\t}\n}\n\n.emoji-delete {\n\tvertical-align: top;\n\tmargin-left: -21px;\n\tmargin-top: -3px;\n}\n</style>\n"],"names":["_sfc_main","emojiIndex","i18n","t","skinTonePalette","Color","Emoji","IconCircle","NcButton","NcColorPicker","NcPopover","NcTextField","Picker","EmojiIndex","data","currentSkinTone","getCurrentSkinTone","input","_b","_a","color","index","tone","setCurrentSkinTone","emojiObject","event","focusableList","last"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,6 +1,6 @@
1
1
  require('../assets/NcEmojiPicker-B-4WNYcx.css');
2
2
  "use strict";
3
- const l = require("emoji-mart-vue-fast"), n = require("./_l10n-BG5lXDmm.cjs"), c = require("./emoji-DEH9dtOa.cjs"), o = require("./GenColors-BCHzPRPI.cjs"), p = require("emoji-mart-vue-fast/data/all.json"), f = require("./_plugin-vue2_normalizer-GXKvuwrq.cjs"), d = require("../Components/NcButton.cjs"), m = require("./NcColorPicker-D0rQKQAy.cjs"), h = require("./NcPopover-h-t7Dnjk.cjs"), k = require("./NcTextField-DgzR5_48.cjs"), _ = (r) => r && r.__esModule ? r : { default: r }, v = /* @__PURE__ */ _(p);
3
+ const l = require("emoji-mart-vue-fast"), n = require("./_l10n-B8iumFKB.cjs"), c = require("./emoji-DEH9dtOa.cjs"), o = require("./GenColors-hkqGpnOK.cjs"), p = require("emoji-mart-vue-fast/data/all.json"), f = require("./_plugin-vue2_normalizer-GXKvuwrq.cjs"), d = require("../Components/NcButton.cjs"), m = require("./NcColorPicker-DOcxlY35.cjs"), h = require("./NcPopover-h-t7Dnjk.cjs"), k = require("./NcTextField-B5cUYgRy.cjs"), _ = (r) => r && r.__esModule ? r : { default: r }, v = /* @__PURE__ */ _(p);
4
4
  n.register(n.t6, n.t31, n.t36);
5
5
  const y = {
6
6
  name: "CircleIcon",