@witchcraft/ui 0.0.1

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 (315) hide show
  1. package/README.md +236 -0
  2. package/dist/module.cjs +5 -0
  3. package/dist/module.d.mts +34 -0
  4. package/dist/module.d.ts +34 -0
  5. package/dist/module.json +9 -0
  6. package/dist/module.mjs +124 -0
  7. package/dist/runtime/assets/base.css +1 -0
  8. package/dist/runtime/assets/locales/en.json +33 -0
  9. package/dist/runtime/assets/style.css +1 -0
  10. package/dist/runtime/assets/tailwind.css +1 -0
  11. package/dist/runtime/assets/theme.css +1 -0
  12. package/dist/runtime/build/WitchcraftUiResolver.d.ts +5 -0
  13. package/dist/runtime/build/WitchcraftUiResolver.js +17 -0
  14. package/dist/runtime/build/generateTheme.d.ts +1 -0
  15. package/dist/runtime/build/generateTheme.js +14 -0
  16. package/dist/runtime/build/unpluginIconViteOptions.d.ts +2 -0
  17. package/dist/runtime/build/unpluginIconViteOptions.js +10 -0
  18. package/dist/runtime/components/Aria/Aria.vue +18 -0
  19. package/dist/runtime/components/Focus.stories.d.ts +11 -0
  20. package/dist/runtime/components/Focus.stories.js +53 -0
  21. package/dist/runtime/components/Icon/Icon.vue +39 -0
  22. package/dist/runtime/components/LibButton/LibButton.stories.d.ts +12 -0
  23. package/dist/runtime/components/LibButton/LibButton.stories.js +94 -0
  24. package/dist/runtime/components/LibButton/LibButton.vue +247 -0
  25. package/dist/runtime/components/LibCheckbox/LibCheckbox.stories.d.ts +14 -0
  26. package/dist/runtime/components/LibCheckbox/LibCheckbox.stories.js +29 -0
  27. package/dist/runtime/components/LibCheckbox/LibCheckbox.vue +132 -0
  28. package/dist/runtime/components/LibColorInput/LibColorInput.stories.d.ts +7 -0
  29. package/dist/runtime/components/LibColorInput/LibColorInput.stories.js +58 -0
  30. package/dist/runtime/components/LibColorInput/LibColorInput.vue +125 -0
  31. package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.d.ts +7 -0
  32. package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.js +51 -0
  33. package/dist/runtime/components/LibColorPicker/LibColorPicker.vue +448 -0
  34. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.d.ts +7 -0
  35. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.js +36 -0
  36. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +95 -0
  37. package/dist/runtime/components/LibDatePicker/LibDatePicker.stories.d.ts +11 -0
  38. package/dist/runtime/components/LibDatePicker/LibDatePicker.stories.js +98 -0
  39. package/dist/runtime/components/LibDatePicker/LibDatePicker.vue +67 -0
  40. package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue +370 -0
  41. package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue +314 -0
  42. package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue +27 -0
  43. package/dist/runtime/components/LibDatePicker/helpers.d.ts +25 -0
  44. package/dist/runtime/components/LibDatePicker/helpers.js +28 -0
  45. package/dist/runtime/components/LibDebug/LibDebug.stories.d.ts +9 -0
  46. package/dist/runtime/components/LibDebug/LibDebug.stories.js +46 -0
  47. package/dist/runtime/components/LibDebug/LibDebug.vue +91 -0
  48. package/dist/runtime/components/LibDevOnly/LibDevOnly.vue +53 -0
  49. package/dist/runtime/components/LibFileInput/LibFileInput.stories.d.ts +10 -0
  50. package/dist/runtime/components/LibFileInput/LibFileInput.stories.js +63 -0
  51. package/dist/runtime/components/LibFileInput/LibFileInput.vue +273 -0
  52. package/dist/runtime/components/LibInput/LibInput.stories.d.ts +33 -0
  53. package/dist/runtime/components/LibInput/LibInput.stories.js +339 -0
  54. package/dist/runtime/components/LibInput/LibInput.vue +372 -0
  55. package/dist/runtime/components/LibLabel/LibLabel.stories.d.ts +6 -0
  56. package/dist/runtime/components/LibLabel/LibLabel.stories.js +25 -0
  57. package/dist/runtime/components/LibLabel/LibLabel.vue +66 -0
  58. package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.d.ts +23 -0
  59. package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.js +60 -0
  60. package/dist/runtime/components/LibMultiValues/LibMultiValues.vue +127 -0
  61. package/dist/runtime/components/LibNotifications/LibNotification.stories.d.ts +15 -0
  62. package/dist/runtime/components/LibNotifications/LibNotification.stories.js +126 -0
  63. package/dist/runtime/components/LibNotifications/LibNotification.vue +121 -0
  64. package/dist/runtime/components/LibNotifications/LibNotifications.stories.d.ts +6 -0
  65. package/dist/runtime/components/LibNotifications/LibNotifications.stories.js +109 -0
  66. package/dist/runtime/components/LibNotifications/LibNotifications.vue +133 -0
  67. package/dist/runtime/components/LibPagination/LibPagination.stories.d.ts +6 -0
  68. package/dist/runtime/components/LibPagination/LibPagination.stories.js +40 -0
  69. package/dist/runtime/components/LibPagination/LibPagination.vue +261 -0
  70. package/dist/runtime/components/LibPalette/LibPalette.stories.d.ts +6 -0
  71. package/dist/runtime/components/LibPalette/LibPalette.stories.js +20 -0
  72. package/dist/runtime/components/LibPalette/LibPalette.vue +49 -0
  73. package/dist/runtime/components/LibPopup/LibPopup.stories.d.ts +14 -0
  74. package/dist/runtime/components/LibPopup/LibPopup.stories.js +147 -0
  75. package/dist/runtime/components/LibPopup/LibPopup.vue +441 -0
  76. package/dist/runtime/components/LibProgressBar/LibProgressBar.stories.d.ts +10 -0
  77. package/dist/runtime/components/LibProgressBar/LibProgressBar.stories.js +81 -0
  78. package/dist/runtime/components/LibProgressBar/LibProgressBar.vue +192 -0
  79. package/dist/runtime/components/LibRecorder/LibRecorder.stories.d.ts +19 -0
  80. package/dist/runtime/components/LibRecorder/LibRecorder.stories.js +63 -0
  81. package/dist/runtime/components/LibRecorder/LibRecorder.vue +243 -0
  82. package/dist/runtime/components/LibRoot/LibRoot.vue +126 -0
  83. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.stories.d.ts +26 -0
  84. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.stories.js +78 -0
  85. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue +148 -0
  86. package/dist/runtime/components/LibSuggestions/LibSuggestions.stories.d.ts +27 -0
  87. package/dist/runtime/components/LibSuggestions/LibSuggestions.stories.js +112 -0
  88. package/dist/runtime/components/LibSuggestions/LibSuggestions.vue +198 -0
  89. package/dist/runtime/components/LibTable/LibTable.stories.d.ts +16 -0
  90. package/dist/runtime/components/LibTable/LibTable.stories.js +156 -0
  91. package/dist/runtime/components/LibTable/LibTable.vue +177 -0
  92. package/dist/runtime/components/Template/NAME.vue +49 -0
  93. package/dist/runtime/components/Template/TemplateStory.d.ts +7 -0
  94. package/dist/runtime/components/Template/TemplateStory.js +22 -0
  95. package/dist/runtime/components/TestControls/TestControls.vue +19 -0
  96. package/dist/runtime/components/index.d.ts +19 -0
  97. package/dist/runtime/components/index.js +19 -0
  98. package/dist/runtime/components/reset.stories.d.ts +5 -0
  99. package/dist/runtime/components/reset.stories.js +19 -0
  100. package/dist/runtime/components/shared/props.d.ts +135 -0
  101. package/dist/runtime/components/shared/props.js +14 -0
  102. package/dist/runtime/components/shared/storyHelpers/playInput.d.ts +8 -0
  103. package/dist/runtime/components/shared/storyHelpers/playInput.js +26 -0
  104. package/dist/runtime/components/shared/storyHelpers/playSuggestions.d.ts +12 -0
  105. package/dist/runtime/components/shared/storyHelpers/playSuggestions.js +83 -0
  106. package/dist/runtime/composables/index.d.ts +11 -0
  107. package/dist/runtime/composables/index.js +11 -0
  108. package/dist/runtime/composables/useAccesibilityOutline.d.ts +41 -0
  109. package/dist/runtime/composables/useAccesibilityOutline.js +58 -0
  110. package/dist/runtime/composables/useAriaLabel.d.ts +6 -0
  111. package/dist/runtime/composables/useAriaLabel.js +15 -0
  112. package/dist/runtime/composables/useDarkMode.d.ts +38 -0
  113. package/dist/runtime/composables/useDarkMode.js +79 -0
  114. package/dist/runtime/composables/useDivideAttrs.d.ts +27 -0
  115. package/dist/runtime/composables/useDivideAttrs.js +26 -0
  116. package/dist/runtime/composables/useGlobalResizeObserver.d.ts +3 -0
  117. package/dist/runtime/composables/useGlobalResizeObserver.js +28 -0
  118. package/dist/runtime/composables/useInjectedDarkMode.d.ts +2 -0
  119. package/dist/runtime/composables/useInjectedDarkMode.js +13 -0
  120. package/dist/runtime/composables/useInjectedI18n.d.ts +2 -0
  121. package/dist/runtime/composables/useInjectedI18n.js +7 -0
  122. package/dist/runtime/composables/useInjectedLocale.d.ts +2 -0
  123. package/dist/runtime/composables/useInjectedLocale.js +21 -0
  124. package/dist/runtime/composables/useNotificationHandler.d.ts +4 -0
  125. package/dist/runtime/composables/useNotificationHandler.js +21 -0
  126. package/dist/runtime/composables/useScrollNearContainerEdges.d.ts +68 -0
  127. package/dist/runtime/composables/useScrollNearContainerEdges.js +116 -0
  128. package/dist/runtime/composables/useScrollNearContainerEdges.stories.d.ts +7 -0
  129. package/dist/runtime/composables/useScrollNearContainerEdges.stories.js +85 -0
  130. package/dist/runtime/composables/useSetupDarkMode.d.ts +12 -0
  131. package/dist/runtime/composables/useSetupDarkMode.js +4 -0
  132. package/dist/runtime/composables/useSetupI18n.d.ts +20 -0
  133. package/dist/runtime/composables/useSetupI18n.js +50 -0
  134. package/dist/runtime/composables/useSetupLocale.d.ts +9 -0
  135. package/dist/runtime/composables/useSetupLocale.js +21 -0
  136. package/dist/runtime/composables/useShowDevOnlyKey.d.ts +7 -0
  137. package/dist/runtime/composables/useShowDevOnlyKey.js +20 -0
  138. package/dist/runtime/composables/useSuggestions.d.ts +38 -0
  139. package/dist/runtime/composables/useSuggestions.js +226 -0
  140. package/dist/runtime/directives/index.d.ts +4 -0
  141. package/dist/runtime/directives/index.js +4 -0
  142. package/dist/runtime/directives/vDetectFlex.d.ts +2 -0
  143. package/dist/runtime/directives/vDetectFlex.js +109 -0
  144. package/dist/runtime/directives/vExtractRootEl.d.ts +22 -0
  145. package/dist/runtime/directives/vExtractRootEl.js +13 -0
  146. package/dist/runtime/directives/vResizableCols.d.ts +60 -0
  147. package/dist/runtime/directives/vResizableCols.js +252 -0
  148. package/dist/runtime/directives/vResizeObserver.d.ts +2 -0
  149. package/dist/runtime/directives/vResizeObserver.js +34 -0
  150. package/dist/runtime/globalResizeObserver.d.ts +5 -0
  151. package/dist/runtime/globalResizeObserver.js +5 -0
  152. package/dist/runtime/helpers/NotificationHandler.d.ts +48 -0
  153. package/dist/runtime/helpers/NotificationHandler.js +162 -0
  154. package/dist/runtime/helpers/addValue.d.ts +1 -0
  155. package/dist/runtime/helpers/addValue.js +8 -0
  156. package/dist/runtime/helpers/base64ToImg.d.ts +1 -0
  157. package/dist/runtime/helpers/base64ToImg.js +11 -0
  158. package/dist/runtime/helpers/copy.d.ts +1 -0
  159. package/dist/runtime/helpers/copy.js +10 -0
  160. package/dist/runtime/helpers/createNoonUtcDate.d.ts +7 -0
  161. package/dist/runtime/helpers/createNoonUtcDate.js +14 -0
  162. package/dist/runtime/helpers/defaultTranslationFunction.d.ts +16 -0
  163. package/dist/runtime/helpers/defaultTranslationFunction.js +14 -0
  164. package/dist/runtime/helpers/getTimeZoneList.d.ts +1 -0
  165. package/dist/runtime/helpers/getTimeZoneList.js +3 -0
  166. package/dist/runtime/helpers/hasModifiers.d.ts +1 -0
  167. package/dist/runtime/helpers/hasModifiers.js +1 -0
  168. package/dist/runtime/helpers/index.d.ts +8 -0
  169. package/dist/runtime/helpers/index.js +8 -0
  170. package/dist/runtime/helpers/readFile.d.ts +1 -0
  171. package/dist/runtime/helpers/readFile.js +13 -0
  172. package/dist/runtime/helpers/resizeObserverWrapper.d.ts +8 -0
  173. package/dist/runtime/helpers/resizeObserverWrapper.js +37 -0
  174. package/dist/runtime/helpers/storybook.d.ts +7 -0
  175. package/dist/runtime/helpers/storybook.js +42 -0
  176. package/dist/runtime/main.lib.d.ts +26 -0
  177. package/dist/runtime/main.lib.js +8 -0
  178. package/dist/runtime/nuxt/plugins/vue-plugin.d.ts +2 -0
  179. package/dist/runtime/nuxt/plugins/vue-plugin.js +12 -0
  180. package/dist/runtime/tailwind/index.d.ts +1 -0
  181. package/dist/runtime/tailwind/index.js +1 -0
  182. package/dist/runtime/tailwind/themeConvertionOpts.d.ts +2 -0
  183. package/dist/runtime/tailwind/themeConvertionOpts.js +12 -0
  184. package/dist/runtime/theme.d.ts +2 -0
  185. package/dist/runtime/theme.js +2 -0
  186. package/dist/runtime/types/index.d.ts +119 -0
  187. package/dist/runtime/types/index.js +0 -0
  188. package/dist/runtime/utils/twMerge.d.ts +10 -0
  189. package/dist/runtime/utils/twMerge.js +10 -0
  190. package/dist/runtime/vue/VueComponentsPlugin.d.ts +2 -0
  191. package/dist/runtime/vue/VueComponentsPlugin.js +10 -0
  192. package/dist/runtime/vue/registerComponents.d.ts +19 -0
  193. package/dist/runtime/vue/registerComponents.js +10 -0
  194. package/dist/runtime/vue/registerDirectives.d.ts +3 -0
  195. package/dist/runtime/vue/registerDirectives.js +9 -0
  196. package/dist/types.d.mts +7 -0
  197. package/dist/types.d.ts +7 -0
  198. package/package.json +207 -0
  199. package/src/module.ts +176 -0
  200. package/src/runtime/assets/base.css +67 -0
  201. package/src/runtime/assets/locales/en.json +33 -0
  202. package/src/runtime/assets/style.css +144 -0
  203. package/src/runtime/assets/tailwind.css +5 -0
  204. package/src/runtime/assets/theme.css +65 -0
  205. package/src/runtime/build/WitchcraftUiResolver.ts +27 -0
  206. package/src/runtime/build/generateTheme.ts +16 -0
  207. package/src/runtime/build/unpluginIconViteOptions.ts +11 -0
  208. package/src/runtime/components/Aria/Aria.vue +27 -0
  209. package/src/runtime/components/Focus.stories.ts +67 -0
  210. package/src/runtime/components/Icon/Icon.vue +39 -0
  211. package/src/runtime/components/LibButton/LibButton.stories.ts +107 -0
  212. package/src/runtime/components/LibButton/LibButton.vue +247 -0
  213. package/src/runtime/components/LibCheckbox/LibCheckbox.stories.ts +41 -0
  214. package/src/runtime/components/LibCheckbox/LibCheckbox.vue +132 -0
  215. package/src/runtime/components/LibColorInput/LibColorInput.stories.ts +69 -0
  216. package/src/runtime/components/LibColorInput/LibColorInput.vue +125 -0
  217. package/src/runtime/components/LibColorPicker/LibColorPicker.stories.ts +60 -0
  218. package/src/runtime/components/LibColorPicker/LibColorPicker.vue +448 -0
  219. package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.ts +51 -0
  220. package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +95 -0
  221. package/src/runtime/components/LibDatePicker/LibDatePicker.stories.ts +114 -0
  222. package/src/runtime/components/LibDatePicker/LibDatePicker.vue +67 -0
  223. package/src/runtime/components/LibDatePicker/LibRangeDatePicker.vue +370 -0
  224. package/src/runtime/components/LibDatePicker/LibSingleDatePicker.vue +314 -0
  225. package/src/runtime/components/LibDatePicker/LibTimeZonePicker.vue +27 -0
  226. package/src/runtime/components/LibDatePicker/helpers.ts +55 -0
  227. package/src/runtime/components/LibDebug/LibDebug.stories.ts +58 -0
  228. package/src/runtime/components/LibDebug/LibDebug.vue +91 -0
  229. package/src/runtime/components/LibDevOnly/LibDevOnly.vue +53 -0
  230. package/src/runtime/components/LibFileInput/LibFileInput.stories.ts +79 -0
  231. package/src/runtime/components/LibFileInput/LibFileInput.vue +273 -0
  232. package/src/runtime/components/LibInput/LibInput.stories.ts +367 -0
  233. package/src/runtime/components/LibInput/LibInput.vue +372 -0
  234. package/src/runtime/components/LibLabel/LibLabel.stories.ts +37 -0
  235. package/src/runtime/components/LibLabel/LibLabel.vue +66 -0
  236. package/src/runtime/components/LibMultiValues/LibMultiValues.stories.ts +83 -0
  237. package/src/runtime/components/LibMultiValues/LibMultiValues.vue +127 -0
  238. package/src/runtime/components/LibNotifications/LibNotification.stories.ts +142 -0
  239. package/src/runtime/components/LibNotifications/LibNotification.vue +121 -0
  240. package/src/runtime/components/LibNotifications/LibNotifications.stories.ts +124 -0
  241. package/src/runtime/components/LibNotifications/LibNotifications.vue +133 -0
  242. package/src/runtime/components/LibPagination/LibPagination.stories.ts +53 -0
  243. package/src/runtime/components/LibPagination/LibPagination.vue +261 -0
  244. package/src/runtime/components/LibPalette/LibPalette.stories.ts +32 -0
  245. package/src/runtime/components/LibPalette/LibPalette.vue +49 -0
  246. package/src/runtime/components/LibPopup/LibPopup.stories.ts +157 -0
  247. package/src/runtime/components/LibPopup/LibPopup.vue +441 -0
  248. package/src/runtime/components/LibProgressBar/LibProgressBar.stories.ts +94 -0
  249. package/src/runtime/components/LibProgressBar/LibProgressBar.vue +192 -0
  250. package/src/runtime/components/LibRecorder/LibRecorder.stories.ts +81 -0
  251. package/src/runtime/components/LibRecorder/LibRecorder.vue +243 -0
  252. package/src/runtime/components/LibRoot/LibRoot.vue +126 -0
  253. package/src/runtime/components/LibSimpleInput/LibSimpleInput.stories.ts +98 -0
  254. package/src/runtime/components/LibSimpleInput/LibSimpleInput.vue +148 -0
  255. package/src/runtime/components/LibSuggestions/LibSuggestions.stories.ts +137 -0
  256. package/src/runtime/components/LibSuggestions/LibSuggestions.vue +198 -0
  257. package/src/runtime/components/LibTable/LibTable.stories.ts +170 -0
  258. package/src/runtime/components/LibTable/LibTable.vue +177 -0
  259. package/src/runtime/components/Template/NAME.vue +49 -0
  260. package/src/runtime/components/Template/TemplateStory.ts +38 -0
  261. package/src/runtime/components/TestControls/TestControls.vue +19 -0
  262. package/src/runtime/components/index.ts +22 -0
  263. package/src/runtime/components/reset.stories.ts +32 -0
  264. package/src/runtime/components/shared/props.ts +142 -0
  265. package/src/runtime/components/shared/storyHelpers/playInput.ts +35 -0
  266. package/src/runtime/components/shared/storyHelpers/playSuggestions.ts +105 -0
  267. package/src/runtime/composables/index.ts +13 -0
  268. package/src/runtime/composables/useAccesibilityOutline.ts +104 -0
  269. package/src/runtime/composables/useAriaLabel.ts +23 -0
  270. package/src/runtime/composables/useDarkMode.ts +146 -0
  271. package/src/runtime/composables/useDivideAttrs.ts +52 -0
  272. package/src/runtime/composables/useGlobalResizeObserver.ts +33 -0
  273. package/src/runtime/composables/useInjectedDarkMode.ts +15 -0
  274. package/src/runtime/composables/useInjectedI18n.ts +10 -0
  275. package/src/runtime/composables/useInjectedLocale.ts +24 -0
  276. package/src/runtime/composables/useNotificationHandler.ts +32 -0
  277. package/src/runtime/composables/useScrollNearContainerEdges.stories.ts +93 -0
  278. package/src/runtime/composables/useScrollNearContainerEdges.ts +205 -0
  279. package/src/runtime/composables/useSetupDarkMode.ts +14 -0
  280. package/src/runtime/composables/useSetupI18n.ts +77 -0
  281. package/src/runtime/composables/useSetupLocale.ts +32 -0
  282. package/src/runtime/composables/useShowDevOnlyKey.ts +28 -0
  283. package/src/runtime/composables/useSuggestions.ts +297 -0
  284. package/src/runtime/directives/index.ts +6 -0
  285. package/src/runtime/directives/vDetectFlex.ts +159 -0
  286. package/src/runtime/directives/vExtractRootEl.ts +38 -0
  287. package/src/runtime/directives/vResizableCols.ts +378 -0
  288. package/src/runtime/directives/vResizeObserver.ts +45 -0
  289. package/src/runtime/globalResizeObserver.ts +12 -0
  290. package/src/runtime/helpers/NotificationHandler.ts +227 -0
  291. package/src/runtime/helpers/addValue.ts +10 -0
  292. package/src/runtime/helpers/base64ToImg.ts +14 -0
  293. package/src/runtime/helpers/copy.ts +11 -0
  294. package/src/runtime/helpers/createNoonUtcDate.ts +21 -0
  295. package/src/runtime/helpers/defaultTranslationFunction.ts +33 -0
  296. package/src/runtime/helpers/getTimeZoneList.ts +4 -0
  297. package/src/runtime/helpers/hasModifiers.ts +1 -0
  298. package/src/runtime/helpers/index.ts +10 -0
  299. package/src/runtime/helpers/readFile.ts +22 -0
  300. package/src/runtime/helpers/resizeObserverWrapper.ts +45 -0
  301. package/src/runtime/helpers/storybook.ts +52 -0
  302. package/src/runtime/main.lib.ts +31 -0
  303. package/src/runtime/nuxt/plugins/vue-plugin.ts +19 -0
  304. package/src/runtime/tailwind/index.ts +3 -0
  305. package/src/runtime/tailwind/themeConvertionOpts.ts +15 -0
  306. package/src/runtime/theme.ts +5 -0
  307. package/src/runtime/types/index.ts +116 -0
  308. package/src/runtime/utils/twMerge.ts +13 -0
  309. package/src/runtime/vue/VueComponentsPlugin.ts +16 -0
  310. package/src/runtime/vue/registerComponents.ts +31 -0
  311. package/src/runtime/vue/registerDirectives.ts +12 -0
  312. package/types/components.d.ts +27 -0
  313. package/types/global.d.ts +16 -0
  314. package/types/index.d.ts +5 -0
  315. package/types/vite.d.ts +2 -0
@@ -0,0 +1,109 @@
1
+ import { castType } from "@alanscodelog/utils/castType.js";
2
+ import { last } from "@alanscodelog/utils/last.js";
3
+ import { throttle } from "@alanscodelog/utils/throttle.js";
4
+ import { unreachable } from "@alanscodelog/utils/unreachable.js";
5
+ import { globalResizeObserver } from "../globalResizeObserver.js";
6
+ const observer = globalResizeObserver;
7
+ const callbacks = {};
8
+ const elMap = /* @__PURE__ */ new WeakMap();
9
+ function getOrCreateCallback(throttleTime) {
10
+ if (callbacks[throttleTime]) {
11
+ callbacks[throttleTime].count++;
12
+ } else {
13
+ callbacks[throttleTime] = { count: 1, callback: throttle(callback, throttleTime) };
14
+ }
15
+ return callbacks[throttleTime].callback;
16
+ }
17
+ function removeCallback(throttleTime) {
18
+ if (callbacks[throttleTime]) {
19
+ callbacks[throttleTime].count--;
20
+ if (callbacks[throttleTime].count === 0) delete callbacks[throttleTime];
21
+ }
22
+ }
23
+ function callback(_rect, el) {
24
+ const _ = elMap.get(el);
25
+ if (!_) {
26
+ unreachable();
27
+ }
28
+ const pos = _.vertical ? "x" : "y";
29
+ const dimension = _.vertical ? "width" : "height";
30
+ castType(el);
31
+ const filteredChildren = Array.from(el.children).filter((child) => _.ignoreSelector && !child.matches(_.ignoreSelector));
32
+ const firstChild = filteredChildren[0];
33
+ const lastChild = last(filteredChildren);
34
+ if (firstChild === void 0 || firstChild === lastChild) {
35
+ console.warn("detect-flex directive detected there are less than two child elements.");
36
+ console.warn(el);
37
+ el.classList.remove("wrapped");
38
+ return;
39
+ }
40
+ const firstRect = firstChild.getBoundingClientRect();
41
+ const lastRect = lastChild.getBoundingClientRect();
42
+ if (Math.round(10 * (firstRect[pos] + firstRect[dimension] - lastRect[pos])) * 10 <= 0) {
43
+ el.classList.add("wrapped");
44
+ } else {
45
+ el.classList.remove("wrapped");
46
+ }
47
+ }
48
+ export const vDetectFlex = {
49
+ mounted(el, { value: { condition = true, vertical = false, throttleTime = 50, ignoreSelector = ".detect-flex-ignore" } = {} }) {
50
+ const _ = {
51
+ vertical,
52
+ lastCondition: condition,
53
+ lastThrottleTime: throttleTime,
54
+ ignoreSelector
55
+ };
56
+ elMap.set(el, _);
57
+ if (condition) {
58
+ _.callback = getOrCreateCallback(throttleTime);
59
+ observer.observe(el, _.callback);
60
+ }
61
+ },
62
+ updated(el, { value: { condition = true, vertical = false, throttleTime = 50, ignoreSelector = ".detect-flex-ignore" } = {} }) {
63
+ const _ = elMap.get(el);
64
+ if (!_) {
65
+ unreachable();
66
+ }
67
+ _.vertical = vertical;
68
+ _.ignoreSelector = ignoreSelector;
69
+ if (throttleTime !== _.lastThrottleTime) {
70
+ if (condition && _.lastCondition) {
71
+ if (!_.callback) unreachable();
72
+ observer.unobserve(el, _.callback);
73
+ removeCallback(_.lastThrottleTime);
74
+ _.callback = getOrCreateCallback(throttleTime);
75
+ observer.observe(el, _.callback);
76
+ }
77
+ _.lastThrottleTime = throttleTime;
78
+ }
79
+ if (condition !== _.lastCondition) {
80
+ _.lastCondition = condition;
81
+ if (condition) {
82
+ _.callback = getOrCreateCallback(throttleTime);
83
+ observer.observe(el, _.callback);
84
+ } else {
85
+ if (!_.callback) unreachable();
86
+ observer.unobserve(el, _.callback);
87
+ removeCallback(throttleTime);
88
+ _.callback = void 0;
89
+ }
90
+ }
91
+ },
92
+ unmounted(el, { value: { vertical = false, throttleTime = 50, ignoreSelector = ".detect-flex-ignore" } = {} }) {
93
+ const _ = elMap.get(el);
94
+ if (!_) {
95
+ unreachable();
96
+ }
97
+ _.vertical = vertical;
98
+ _.ignoreSelector = ignoreSelector;
99
+ _.lastThrottleTime = throttleTime;
100
+ if (_.lastCondition) {
101
+ if (!_.callback) unreachable();
102
+ observer.unobserve(el, _.callback);
103
+ _.callback = void 0;
104
+ }
105
+ },
106
+ getSSRProps() {
107
+ return {};
108
+ }
109
+ };
@@ -0,0 +1,22 @@
1
+ import type { Directive } from "vue";
2
+ /**
3
+ * Vue 3 no longer allows extracting the root element from a component.
4
+ *
5
+ * This allows us to extract it via a callback.
6
+ *
7
+ * Note the callback will be called on mount/unmount to keep the value up to date and make it null if the element disappears.
8
+ *
9
+ * One can create a ref:
10
+ * ```ts
11
+ * import { vExtractRootEl } from "@witchcraft/ui/directives/vExtractRootEl.js"
12
+ * const el = ref<HTMLElement|null>(null)
13
+ *
14
+ * ```
15
+ * Then in the template
16
+ * ```vue
17
+ * <SomeComponent v-extract-root-el="_ => el = _" />
18
+ * ```
19
+ *
20
+ * Currently only tested with single root elements.
21
+ */
22
+ export declare const vExtractRootEl: Directive;
@@ -0,0 +1,13 @@
1
+ export const vExtractRootEl = {
2
+ // @ts-expect-error for registering properly without doing complicated case conversion
3
+ directiveName: "extract-root-el",
4
+ mounted(el, { value: callback }) {
5
+ callback(el);
6
+ },
7
+ unmounted(_el, { value: callback }) {
8
+ callback(null);
9
+ },
10
+ getSSRProps() {
11
+ return {};
12
+ }
13
+ };
@@ -0,0 +1,60 @@
1
+ import type { Directive } from "vue";
2
+ /**
3
+ * Allow a table like element to be resized along it's columns.
4
+ *
5
+ * ```vue
6
+ * <template>
7
+ * <div v-resizable-cols="opts">
8
+ * <!---->
9
+ * </div>
10
+ * </template>
11
+ * <script setup>
12
+ * import {vResizeCols} from "@witchcraft/ui/directives/vResizableCols.js"
13
+ * </script>
14
+ * ```
15
+ *
16
+ * This assumes the following:
17
+ * - The `.grip` element the directive adds for each column is styled with at least some width.
18
+ * - The containing element must not have any borders. Use a wrapper if you need them.
19
+ *
20
+ * This will set the following styles on the elements:
21
+ *
22
+ * ```css
23
+ * el {
24
+ * min-width: [opts.minWidth * col #] // only if needed, see margin and fitWidth options
25
+ * min-width: min-content; // if fitWidth: false
26
+ * .grip {
27
+ * position: absolute;
28
+ * top: 0;
29
+ * bottom: 0;
30
+ * cursor: col-resize;
31
+ * }
32
+ * [cells] {
33
+ * none
34
+ * }
35
+ * }
36
+ * ```
37
+ * Note that they aren't removed if the directive is disabled.
38
+ *
39
+ * It does NOT set the widths on the cells. It used to, but for maximum flexibility a ref with an array should be passed to be populated by the widths calculated.
40
+ *
41
+ * Additionally the following are suggested:
42
+ * - If fitWidth is true, `overflow: hidden` should be set on the column elements to avoid glitches when dragging the last column near the right edge.
43
+ * - The root element should have `overflow-x:scroll` even if `fitWidth` is true, since there is some minimum space (margin+grip * col) the element will always occupy.
44
+ *
45
+ * The directive also adds a class after the initial setup `resizable-cols-setup`. This is useful to set initial column widths, for example, using flexboxes, then removing those styles when the element is setup. You can also check if the passed widths array is still of 0 length.
46
+ *
47
+ * ```css
48
+ * el:not(.resizable-cols-setup) {
49
+ * initial styles
50
+ * }
51
+ * ```
52
+ *
53
+ * You can prevent columns from being resized by adding the class `no-resize`. When a column cannot be moved, the `resizable-cols-error` class is added to the element.
54
+ *
55
+ * Also note the `.grip` element added is added to the root element. This is so you can have `overflow:hidden` on cells if you want without the grip getting hidden. But this does mean that if you're styling the cells using `:last-child`, to, for example, target table rows, won't work, you'll need `:last-of-type`.
56
+ *
57
+ * # Options
58
+ * See {@link ResizableOptions}
59
+ */
60
+ export declare const vResizableCols: Directive;
@@ -0,0 +1,252 @@
1
+ import { castType } from "@alanscodelog/utils/castType.js";
2
+ import { override } from "@alanscodelog/utils/override.js";
3
+ import { throttle } from "@alanscodelog/utils/throttle.js";
4
+ import { unreachable } from "@alanscodelog/utils/unreachable.js";
5
+ import { globalResizeObserver } from "../globalResizeObserver.js";
6
+ const observer = globalResizeObserver;
7
+ const elMap = /* @__PURE__ */ new WeakMap();
8
+ const defaultOpts = {
9
+ fitWidth: true,
10
+ margin: "dynamic",
11
+ enabled: true
12
+ };
13
+ const callback = (_rect, el) => {
14
+ setColWidths(el);
15
+ positionGrips(el);
16
+ };
17
+ const throttledCallback = throttle(callback);
18
+ export const vResizableCols = {
19
+ mounted(el, { value: opts = {} }) {
20
+ const options = override({ ...defaultOpts }, opts);
21
+ if (options.enabled) {
22
+ setupColumns(el, options);
23
+ observer.observe(el, throttledCallback);
24
+ }
25
+ },
26
+ updated(el, { value: opts = {} }) {
27
+ const options = override({ ...defaultOpts }, opts);
28
+ const info = el && getElInfo(el);
29
+ const hasGrips = el && elMap.get(el).grips;
30
+ const colsNotEqual = info && info.colCount !== options.colCount;
31
+ if (hasGrips && !options.enabled || colsNotEqual) {
32
+ teardownColumns(el);
33
+ observer.unobserve(el, throttledCallback);
34
+ }
35
+ if (!hasGrips && options.enabled || colsNotEqual) {
36
+ setupColumns(el, options);
37
+ observer.observe(el, throttledCallback);
38
+ }
39
+ },
40
+ unmounted(el) {
41
+ const hasGrips = elMap.has(el) && elMap.get(el).grips;
42
+ if (hasGrips) {
43
+ teardownColumns(el);
44
+ globalResizeObserver.unobserve(el, throttledCallback);
45
+ }
46
+ },
47
+ getSSRProps() {
48
+ return {};
49
+ }
50
+ };
51
+ const setWidth = (col, amountInPx, el) => {
52
+ const $el = getElInfo(el);
53
+ const width = Math.max($el.margin, amountInPx);
54
+ const index = getColEls(el).findIndex((_) => col === _);
55
+ if ($el.fitWidth) {
56
+ $el.widths.value[index] = `${width / getBox(el).width * 100}%`;
57
+ } else {
58
+ $el.widths.value[index] = `${width}px`;
59
+ }
60
+ };
61
+ const getBox = (el) => {
62
+ const rect = el.getBoundingClientRect();
63
+ return { x: Math.round(rect.x), width: Math.round(rect.width) };
64
+ };
65
+ const getCols = (el) => {
66
+ const $el = getElInfo(el);
67
+ if (!$el.target) unreachable();
68
+ let col = getColEls(el)[$el.grips.get($el.target)];
69
+ if (!col) unreachable();
70
+ while (col?.classList.contains("no-resize")) {
71
+ col = col?.previousElementSibling ?? null;
72
+ }
73
+ let colNext = col?.nextElementSibling ?? null;
74
+ if ($el.fitWidth) {
75
+ while (colNext?.classList.contains("no-resize")) {
76
+ colNext = colNext?.nextElementSibling ?? null;
77
+ }
78
+ }
79
+ return { col, colNext };
80
+ };
81
+ const createPointerDownHandler = (el) => (e) => {
82
+ const $el = getElInfo(el);
83
+ if (!$el.isDragging) {
84
+ castType(e.target);
85
+ $el.target = e.target;
86
+ $el.isDragging = true;
87
+ e.preventDefault();
88
+ document.addEventListener("pointerup", $el.pointerUpHandler);
89
+ const { col, colNext } = getCols(el);
90
+ if (col === null || colNext === null) {
91
+ el.classList.add("resizable-cols-error");
92
+ } else {
93
+ document.addEventListener("pointermove", $el.pointerMoveHandler);
94
+ const box = getBox(col);
95
+ if (box) {
96
+ $el.offset = e.pageX - (box.x + box.width);
97
+ }
98
+ }
99
+ }
100
+ };
101
+ const createPointerMoveHandler = (el) => (e) => {
102
+ const $el = getElInfo(el);
103
+ if ($el.isDragging) {
104
+ e.preventDefault();
105
+ const { col, colNext } = getCols(el);
106
+ if (col !== null) {
107
+ const leftBox = getBox(col);
108
+ const oldWidth = leftBox.width;
109
+ const leftBound = leftBox.x;
110
+ const rightBox = colNext ? getBox(colNext) : getBox(el);
111
+ const rightBound = rightBox.x + rightBox.width;
112
+ const margin = $el.margin;
113
+ const pos = e.pageX - $el.offset;
114
+ if ($el.fitWidth) {
115
+ if (pos > leftBound + margin && pos < rightBound - margin) {
116
+ const newWidth = pos - leftBound;
117
+ const diff = oldWidth - newWidth;
118
+ if (rightBox.width + diff < margin) {
119
+ el.classList.add("resizable-cols-error");
120
+ return;
121
+ }
122
+ setWidth(col, newWidth, el);
123
+ setWidth(colNext, rightBox.width + diff, el);
124
+ }
125
+ } else {
126
+ if (pos > leftBound + margin) {
127
+ const newWidth = pos - leftBound;
128
+ setWidth(col, newWidth, el);
129
+ }
130
+ }
131
+ positionGrips(el);
132
+ }
133
+ }
134
+ };
135
+ const createPointerUpHandler = (el) => (e) => {
136
+ const $el = getElInfo(el);
137
+ if ($el.isDragging) {
138
+ e.preventDefault();
139
+ $el.isDragging = false;
140
+ el.classList.remove("resizable-cols-error");
141
+ $el.offset = 0;
142
+ delete $el.target;
143
+ document.removeEventListener("pointermove", $el.pointerMoveHandler);
144
+ document.removeEventListener("pointerup", $el.pointerUpHandler);
145
+ document.removeEventListener("pointerleave", $el.pointerLeaveHandler);
146
+ }
147
+ };
148
+ const createGrip = () => {
149
+ const grip = document.createElement("div");
150
+ grip.style.position = "absolute";
151
+ grip.style.cursor = "col-resize";
152
+ grip.style.top = "0";
153
+ grip.style.bottom = "0";
154
+ grip.classList.add("grip");
155
+ return grip;
156
+ };
157
+ const removeGrips = (el) => {
158
+ const grips = Array.from(el.querySelectorAll(".grip") ?? []);
159
+ for (const grip of grips) {
160
+ el.removeChild(grip);
161
+ }
162
+ };
163
+ const getTestGripSize = (el) => {
164
+ const testGrip = createGrip();
165
+ el.appendChild(testGrip);
166
+ const dynamicMinWidth = getBox(testGrip).width * 3;
167
+ el.removeChild(testGrip);
168
+ return dynamicMinWidth;
169
+ };
170
+ const getElInfo = (el) => {
171
+ const $el = elMap.get(el);
172
+ if (!$el) unreachable("El went missing.");
173
+ return $el;
174
+ };
175
+ const getColEls = (el) => {
176
+ const $el = elMap.get(el);
177
+ if (!$el) unreachable("El went missing.");
178
+ return [...el.querySelectorAll(`:scope ${$el.selector ? $el.selector : "tr > td"}`)];
179
+ };
180
+ const setupColumns = (el, opts) => {
181
+ const gripWidth = getTestGripSize(el);
182
+ const $el = {
183
+ grips: /* @__PURE__ */ new Map(),
184
+ isDragging: false,
185
+ pointerDownHandler: createPointerDownHandler(el),
186
+ pointerMoveHandler: createPointerMoveHandler(el),
187
+ pointerUpHandler: createPointerUpHandler(el),
188
+ pointerLeaveHandler: createPointerUpHandler(el),
189
+ fitWidth: opts.fitWidth,
190
+ margin: opts.margin === "dynamic" ? gripWidth : opts.margin,
191
+ colCount: opts.colCount,
192
+ widths: opts.widths,
193
+ selector: opts.selector
194
+ };
195
+ elMap.set(el, $el);
196
+ const els = getColEls(el);
197
+ const headers = els.slice(0, opts.colCount);
198
+ setColWidths(el, headers);
199
+ el.style.width = $el.fitWidth ? "" : "min-content";
200
+ const len = opts.colCount;
201
+ for (let i = 0; i < len; i++) {
202
+ if (opts.fitWidth && i === len - 1) continue;
203
+ const grip = createGrip();
204
+ grip.addEventListener("pointerdown", $el.pointerDownHandler);
205
+ el.appendChild(grip);
206
+ $el.grips.set(grip, i);
207
+ }
208
+ positionGrips(el);
209
+ el.classList.add("resizable-cols-setup");
210
+ };
211
+ const positionGrips = (el) => {
212
+ let xPos = 0;
213
+ const $el = getElInfo(el);
214
+ for (const grip of $el.grips.keys()) {
215
+ const col = $el.grips.get(grip);
216
+ const colBox = getBox(getColEls(el)[col]);
217
+ const gripBox = getBox(grip);
218
+ grip.style.left = `${xPos + colBox.width - gripBox.width / 2}px`;
219
+ xPos += colBox.width;
220
+ }
221
+ };
222
+ const setColWidths = (el, children) => {
223
+ const $el = getElInfo(el);
224
+ const header = children ?? getColEls(el).slice(0, $el.colCount);
225
+ const len = $el.colCount;
226
+ let width = 0;
227
+ const minTotalWidth = len * $el.margin;
228
+ for (let i = 0; i < len; i++) {
229
+ const col = header[i];
230
+ castType(col);
231
+ const colBox = getBox(col);
232
+ setWidth(col, colBox.width, el);
233
+ width += getBox(col).width;
234
+ }
235
+ if (width < minTotalWidth) {
236
+ el.style.minWidth = `${minTotalWidth}px`;
237
+ } else {
238
+ el.style.minWidth = "";
239
+ }
240
+ };
241
+ const teardownColumns = (el) => {
242
+ const $el = getElInfo(el);
243
+ el.removeEventListener("pointerdown", $el.pointerDownHandler);
244
+ document.removeEventListener("pointermove", $el.pointerMoveHandler);
245
+ document.removeEventListener("pointerup", $el.pointerUpHandler);
246
+ for (const key of Object.keys($el)) {
247
+ delete $el[key];
248
+ }
249
+ elMap.delete(el);
250
+ el.classList.remove("resizable-cols-setup");
251
+ removeGrips(el);
252
+ };
@@ -0,0 +1,2 @@
1
+ import type { Directive } from "vue";
2
+ export declare const vResizeObserver: Directive;
@@ -0,0 +1,34 @@
1
+ import { globalResizeObserver } from "../globalResizeObserver.js";
2
+ const observer = globalResizeObserver;
3
+ const lastCondition = Symbol("lastCondition");
4
+ const checkCallback = (cb) => {
5
+ if (cb === void 0) {
6
+ throw new Error("No callback function passed to resize observer directive.");
7
+ }
8
+ };
9
+ export const vResizeObserver = {
10
+ mounted(el, { value: { condition = true, callback } }) {
11
+ if (condition) {
12
+ observer.observe(el, callback);
13
+ }
14
+ checkCallback(callback);
15
+ },
16
+ updated(el, { value: { condition = true, callback } }) {
17
+ if (condition !== el[lastCondition]) {
18
+ el[lastCondition] = condition;
19
+ if (condition) {
20
+ observer.observe(el, callback);
21
+ } else {
22
+ observer.unobserve(el, callback);
23
+ }
24
+ }
25
+ checkCallback(callback);
26
+ },
27
+ unmounted(el, { value: { callback } }) {
28
+ observer.unobserve(el, callback);
29
+ delete el[lastCondition];
30
+ },
31
+ getSSRProps() {
32
+ return {};
33
+ }
34
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * This is not inside helpers to avoid having it get dragged in by an import of /helpers.
3
+ */
4
+ import { ResizeObserverWrapper } from "./helpers/resizeObserverWrapper.js.js";
5
+ export declare const globalResizeObserver: ResizeObserverWrapper;
@@ -0,0 +1,5 @@
1
+ import { ResizeObserverWrapper } from "./helpers/resizeObserverWrapper.js";
2
+ if (typeof ResizeObserver === "undefined") {
3
+ console.warn("You are using a directive that uses a ResizeObserver or are importing something that uses this resize observer in a context (e.g. the server) where ResizeObserver does not exist.");
4
+ }
5
+ export const globalResizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserverWrapper() : {};
@@ -0,0 +1,48 @@
1
+ import type { AnyFunction, MakeRequired } from "@alanscodelog/utils";
2
+ export declare class NotificationHandler<TRawEntry extends RawNotificationEntry<any, any> = RawNotificationEntry<any, any>, TEntry extends NotificationEntry<TRawEntry> = NotificationEntry<TRawEntry>> {
3
+ timeout: number;
4
+ debug: boolean;
5
+ private id;
6
+ readonly queue: TEntry[];
7
+ readonly history: TEntry[];
8
+ maxHistory: number;
9
+ listeners: NotificationListener<TEntry>[];
10
+ stringifier?: NotificationStringifier<TEntry>;
11
+ constructor({ timeout, stringifier, maxHistory, }?: {
12
+ timeout?: NotificationHandler<TRawEntry>["timeout"];
13
+ stringifier?: NotificationHandler<TRawEntry>["stringifier"];
14
+ maxHistory?: NotificationHandler<TRawEntry>["maxHistory"];
15
+ });
16
+ private _checkEntry;
17
+ protected _createEntry<TNotifyEntry extends RawNotificationEntry<any, any>>(rawEntry: TNotifyEntry): TEntry;
18
+ notify<TNotifyEntry extends RawNotificationEntry<any, any>>(rawEntry: TNotifyEntry): NotificationPromise<TNotifyEntry["options"][number] extends string ? TNotifyEntry["options"][number] : "Ok" | "Cancel">;
19
+ static resolveToDefault(notification: NotificationEntry): void;
20
+ static dismiss(notification: NotificationEntry): void;
21
+ stringify(notification: NotificationEntry): string;
22
+ clear(): void;
23
+ addNotificationListener(cb: NotificationListener<TEntry>): void;
24
+ removeNotificationListener(cb: NotificationListener<TEntry>): void;
25
+ }
26
+ export type NotificationPromise<TOption extends string = string> = Promise<TOption>;
27
+ export type RawNotificationEntry<TOptions extends string[] = ["Ok", "Cancel"], TCancellable extends boolean | TOptions[number] = "Cancel"> = {
28
+ message: string;
29
+ title?: string;
30
+ code?: string;
31
+ options?: TOptions;
32
+ requiresAction?: boolean;
33
+ cancellable?: TCancellable;
34
+ default?: TOptions[number];
35
+ dangerous?: TOptions[number][];
36
+ timeout?: number | boolean;
37
+ icon?: string;
38
+ };
39
+ export type NotificationEntry<TRawEntry extends RawNotificationEntry<any, any> = RawNotificationEntry<any, any>> = Omit<MakeRequired<TRawEntry, "options" | "requiresAction" | "default" | "dangerous">, "cancellable"> & {
40
+ promise: NotificationPromise;
41
+ resolve: AnyFunction;
42
+ cancellable?: string;
43
+ timeout?: number;
44
+ resolution?: string;
45
+ id: number;
46
+ };
47
+ export type NotificationListener<TEntry extends NotificationEntry<any>> = (notification: TEntry, type: "added" | "resolved" | "deleted") => void;
48
+ export type NotificationStringifier<T extends NotificationEntry<any>> = (notification: T) => string;