@pictogrammers/components 0.3.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 (379) hide show
  1. package/@types/css.d.ts +4 -0
  2. package/@types/html.d.ts +4 -0
  3. package/README.md +49 -0
  4. package/dist/main.js +3819 -0
  5. package/dist/pgAnnoy.js +116 -0
  6. package/dist/pgAvatar.js +136 -0
  7. package/dist/pgButton.js +116 -0
  8. package/dist/pgButtonGroup.js +116 -0
  9. package/dist/pgButtonLink.js +116 -0
  10. package/dist/pgButtonToggle.js +146 -0
  11. package/dist/pgCard.js +116 -0
  12. package/dist/pgCardUser.js +196 -0
  13. package/dist/pgColor.js +136 -0
  14. package/dist/pgDatabase.js +236 -0
  15. package/dist/pgDropdown.js +686 -0
  16. package/dist/pgGrid.js +126 -0
  17. package/dist/pgHeader.js +116 -0
  18. package/dist/pgIcon.js +116 -0
  19. package/dist/pgInputCheck.js +116 -0
  20. package/dist/pgInputCheckList.js +126 -0
  21. package/dist/pgInputFileLocal.js +116 -0
  22. package/dist/pgInputHexRgb.js +126 -0
  23. package/dist/pgInputRange.js +116 -0
  24. package/dist/pgInputSelect.js +116 -0
  25. package/dist/pgInputText.js +116 -0
  26. package/dist/pgInputTextIcon.js +176 -0
  27. package/dist/pgInputUserSelect.js +116 -0
  28. package/dist/pgListTag.js +136 -0
  29. package/dist/pgMarkdown.js +346 -0
  30. package/dist/pgMenuIcon.js +206 -0
  31. package/dist/pgModalAlert.js +126 -0
  32. package/dist/pgModification.js +396 -0
  33. package/dist/pgNav.js +116 -0
  34. package/dist/pgOverlay.js +96 -0
  35. package/dist/pgPicker.js +116 -0
  36. package/dist/pgPreview.js +116 -0
  37. package/dist/pgScroll.js +266 -0
  38. package/dist/pgSearch.js +146 -0
  39. package/dist/pgTab.js +116 -0
  40. package/dist/pgTabs.js +136 -0
  41. package/dist/pgToast.js +136 -0
  42. package/dist/pgToasts.js +136 -0
  43. package/dist/pgTooltip.js +126 -0
  44. package/index.html +302 -0
  45. package/package.json +25 -0
  46. package/pg/annoy/README.md +18 -0
  47. package/pg/annoy/__examples__/basic/basic.html +8 -0
  48. package/pg/annoy/__examples__/basic/basic.ts +11 -0
  49. package/pg/annoy/annoy.css +238 -0
  50. package/pg/annoy/annoy.html +59 -0
  51. package/pg/annoy/annoy.ts +48 -0
  52. package/pg/annoy/index.ts +3 -0
  53. package/pg/avatar/README.md +23 -0
  54. package/pg/avatar/__examples__/basic/basic.html +6 -0
  55. package/pg/avatar/__examples__/basic/basic.ts +41 -0
  56. package/pg/avatar/__examples__/basic/constants.ts +1 -0
  57. package/pg/avatar/avatar.css +45 -0
  58. package/pg/avatar/avatar.html +8 -0
  59. package/pg/avatar/avatar.spec.ts +51 -0
  60. package/pg/avatar/avatar.ts +37 -0
  61. package/pg/avatar/index.ts +3 -0
  62. package/pg/button/README.md +51 -0
  63. package/pg/button/__examples__/basic/basic.html +11 -0
  64. package/pg/button/__examples__/basic/basic.ts +11 -0
  65. package/pg/button/__examples__/states/states.html +8 -0
  66. package/pg/button/__examples__/states/states.ts +20 -0
  67. package/pg/button/button.css +91 -0
  68. package/pg/button/button.html +3 -0
  69. package/pg/button/button.ts +45 -0
  70. package/pg/button/index.ts +3 -0
  71. package/pg/buttonGroup/README.md +28 -0
  72. package/pg/buttonGroup/__examples__/basic/basic.html +12 -0
  73. package/pg/buttonGroup/__examples__/basic/basic.ts +11 -0
  74. package/pg/buttonGroup/buttonGroup.css +4 -0
  75. package/pg/buttonGroup/buttonGroup.html +1 -0
  76. package/pg/buttonGroup/buttonGroup.spec.ts +30 -0
  77. package/pg/buttonGroup/buttonGroup.ts +50 -0
  78. package/pg/buttonGroup/index.ts +3 -0
  79. package/pg/buttonLink/README.md +51 -0
  80. package/pg/buttonLink/__examples__/basic/basic.html +17 -0
  81. package/pg/buttonLink/__examples__/basic/basic.ts +11 -0
  82. package/pg/buttonLink/buttonLink.css +91 -0
  83. package/pg/buttonLink/buttonLink.html +3 -0
  84. package/pg/buttonLink/buttonLink.ts +46 -0
  85. package/pg/buttonLink/index.ts +3 -0
  86. package/pg/buttonToggle/README.md +54 -0
  87. package/pg/buttonToggle/__examples__/basic/basic.html +10 -0
  88. package/pg/buttonToggle/__examples__/basic/basic.ts +23 -0
  89. package/pg/buttonToggle/buttonToggle.css +8 -0
  90. package/pg/buttonToggle/buttonToggle.html +4 -0
  91. package/pg/buttonToggle/buttonToggle.ts +44 -0
  92. package/pg/buttonToggle/index.ts +3 -0
  93. package/pg/card/README.md +21 -0
  94. package/pg/card/__examples__/basic/basic.html +5 -0
  95. package/pg/card/__examples__/basic/basic.ts +11 -0
  96. package/pg/card/card.css +11 -0
  97. package/pg/card/card.html +3 -0
  98. package/pg/card/card.spec.ts +30 -0
  99. package/pg/card/card.ts +13 -0
  100. package/pg/card/index.ts +3 -0
  101. package/pg/cardUser/README.md +22 -0
  102. package/pg/cardUser/__examples__/basic/basic.html +3 -0
  103. package/pg/cardUser/__examples__/basic/basic.ts +30 -0
  104. package/pg/cardUser/__examples__/basic/constants.ts +1 -0
  105. package/pg/cardUser/cardUser.css +67 -0
  106. package/pg/cardUser/cardUser.html +23 -0
  107. package/pg/cardUser/cardUser.spec.ts +46 -0
  108. package/pg/cardUser/cardUser.ts +53 -0
  109. package/pg/cardUser/index.ts +3 -0
  110. package/pg/color/README.md +13 -0
  111. package/pg/color/__examples__/basic/basic.html +4 -0
  112. package/pg/color/__examples__/basic/basic.ts +20 -0
  113. package/pg/color/color.css +21 -0
  114. package/pg/color/color.html +1 -0
  115. package/pg/color/color.ts +97 -0
  116. package/pg/color/constants.ts +357 -0
  117. package/pg/color/index.ts +3 -0
  118. package/pg/color/utils.ts +27 -0
  119. package/pg/database/README.md +28 -0
  120. package/pg/database/__examples__/basic/basic.html +9 -0
  121. package/pg/database/__examples__/basic/basic.ts +37 -0
  122. package/pg/database/database.css +0 -0
  123. package/pg/database/database.html +0 -0
  124. package/pg/database/database.ts +42 -0
  125. package/pg/database/index.ts +3 -0
  126. package/pg/dropdown/README.md +13 -0
  127. package/pg/dropdown/__examples__/basic/basic.html +14 -0
  128. package/pg/dropdown/__examples__/basic/basic.ts +11 -0
  129. package/pg/dropdown/dropdown.css +46 -0
  130. package/pg/dropdown/dropdown.html +5 -0
  131. package/pg/dropdown/dropdown.ts +60 -0
  132. package/pg/dropdown/index.ts +3 -0
  133. package/pg/grid/README.md +97 -0
  134. package/pg/grid/__examples__/basic/basic.html +29 -0
  135. package/pg/grid/__examples__/basic/basic.ts +139 -0
  136. package/pg/grid/grid.css +68 -0
  137. package/pg/grid/grid.html +6 -0
  138. package/pg/grid/grid.spec.ts +66 -0
  139. package/pg/grid/grid.ts +417 -0
  140. package/pg/grid/index.ts +3 -0
  141. package/pg/header/README.md +23 -0
  142. package/pg/header/__examples__/basic/basic.html +8 -0
  143. package/pg/header/__examples__/basic/basic.ts +11 -0
  144. package/pg/header/header.css +42 -0
  145. package/pg/header/header.html +15 -0
  146. package/pg/header/header.ts +28 -0
  147. package/pg/header/index.ts +3 -0
  148. package/pg/icon/README.md +26 -0
  149. package/pg/icon/__examples__/basic/basic.html +16 -0
  150. package/pg/icon/__examples__/basic/basic.ts +34 -0
  151. package/pg/icon/__examples__/basic/constants.ts +2 -0
  152. package/pg/icon/icon.css +9 -0
  153. package/pg/icon/icon.html +3 -0
  154. package/pg/icon/icon.spec.ts +46 -0
  155. package/pg/icon/icon.ts +23 -0
  156. package/pg/icon/index.ts +3 -0
  157. package/pg/inputCheck/README.md +32 -0
  158. package/pg/inputCheck/__examples__/basic/basic.html +8 -0
  159. package/pg/inputCheck/__examples__/basic/basic.ts +23 -0
  160. package/pg/inputCheck/index.ts +3 -0
  161. package/pg/inputCheck/inputCheck.css +45 -0
  162. package/pg/inputCheck/inputCheck.html +6 -0
  163. package/pg/inputCheck/inputCheck.ts +42 -0
  164. package/pg/inputCheckList/README.md +35 -0
  165. package/pg/inputCheckList/__examples__/basic/basic.html +4 -0
  166. package/pg/inputCheckList/__examples__/basic/basic.ts +31 -0
  167. package/pg/inputCheckList/index.ts +3 -0
  168. package/pg/inputCheckList/inputCheckList.css +70 -0
  169. package/pg/inputCheckList/inputCheckList.html +1 -0
  170. package/pg/inputCheckList/inputCheckList.ts +103 -0
  171. package/pg/inputCheckList/templates/option.html +8 -0
  172. package/pg/inputFileLocal/README.md +30 -0
  173. package/pg/inputFileLocal/__examples__/basic/basic.html +4 -0
  174. package/pg/inputFileLocal/__examples__/basic/basic.ts +23 -0
  175. package/pg/inputFileLocal/index.ts +3 -0
  176. package/pg/inputFileLocal/inputFileLocal.css +80 -0
  177. package/pg/inputFileLocal/inputFileLocal.html +5 -0
  178. package/pg/inputFileLocal/inputFileLocal.ts +82 -0
  179. package/pg/inputHexRgb/README.md +15 -0
  180. package/pg/inputHexRgb/__examples__/basic/basic.html +4 -0
  181. package/pg/inputHexRgb/__examples__/basic/basic.ts +23 -0
  182. package/pg/inputHexRgb/index.ts +3 -0
  183. package/pg/inputHexRgb/inputHexRgb.css +96 -0
  184. package/pg/inputHexRgb/inputHexRgb.html +9 -0
  185. package/pg/inputHexRgb/inputHexRgb.ts +79 -0
  186. package/pg/inputHexRgb/utils.ts +27 -0
  187. package/pg/inputRange/README.md +18 -0
  188. package/pg/inputRange/__examples__/basic/basic.html +9 -0
  189. package/pg/inputRange/__examples__/basic/basic.ts +30 -0
  190. package/pg/inputRange/index.ts +3 -0
  191. package/pg/inputRange/inputRange.css +0 -0
  192. package/pg/inputRange/inputRange.html +1 -0
  193. package/pg/inputRange/inputRange.ts +53 -0
  194. package/pg/inputSelect/README.md +25 -0
  195. package/pg/inputSelect/__examples__/basic/basic.html +6 -0
  196. package/pg/inputSelect/__examples__/basic/basic.ts +30 -0
  197. package/pg/inputSelect/index.ts +3 -0
  198. package/pg/inputSelect/inputSelect.css +36 -0
  199. package/pg/inputSelect/inputSelect.html +4 -0
  200. package/pg/inputSelect/inputSelect.ts +57 -0
  201. package/pg/inputText/README.md +27 -0
  202. package/pg/inputText/__examples__/basic/basic.html +9 -0
  203. package/pg/inputText/__examples__/basic/basic.ts +30 -0
  204. package/pg/inputText/index.ts +3 -0
  205. package/pg/inputText/inputText.css +20 -0
  206. package/pg/inputText/inputText.html +1 -0
  207. package/pg/inputText/inputText.spec.ts +59 -0
  208. package/pg/inputText/inputText.ts +59 -0
  209. package/pg/inputTextIcon/README.md +26 -0
  210. package/pg/inputTextIcon/index.ts +3 -0
  211. package/pg/inputTextIcon/inputTextIcon.css +24 -0
  212. package/pg/inputTextIcon/inputTextIcon.html +4 -0
  213. package/pg/inputTextIcon/inputTextIcon.spec.ts +44 -0
  214. package/pg/inputTextIcon/inputTextIcon.ts +26 -0
  215. package/pg/inputUserSelect/README.md +31 -0
  216. package/pg/inputUserSelect/__examples__/basic/basic.html +4 -0
  217. package/pg/inputUserSelect/__examples__/basic/basic.ts +25 -0
  218. package/pg/inputUserSelect/__examples__/basic/constants.ts +33 -0
  219. package/pg/inputUserSelect/index.ts +3 -0
  220. package/pg/inputUserSelect/inputUserSelect.css +174 -0
  221. package/pg/inputUserSelect/inputUserSelect.html +18 -0
  222. package/pg/inputUserSelect/inputUserSelect.ts +266 -0
  223. package/pg/listTag/README.md +26 -0
  224. package/pg/listTag/__examples__/basic/basic.html +16 -0
  225. package/pg/listTag/__examples__/basic/basic.ts +53 -0
  226. package/pg/listTag/__examples__/basic/constants.ts +22 -0
  227. package/pg/listTag/index.ts +3 -0
  228. package/pg/listTag/listTag.css +9 -0
  229. package/pg/listTag/listTag.html +1 -0
  230. package/pg/listTag/listTag.ts +48 -0
  231. package/pg/listTag/partials/tag.html +3 -0
  232. package/pg/markdown/README.md +13 -0
  233. package/pg/markdown/__examples__/basic/basic.html +3 -0
  234. package/pg/markdown/__examples__/basic/basic.ts +51 -0
  235. package/pg/markdown/__examples__/basic/constants.ts +129 -0
  236. package/pg/markdown/index.ts +5 -0
  237. package/pg/markdown/markdown.css +760 -0
  238. package/pg/markdown/markdown.html +1 -0
  239. package/pg/markdown/markdown.md +123 -0
  240. package/pg/markdown/markdown.spec.ts +87 -0
  241. package/pg/markdown/markdown.ts +381 -0
  242. package/pg/markdown/markdownReplace.ts +7 -0
  243. package/pg/menuIcon/README.md +13 -0
  244. package/pg/menuIcon/__examples__/basic/basic.html +3 -0
  245. package/pg/menuIcon/__examples__/basic/basic.ts +15 -0
  246. package/pg/menuIcon/index.ts +3 -0
  247. package/pg/menuIcon/menuIcon.css +168 -0
  248. package/pg/menuIcon/menuIcon.html +64 -0
  249. package/pg/menuIcon/menuIcon.ts +271 -0
  250. package/pg/modalAlert/README.md +17 -0
  251. package/pg/modalAlert/__examples__/basic/basic.html +4 -0
  252. package/pg/modalAlert/__examples__/basic/basic.ts +27 -0
  253. package/pg/modalAlert/index.ts +3 -0
  254. package/pg/modalAlert/modalAlert.css +43 -0
  255. package/pg/modalAlert/modalAlert.html +22 -0
  256. package/pg/modalAlert/modalAlert.ts +45 -0
  257. package/pg/modification/README.md +34 -0
  258. package/pg/modification/__examples__/basic/basic.html +8 -0
  259. package/pg/modification/__examples__/basic/basic.ts +63 -0
  260. package/pg/modification/__examples__/basic/constants.ts +416 -0
  261. package/pg/modification/index.ts +3 -0
  262. package/pg/modification/modification.css +311 -0
  263. package/pg/modification/modification.html +1 -0
  264. package/pg/modification/modification.spec.ts +33 -0
  265. package/pg/modification/modification.ts +201 -0
  266. package/pg/modification/type/date.html +1 -0
  267. package/pg/modification/type/iconAliasCreated.html +13 -0
  268. package/pg/modification/type/iconAliasDeleted.html +13 -0
  269. package/pg/modification/type/iconAuthorModified.html +13 -0
  270. package/pg/modification/type/iconCreated.html +13 -0
  271. package/pg/modification/type/iconDeleted.html +13 -0
  272. package/pg/modification/type/iconDeprecated.html +13 -0
  273. package/pg/modification/type/iconDescriptionModified.html +10 -0
  274. package/pg/modification/type/iconModified.html +14 -0
  275. package/pg/modification/type/iconRenamed.html +13 -0
  276. package/pg/modification/type/iconTagCreated.html +13 -0
  277. package/pg/modification/type/iconTagDeleted.html +13 -0
  278. package/pg/modification/type/news.html +5 -0
  279. package/pg/nav/README.md +16 -0
  280. package/pg/nav/__examples__/basic/basic.html +5 -0
  281. package/pg/nav/__examples__/basic/basic.ts +11 -0
  282. package/pg/nav/index.ts +3 -0
  283. package/pg/nav/nav.css +14 -0
  284. package/pg/nav/nav.html +16 -0
  285. package/pg/nav/nav.ts +21 -0
  286. package/pg/overlay/README.md +37 -0
  287. package/pg/overlay/__examples__/basic/basic.css +3 -0
  288. package/pg/overlay/__examples__/basic/basic.html +3 -0
  289. package/pg/overlay/__examples__/basic/basic.ts +13 -0
  290. package/pg/overlay/index.ts +3 -0
  291. package/pg/overlay/overlay.ts +26 -0
  292. package/pg/picker/README.md +13 -0
  293. package/pg/picker/index.ts +3 -0
  294. package/pg/picker/picker.css +56 -0
  295. package/pg/picker/picker.html +8 -0
  296. package/pg/picker/picker.ts +66 -0
  297. package/pg/preview/README.md +19 -0
  298. package/pg/preview/__examples__/basic/basic.html +11 -0
  299. package/pg/preview/__examples__/basic/basic.ts +22 -0
  300. package/pg/preview/index.ts +3 -0
  301. package/pg/preview/preview.css +34 -0
  302. package/pg/preview/preview.html +5 -0
  303. package/pg/preview/preview.ts +38 -0
  304. package/pg/scroll/README.md +42 -0
  305. package/pg/scroll/__examples__/basic/basic.css +4 -0
  306. package/pg/scroll/__examples__/basic/basic.html +11 -0
  307. package/pg/scroll/__examples__/basic/basic.ts +88 -0
  308. package/pg/scroll/index.ts +3 -0
  309. package/pg/scroll/scroll.css +7 -0
  310. package/pg/scroll/scroll.html +3 -0
  311. package/pg/scroll/scroll.ts +158 -0
  312. package/pg/search/README.md +59 -0
  313. package/pg/search/__examples__/basic/basic.html +3 -0
  314. package/pg/search/__examples__/basic/basic.ts +29 -0
  315. package/pg/search/__examples__/basic/constants.ts +3 -0
  316. package/pg/search/index.ts +3 -0
  317. package/pg/search/search.css +188 -0
  318. package/pg/search/search.html +18 -0
  319. package/pg/search/search.ts +252 -0
  320. package/pg/search/utils.ts +12 -0
  321. package/pg/shared/README.md +28 -0
  322. package/pg/shared/copy.ts +25 -0
  323. package/pg/shared/database.ts +35 -0
  324. package/pg/shared/databaseService.ts +230 -0
  325. package/pg/shared/debounce.ts +12 -0
  326. package/pg/shared/enums/modificationType.ts +19 -0
  327. package/pg/shared/filter.ts +14 -0
  328. package/pg/shared/http.ts +83 -0
  329. package/pg/shared/iconFilter.spec.ts +61 -0
  330. package/pg/shared/iconFilter.ts +71 -0
  331. package/pg/shared/list.ts +34 -0
  332. package/pg/shared/models/alias.ts +40 -0
  333. package/pg/shared/models/font.ts +31 -0
  334. package/pg/shared/models/fontIcon.ts +25 -0
  335. package/pg/shared/models/fontVersion.ts +22 -0
  336. package/pg/shared/models/icon.ts +97 -0
  337. package/pg/shared/models/modification.ts +45 -0
  338. package/pg/shared/models/style.ts +12 -0
  339. package/pg/shared/models/tag.ts +37 -0
  340. package/pg/shared/models/user.ts +35 -0
  341. package/pg/shared/models/version.ts +20 -0
  342. package/pg/shared/removeDiacritics.ts +94 -0
  343. package/pg/shared/toast.ts +47 -0
  344. package/pg/shared/uuid.ts +6 -0
  345. package/pg/tab/README.md +18 -0
  346. package/pg/tab/index.ts +3 -0
  347. package/pg/tab/tab.css +13 -0
  348. package/pg/tab/tab.html +3 -0
  349. package/pg/tab/tab.ts +51 -0
  350. package/pg/tabs/README.md +31 -0
  351. package/pg/tabs/__examples__/basic/basic.html +13 -0
  352. package/pg/tabs/__examples__/basic/basic.ts +11 -0
  353. package/pg/tabs/index.ts +3 -0
  354. package/pg/tabs/partials/tab.html +3 -0
  355. package/pg/tabs/tabs.css +69 -0
  356. package/pg/tabs/tabs.html +4 -0
  357. package/pg/tabs/tabs.ts +102 -0
  358. package/pg/toast/README.md +13 -0
  359. package/pg/toast/index.ts +3 -0
  360. package/pg/toast/toast.css +112 -0
  361. package/pg/toast/toast.html +13 -0
  362. package/pg/toast/toast.ts +39 -0
  363. package/pg/toasts/README.md +37 -0
  364. package/pg/toasts/__examples__/basic/basic.html +11 -0
  365. package/pg/toasts/__examples__/basic/basic.ts +86 -0
  366. package/pg/toasts/index.ts +3 -0
  367. package/pg/toasts/toasts.css +8 -0
  368. package/pg/toasts/toasts.html +1 -0
  369. package/pg/toasts/toasts.ts +51 -0
  370. package/pg/tooltip/README.md +51 -0
  371. package/pg/tooltip/__examples__/basic/basic.css +38 -0
  372. package/pg/tooltip/__examples__/basic/basic.html +21 -0
  373. package/pg/tooltip/__examples__/basic/basic.ts +55 -0
  374. package/pg/tooltip/addTooltip.ts +31 -0
  375. package/pg/tooltip/index.ts +20 -0
  376. package/pg/tooltip/position.ts +15 -0
  377. package/pg/tooltip/tooltip.css +36 -0
  378. package/pg/tooltip/tooltip.html +4 -0
  379. package/pg/tooltip/tooltip.ts +170 -0
@@ -0,0 +1,252 @@
1
+ import { Component, Prop, Part } from '@pictogrammers/element';
2
+ import { Icon } from '../shared/models/icon';
3
+ import { iconFilter, sanitizeTerm } from '../shared/iconFilter';
4
+ import { filter } from '../shared/filter';
5
+
6
+ import template from './search.html';
7
+ import style from './search.css';
8
+
9
+ interface Item {
10
+ name: string,
11
+ type: string,
12
+ aliases?: string[],
13
+ icon?: string,
14
+ url: string
15
+ }
16
+
17
+ const KEY = {
18
+ ArrowUp: 'ArrowUp',
19
+ ArrowRight: 'ArrowRight',
20
+ ArrowDown: 'ArrowDown',
21
+ ArrowLeft: 'ArrowLeft'
22
+ };
23
+
24
+ @Component({
25
+ selector: 'pg-search',
26
+ style,
27
+ template
28
+ })
29
+ export default class PgSearch extends HTMLElement {
30
+ @Prop() items: Item[] = [];
31
+ @Prop() icons: Icon[] = [];
32
+
33
+ @Part() $grid: HTMLDivElement;
34
+ @Part() $menu: HTMLDivElement;
35
+ @Part() $input: HTMLInputElement;
36
+ @Part() $list: HTMLUListElement;
37
+ @Part() $empty: HTMLDivElement;
38
+ @Part() $reqIcon: HTMLAnchorElement;
39
+ @Part() $reqDoc: HTMLAnchorElement;
40
+
41
+ isOpen: boolean = false;
42
+ isOver: boolean = false;
43
+ term: string = '';
44
+ keyIndex = -1;
45
+ anchors: HTMLAnchorElement[] = [];
46
+
47
+ connectedCallback() {
48
+ this.$input.addEventListener('input', this.handleInput.bind(this));
49
+ this.$input.addEventListener('focus', this.handleFocus.bind(this));
50
+ this.$input.addEventListener('blur', this.handleBlur.bind(this));
51
+ this.addEventListener('keydown', this.keydown.bind(this));
52
+ this.$list.addEventListener('mouseenter', this.handleListEnter.bind(this));
53
+ this.$list.addEventListener('mouseleave', this.handleListLeave.bind(this));
54
+ }
55
+
56
+ handleInput(e) {
57
+ const target = e.target as HTMLInputElement;
58
+ const { value } = target;
59
+ this.term = value;
60
+ this.updateList();
61
+ }
62
+
63
+ handleFocus() {
64
+ this.keyIndex = -1;
65
+ this.updateList();
66
+ this.isOpen = true;
67
+ this.$menu.style.display = 'block';
68
+ this.$grid.classList.add('active');
69
+ }
70
+
71
+ handleBlur() {
72
+ if (!this.isOver) {
73
+ this.isOpen = false;
74
+ this.$menu.style.display = 'none';
75
+ this.$grid.classList.remove('active');
76
+ this.keyIndex -= 1;
77
+ }
78
+ }
79
+
80
+ keydown(e: KeyboardEvent) {
81
+ switch(e.key) {
82
+ case KEY.ArrowDown:
83
+ this.keyIndex += 1;
84
+ this.setActive();
85
+ e.preventDefault();
86
+ e.stopPropagation();
87
+ break;
88
+ case KEY.ArrowUp:
89
+ this.keyIndex -= 1;
90
+ this.setActive();
91
+ e.preventDefault();
92
+ e.stopPropagation();
93
+ break;
94
+ }
95
+ }
96
+
97
+ setActive() {
98
+ if (this.keyIndex === -2) {
99
+ this.keyIndex = this.anchors.length - 1;
100
+ }
101
+ if (this.keyIndex === this.anchors.length) {
102
+ this.keyIndex = -1;
103
+ }
104
+ if (this.keyIndex === -1) {
105
+ this.$input.focus();
106
+ this.isOver = false;
107
+ } else {
108
+ this.isOver = true;
109
+ this.anchors[this.keyIndex].focus();
110
+ }
111
+ }
112
+
113
+ handleListEnter() {
114
+ this.isOver = true;
115
+ }
116
+
117
+ handleListLeave() {
118
+ this.isOver = false;
119
+ }
120
+
121
+ highlight(text: string) {
122
+ var i = 0;
123
+ var normalized = text;
124
+ const span = document.createElement('span');
125
+ const term = sanitizeTerm(this.term);
126
+ if (this.term === '') {
127
+ span.innerText = text;
128
+ return span;
129
+ }
130
+ while (normalized) {
131
+ var index = normalized.toLowerCase().indexOf(term);
132
+ if (index === -1) {
133
+ const end = document.createElement('span');
134
+ end.innerText = normalized.substr(0, normalized.length);
135
+ span.appendChild(end);
136
+ normalized = '';
137
+ } else {
138
+ if (index > 0) {
139
+ const start = document.createElement('span');
140
+ start.innerText = normalized.substr(0, index);
141
+ span.appendChild(start);
142
+ }
143
+ const strong = document.createElement('strong');
144
+ strong.innerText = normalized.substr(index, term.length);
145
+ span.appendChild(strong);
146
+ normalized = normalized.substr(index + term.length, normalized.length);
147
+ }
148
+ }
149
+ return span;
150
+ }
151
+
152
+ clearList() {
153
+ while(this.$list.firstChild){
154
+ this.$list.removeChild(this.$list.firstChild);
155
+ }
156
+ this.anchors = [];
157
+ }
158
+
159
+ updateList() {
160
+ this.clearList();
161
+ let empty = false;
162
+ const termRegex = new RegExp(this.term, 'i');
163
+ const filtered = Array.from(
164
+ filter(
165
+ this.items,
166
+ (item: any) => {
167
+ return item.name.match(termRegex)
168
+ },
169
+ 5
170
+ )
171
+ );
172
+ filtered.forEach((item, i) => {
173
+ var li = document.createElement('li');
174
+ li.classList.add('item');
175
+ li.classList.toggle('first', i === 0);
176
+ li.classList.toggle('last', i === filtered.length - 1);
177
+ var a = document.createElement('a');
178
+ a.href = item.url;
179
+ var text = this.highlight(item.name);
180
+ a.appendChild(text);
181
+ var type = document.createElement('span');
182
+ type.innerText = item.type;
183
+ type.classList.add('type');
184
+ a.appendChild(type);
185
+ li.appendChild(a);
186
+ this.$list.appendChild(li);
187
+ this.anchors.push(a);
188
+ empty = true;
189
+ });
190
+ if (this.term !== '') {
191
+ const icons = iconFilter(this.icons, this.term, 5);
192
+ if (icons.length) {
193
+ var li = document.createElement('li');
194
+ li.innerText = 'Icons';
195
+ li.classList.add('section');
196
+ this.$list.appendChild(li);
197
+ }
198
+ icons.forEach((icon, i) => {
199
+ var li = document.createElement('li');
200
+ li.classList.add('icon');
201
+ li.classList.toggle('first', i === 0);
202
+ li.classList.toggle('last', i === icons.length - 1);
203
+ var a = document.createElement('a');
204
+ a.href = `/icon/${icon.name}`;
205
+ var additional = icon.aliases.reduce<string[]>((arr, icon) => {
206
+ if (icon.match) {
207
+ arr.push(icon.name || '');
208
+ }
209
+ return arr;
210
+ }, []);
211
+ var aliasText = '';
212
+ if (additional.length) {
213
+ aliasText = ` (${additional.join(', ')})`;
214
+ }
215
+ const text = this.highlight(`${icon.name}${aliasText}`);
216
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
217
+ svg.setAttribute('viewBox', '0 0 24 24');
218
+ svg.setAttribute('fill', 'currentColor');
219
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
220
+ path.setAttribute('d', icon.data as string);
221
+ svg.appendChild(path);
222
+ a.appendChild(svg);
223
+ a.appendChild(text);
224
+ li.appendChild(a);
225
+ this.anchors.push(a);
226
+ this.$list.appendChild(li);
227
+ });
228
+ if (icons.length === 5) {
229
+ var li = document.createElement('li');
230
+ li.classList.add('all');
231
+ var a = document.createElement('a');
232
+ a.href = `/icons?search=${this.term}`;
233
+ a.appendChild(document.createTextNode('All results for "'));
234
+ var strong = document.createElement('strong');
235
+ strong.innerText = this.term;
236
+ a.appendChild(strong)
237
+ a.appendChild(document.createTextNode('"'));
238
+ li.appendChild(a);
239
+ this.anchors.push(a);
240
+ this.$list.appendChild(li);
241
+ }
242
+ if (icons.length > 0) {
243
+ empty = true;
244
+ }
245
+ }
246
+ if (!empty) {
247
+ this.anchors.push(this.$reqIcon);
248
+ this.anchors.push(this.$reqDoc);
249
+ }
250
+ this.$empty.classList.toggle('hide', empty);
251
+ }
252
+ }
@@ -0,0 +1,12 @@
1
+ export const debounce = <F extends (...args: any[]) => any>(func: F, waitFor: number) => {
2
+ let timeout
3
+
4
+ return (...args: Parameters<F>): Promise<ReturnType<F>> =>
5
+ new Promise(resolve => {
6
+ if (timeout) {
7
+ clearTimeout(timeout)
8
+ }
9
+
10
+ timeout = setTimeout(() => resolve(func(...args)), waitFor)
11
+ })
12
+ }
@@ -0,0 +1,28 @@
1
+ # Shared
2
+
3
+ The shared directory is where all the utilities, models, and data services live.
4
+
5
+ ## Database Service
6
+
7
+ ```ts
8
+ import { DatabaseService } from '../shared/databaseService';
9
+
10
+ const db = new DatabaseService();
11
+
12
+ await db.sync();
13
+ ```
14
+
15
+ | Method | Description |
16
+ | -------| ----------- |
17
+ | `db.synced` | `true` if database has been synced. |
18
+ | `db.sync()` | Calling multiple times do nothing. |
19
+ | `db.resync()` | Ignores `synced` and verifies local cache |
20
+ | `db.delete()` | Delete all local cache |
21
+ | `db.getIconByName(fontId, name)` | Get single icon data |
22
+ | `db.geticons(fontId[, term])` | Get all icons in a font with search term |
23
+
24
+ > Note: All data is parsed into models. This can take a second, so data needs to be cached once pulled from the database.
25
+
26
+ ## Toast
27
+
28
+ Reference the toast documentation.
@@ -0,0 +1,25 @@
1
+ export function getCopySvgInline(icon: any) {
2
+ return `<svg viewBox="0 0 24 24"><path fill="currentColor" d="${icon.data}"/></svg>`;
3
+ }
4
+
5
+ export function getCopySvgFile(icon: any) {
6
+ return [
7
+ `<?xml version="1.0" encoding="utf-8"?>`,
8
+ `<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">`,
9
+ `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">`,
10
+ ` <path fill="#000000" fill-opacity="1" stroke-width="0" stroke-linejoin="round" d="${icon.data}"/>`,
11
+ `</svg>`
12
+ ].join('');
13
+ }
14
+
15
+ export const copyText = (text: string) => {
16
+ var copyFrom = document.createElement('textarea');
17
+ copyFrom.setAttribute("style", "position:fixed;opacity:0;top:100px;left:100px;");
18
+ copyFrom.value = text;
19
+ document.body.appendChild(copyFrom);
20
+ copyFrom.select();
21
+ document.execCommand('copy');
22
+ setTimeout(function () {
23
+ document.body.removeChild(copyFrom);
24
+ }, 1500);
25
+ }
@@ -0,0 +1,35 @@
1
+ import Dexie from 'dexie';
2
+
3
+ export class Database extends Dexie {
4
+ hashes: Dexie.Table<HashTable, string>;
5
+ icons: Dexie.Table<IconTable, string>;
6
+
7
+ constructor() {
8
+ super("IconCache");
9
+
10
+ this.version(1).stores({
11
+ hashes: '&id, hash',
12
+ icons: '&id, idFull, fontId, name, data, aliases, tags, codepoint'
13
+ });
14
+
15
+ this.hashes = this.table("hashes");
16
+ this.icons = this.table("icons");
17
+ }
18
+ }
19
+
20
+ export interface HashTable {
21
+ id: string,
22
+ hash: string
23
+ }
24
+
25
+ export interface IconTable {
26
+ id: string,
27
+ idFull: string,
28
+ fontId: string,
29
+ codepoint: string,
30
+ name: string,
31
+ data: string,
32
+ version: string,
33
+ aliases: any,
34
+ tags: any
35
+ }
@@ -0,0 +1,230 @@
1
+ import { Database, IconTable } from './database';
2
+ import { http } from './http';
3
+
4
+ import { Icon } from './models/icon';
5
+ import { Font } from './models/font';
6
+ import { Alias } from './models/alias';
7
+ import { Tag } from './models/tag';
8
+
9
+ interface StringMap {
10
+ [key: string]: string;
11
+ }
12
+
13
+ export class DatabaseService {
14
+
15
+ private db = new Database();
16
+
17
+ /**
18
+ * Get list of hashes for icons in font
19
+ *
20
+ * @param font Font id to lookup hashes for
21
+ */
22
+ private async getHashesFromServer(font: Font): Promise<StringMap> {
23
+ const res = await http.get<StringMap>(`/api/font/${font.id}/hash`);
24
+ return res;
25
+ }
26
+
27
+ private async getIconsFromServer(font: Font, ids: string[]): Promise<Icon[]> {
28
+ if (ids.length === 0) {
29
+ return [];
30
+ }
31
+ const res = await http.get<Icon[]>(`/api/font/${font.id}`, {
32
+ params: {
33
+ ids: ids.join(',')
34
+ }
35
+ });
36
+ return res.map(icon => new Icon().from(icon));
37
+ }
38
+
39
+ private async getIconsByPage(font: Font, page: number, size: number) {
40
+ const res = await http.get<Icon[]>(`/api/font/${font.id}`, {
41
+ params: {
42
+ page: page.toString(),
43
+ size: size.toString()
44
+ }
45
+ });
46
+ return res.map(icon => new Icon().from(icon));
47
+ }
48
+
49
+ async asyncThrottledMap<T, U>(maxCount: number, array: T[], f: (x: T) => Promise<U>) {
50
+ let inFlight = new Set<Promise<U>>();
51
+ const result: Promise<U>[] = [];
52
+
53
+ // Sequentially add a Promise for each operation.
54
+ for (let elem of array) {
55
+
56
+ // Wait for any one of the promises to complete if there are too many running.
57
+ if (inFlight.size >= maxCount) {
58
+ await Promise.race(inFlight);
59
+ }
60
+
61
+ // This is the Promise that the user originally passed us back.
62
+ const origPromise = f(elem);
63
+ // This is a Promise that adds/removes from the set of in-flight promises.
64
+ const handledPromise = wrap(origPromise);
65
+ result.push(handledPromise);
66
+ }
67
+
68
+ return Promise.all(result);
69
+
70
+ async function wrap(p: Promise<U>) {
71
+ inFlight.add(p);
72
+ const result = await p;
73
+ inFlight.delete(p);
74
+ return result;
75
+ }
76
+ }
77
+
78
+ async exists(fontId: string) {
79
+ const count = await this.getCount(fontId);
80
+ return count > 0;
81
+ }
82
+
83
+ async resync(fontId: string) {
84
+ let modified = false;
85
+ const font = new Font().from({
86
+ id: fontId
87
+ } as Font);
88
+ const hashes = await this.getHashesFromServer(font);
89
+ const hashIds = Object.keys(hashes);
90
+ const localHashObj = await this.db.hashes.toArray();
91
+ const localHashes = {};
92
+ localHashObj.forEach((item) => {
93
+ localHashes[item.id] = item.hash;
94
+ });
95
+ const localHashIds = Object.keys(localHashes);
96
+ const modifiedIds: string[] = [];
97
+ hashIds.forEach((id) => {
98
+ if (!(id in localHashes) || localHashes[id] !== hashes[id]) {
99
+ modifiedIds.push(id);
100
+ }
101
+ });
102
+ const removeIds: string[] = [];
103
+ localHashIds.forEach((id) => {
104
+ if (!(id in hashes)) {
105
+ removeIds.push(id);
106
+ }
107
+ });
108
+ await this.db.icons.bulkDelete(removeIds);
109
+ if (modifiedIds.length > 0 || removeIds.length > 0) {
110
+ modified = true;
111
+ }
112
+ if (modifiedIds.length < 500) {
113
+ // Do a partial update patch of data
114
+ let i, j, chunkIds: any[] = [], chunk = 100;
115
+ for (i = 0, j = modifiedIds.length; i < j; i += chunk) {
116
+ chunkIds.push(modifiedIds.slice(i, i + chunk));
117
+ }
118
+ const chunkPromises = chunkIds.map((ids) => {
119
+ return this.getIconsFromServer(font, ids);
120
+ });
121
+ const results = await Promise.all(chunkPromises);
122
+ results.forEach(icons => {
123
+ this.db.icons.bulkPut(
124
+ icons.map(icon => ({
125
+ id: icon.fontIcon.id,
126
+ idFull: icon.id as string,
127
+ fontId: font.id as string,
128
+ name: icon.name as string,
129
+ data: icon.data as string as string,
130
+ version: icon.version as string,
131
+ codepoint: icon.codepoint as string,
132
+ aliases: icon.aliases,
133
+ tags: icon.tags
134
+ })
135
+ ));
136
+ });
137
+ } else if (modifiedIds.length !== 0) {
138
+ // Sync every icon into the database
139
+ let size = 500,
140
+ pages = Math.ceil(hashIds.length / size),
141
+ chunkPromises: Promise<Icon[]>[] = [];
142
+ for (let page = 1; page <= pages; page++) {
143
+ chunkPromises.push(
144
+ this.getIconsByPage(font, page, size)
145
+ );
146
+ }
147
+ await this.asyncThrottledMap<Promise<Icon[]>, void>(2, chunkPromises, (p) =>
148
+ p.then(icons => {
149
+ this.db.icons.bulkPut(
150
+ icons.map(icon => ({
151
+ id: icon.fontIcon.id,
152
+ idFull: icon.id as string,
153
+ fontId: font.id as string,
154
+ name: icon.name as string,
155
+ data: icon.data as string,
156
+ version: icon.version as string,
157
+ codepoint: icon.codepoint as string,
158
+ aliases: JSON.stringify(icon.aliases.map(alias => ({ name: alias.name }))),
159
+ tags: JSON.stringify(icon.tags.map(tag => ({ name: tag.name, url: tag.url})))
160
+ })
161
+ ));
162
+ })
163
+ );
164
+ }
165
+ if (modified) {
166
+ await this.db.hashes.bulkPut(hashIds.map(id => ({ id, hash: hashes[id] })));
167
+ await this.db.hashes.bulkDelete(removeIds);
168
+ }
169
+ return modified;
170
+ }
171
+
172
+ synced = false;
173
+
174
+ async sync(fontId: string) {
175
+ if (!this.synced) {
176
+ const modified = await this.resync(fontId);
177
+ this.synced = true;
178
+ return modified;
179
+ }
180
+ return false;
181
+ }
182
+
183
+ convert(local: IconTable) {
184
+ const icon = new Icon();
185
+ icon.id = local.idFull;
186
+ icon.name = local.name;
187
+ icon.data = local.data;
188
+ icon.version = local.version;
189
+ icon.codepoint = local.codepoint;
190
+ const aliases = local.aliases instanceof Array ? local.aliases : JSON.parse(local.aliases);
191
+ icon.aliases = aliases.map(alias => new Alias().from(alias));
192
+ const tags = local.tags instanceof Array ? local.tags : JSON.parse(local.tags);
193
+ icon.tags = tags.map(tag => new Tag().from(tag));
194
+ return icon;
195
+ }
196
+
197
+ async getIconByName(name) {
198
+ const local = await this.db.icons.where('name').equals(name).first();
199
+ if (!local) {
200
+ return null;
201
+ }
202
+ return this.convert(local);
203
+ }
204
+
205
+ // ToDo, cache into a format that can be parsed quicker for search
206
+
207
+ async getIcons(fontId: string, term?: string) {
208
+ let icons;
209
+ if (term) {
210
+ const safeTerm = term.toLowerCase().replace(/[^a-z0-9-]/g, '');
211
+ const reg = new RegExp(`${safeTerm}`);
212
+ icons = await this.db.icons.where('fontId').equals(fontId)
213
+ .filter((icon) => {
214
+ return icon.name.match(reg) !== null;
215
+ }).sortBy('name');
216
+ } else {
217
+ icons = await this.db.icons.where('fontId').equals(fontId).sortBy('name');
218
+ }
219
+ return icons.map(icon => this.convert(icon));
220
+ }
221
+
222
+ async getCount(fontId: string) {
223
+ return await this.db.icons.where('fontId').equals(fontId).count();
224
+ }
225
+
226
+ async delete() {
227
+ await this.db.delete();
228
+ }
229
+
230
+ }
@@ -0,0 +1,12 @@
1
+ export const debounce = <F extends (...args: any[]) => any>(func: F, waitFor: number) => {
2
+ let timeout
3
+
4
+ return (...args: Parameters<F>): Promise<ReturnType<F>> =>
5
+ new Promise(resolve => {
6
+ if (timeout) {
7
+ clearTimeout(timeout)
8
+ }
9
+
10
+ timeout = setTimeout(() => resolve(func(...args)), waitFor)
11
+ })
12
+ }
@@ -0,0 +1,19 @@
1
+ export enum ModificationType {
2
+ IconAliasCreated = '691c8829-b1e7-11e7-bf5c-94188269ec50',
3
+ IconAliasDeleted = 'f1f70a76-b975-11e9-8ca0-94188269ec50',
4
+ IconCreated = 'AFFE875E-01BC-4A34-9BE3-27625A155B28',
5
+ IconDeleted = 'B1CE1713-A18A-4E9D-9E26-D0B4E44A1FAC',
6
+ IconModified = '1506F66B-CC2A-4575-A20A-DC138628977A',
7
+ IconRenamed = 'F7B6D49B-A86F-49AC-AF92-6B9D0DF6188B',
8
+ IconTagCreated = 'a185a9e8-c192-11e7-bf5c-94188269ec50',
9
+ IconTagDeleted = 'ffe6b5f6-b975-11e9-8ca0-94188269ec50',
10
+ IconDescriptionModified = '3c638179-c4ca-11e8-9f27-94188269ec50',
11
+ IconAuthorModified = '254591d0-b28e-11e9-8ca0-94188269ec50',
12
+ WebfontPublished = '66B9FA99-1FAA-4D8F-B87F-B6F3CA444624',
13
+ News = 'B4DEB3A8-A146-4086-9D7B-B67842A9CCB8',
14
+ IconDeprecated = 'f92f310f-bfed-11e9-8ca0-94188269ec50',
15
+ IconWorkInProgress = 'e262be80-bfed-11e9-8ca0-94188269ec50',
16
+ IconLive = 'f92f2ba6-bfed-11e9-8ca0-94188269ec50',
17
+ IconPublished = 'e262b92e-bfed-11e9-8ca0-94188269ec50',
18
+ Date = 'date'
19
+ }
@@ -0,0 +1,14 @@
1
+ export function *filter(array, condition, maxSize) {
2
+ if (!maxSize || maxSize > array.length) {
3
+ maxSize = array.length;
4
+ }
5
+ let count = 0;
6
+ let i = 0;
7
+ while ( count< maxSize && i < array.length ) {
8
+ if (condition(array[i])) {
9
+ yield array[i];
10
+ count++;
11
+ }
12
+ i++;
13
+ }
14
+ }