@thinkpixellab-public/px-vue 3.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 (398) hide show
  1. package/.eslintrc.js +14 -0
  2. package/.prettierrc.js +10 -0
  3. package/LICENSE.md +9 -0
  4. package/README.md +83 -0
  5. package/assets/feather/activity.svg +1 -0
  6. package/assets/feather/airplay.svg +1 -0
  7. package/assets/feather/alert-circle.svg +1 -0
  8. package/assets/feather/alert-octagon.svg +1 -0
  9. package/assets/feather/alert-triangle.svg +1 -0
  10. package/assets/feather/align-center.svg +1 -0
  11. package/assets/feather/align-justify.svg +1 -0
  12. package/assets/feather/align-left.svg +1 -0
  13. package/assets/feather/align-right.svg +1 -0
  14. package/assets/feather/anchor.svg +1 -0
  15. package/assets/feather/aperture.svg +1 -0
  16. package/assets/feather/archive.svg +1 -0
  17. package/assets/feather/arrow-down-circle.svg +1 -0
  18. package/assets/feather/arrow-down-left.svg +1 -0
  19. package/assets/feather/arrow-down-right.svg +1 -0
  20. package/assets/feather/arrow-down.svg +1 -0
  21. package/assets/feather/arrow-left-circle.svg +1 -0
  22. package/assets/feather/arrow-left.svg +1 -0
  23. package/assets/feather/arrow-right-circle.svg +1 -0
  24. package/assets/feather/arrow-right.svg +1 -0
  25. package/assets/feather/arrow-up-circle.svg +1 -0
  26. package/assets/feather/arrow-up-left.svg +1 -0
  27. package/assets/feather/arrow-up-right.svg +1 -0
  28. package/assets/feather/arrow-up.svg +1 -0
  29. package/assets/feather/at-sign.svg +1 -0
  30. package/assets/feather/award.svg +1 -0
  31. package/assets/feather/bar-chart-2.svg +1 -0
  32. package/assets/feather/bar-chart.svg +1 -0
  33. package/assets/feather/battery-charging.svg +1 -0
  34. package/assets/feather/battery.svg +1 -0
  35. package/assets/feather/bell-off.svg +1 -0
  36. package/assets/feather/bell.svg +1 -0
  37. package/assets/feather/bluetooth.svg +1 -0
  38. package/assets/feather/bold.svg +1 -0
  39. package/assets/feather/book-open.svg +1 -0
  40. package/assets/feather/book.svg +1 -0
  41. package/assets/feather/bookmark.svg +1 -0
  42. package/assets/feather/box.svg +1 -0
  43. package/assets/feather/briefcase.svg +1 -0
  44. package/assets/feather/calendar.svg +1 -0
  45. package/assets/feather/camera-off.svg +1 -0
  46. package/assets/feather/camera.svg +1 -0
  47. package/assets/feather/cast.svg +1 -0
  48. package/assets/feather/check-circle.svg +1 -0
  49. package/assets/feather/check-square.svg +1 -0
  50. package/assets/feather/check.svg +1 -0
  51. package/assets/feather/chevron-down.svg +1 -0
  52. package/assets/feather/chevron-left.svg +1 -0
  53. package/assets/feather/chevron-right.svg +1 -0
  54. package/assets/feather/chevron-up.svg +1 -0
  55. package/assets/feather/chevrons-down.svg +1 -0
  56. package/assets/feather/chevrons-left.svg +1 -0
  57. package/assets/feather/chevrons-right.svg +1 -0
  58. package/assets/feather/chevrons-up.svg +1 -0
  59. package/assets/feather/chrome.svg +1 -0
  60. package/assets/feather/circle.svg +1 -0
  61. package/assets/feather/clipboard.svg +1 -0
  62. package/assets/feather/clock.svg +1 -0
  63. package/assets/feather/cloud-drizzle.svg +1 -0
  64. package/assets/feather/cloud-lightning.svg +1 -0
  65. package/assets/feather/cloud-off.svg +1 -0
  66. package/assets/feather/cloud-rain.svg +1 -0
  67. package/assets/feather/cloud-snow.svg +1 -0
  68. package/assets/feather/cloud.svg +1 -0
  69. package/assets/feather/code.svg +1 -0
  70. package/assets/feather/codepen.svg +1 -0
  71. package/assets/feather/codesandbox.svg +1 -0
  72. package/assets/feather/coffee.svg +1 -0
  73. package/assets/feather/columns.svg +1 -0
  74. package/assets/feather/command.svg +1 -0
  75. package/assets/feather/compass.svg +1 -0
  76. package/assets/feather/copy.svg +1 -0
  77. package/assets/feather/corner-down-left.svg +1 -0
  78. package/assets/feather/corner-down-right.svg +1 -0
  79. package/assets/feather/corner-left-down.svg +1 -0
  80. package/assets/feather/corner-left-up.svg +1 -0
  81. package/assets/feather/corner-right-down.svg +1 -0
  82. package/assets/feather/corner-right-up.svg +1 -0
  83. package/assets/feather/corner-up-left.svg +1 -0
  84. package/assets/feather/corner-up-right.svg +1 -0
  85. package/assets/feather/cpu.svg +1 -0
  86. package/assets/feather/credit-card.svg +1 -0
  87. package/assets/feather/crop.svg +1 -0
  88. package/assets/feather/crosshair.svg +1 -0
  89. package/assets/feather/database.svg +1 -0
  90. package/assets/feather/delete.svg +1 -0
  91. package/assets/feather/disc.svg +1 -0
  92. package/assets/feather/divide-circle.svg +1 -0
  93. package/assets/feather/divide-square.svg +1 -0
  94. package/assets/feather/divide.svg +1 -0
  95. package/assets/feather/dollar-sign.svg +1 -0
  96. package/assets/feather/download-cloud.svg +1 -0
  97. package/assets/feather/download.svg +1 -0
  98. package/assets/feather/dribbble.svg +1 -0
  99. package/assets/feather/droplet.svg +1 -0
  100. package/assets/feather/edit-2.svg +1 -0
  101. package/assets/feather/edit-3.svg +1 -0
  102. package/assets/feather/edit.svg +1 -0
  103. package/assets/feather/external-link.svg +1 -0
  104. package/assets/feather/eye-off.svg +1 -0
  105. package/assets/feather/eye.svg +1 -0
  106. package/assets/feather/facebook.svg +1 -0
  107. package/assets/feather/fast-forward.svg +1 -0
  108. package/assets/feather/feather.svg +1 -0
  109. package/assets/feather/figma.svg +1 -0
  110. package/assets/feather/file-minus.svg +1 -0
  111. package/assets/feather/file-plus.svg +1 -0
  112. package/assets/feather/file-text.svg +1 -0
  113. package/assets/feather/file.svg +1 -0
  114. package/assets/feather/film.svg +1 -0
  115. package/assets/feather/filter.svg +1 -0
  116. package/assets/feather/flag.svg +1 -0
  117. package/assets/feather/folder-minus.svg +1 -0
  118. package/assets/feather/folder-plus.svg +1 -0
  119. package/assets/feather/folder.svg +1 -0
  120. package/assets/feather/framer.svg +1 -0
  121. package/assets/feather/frown.svg +1 -0
  122. package/assets/feather/gift.svg +1 -0
  123. package/assets/feather/git-branch.svg +1 -0
  124. package/assets/feather/git-commit.svg +1 -0
  125. package/assets/feather/git-merge.svg +1 -0
  126. package/assets/feather/git-pull-request.svg +1 -0
  127. package/assets/feather/github.svg +1 -0
  128. package/assets/feather/gitlab.svg +1 -0
  129. package/assets/feather/globe.svg +1 -0
  130. package/assets/feather/grid.svg +1 -0
  131. package/assets/feather/hard-drive.svg +1 -0
  132. package/assets/feather/hash.svg +1 -0
  133. package/assets/feather/headphones.svg +1 -0
  134. package/assets/feather/heart.svg +1 -0
  135. package/assets/feather/help-circle.svg +1 -0
  136. package/assets/feather/hexagon.svg +1 -0
  137. package/assets/feather/home.svg +1 -0
  138. package/assets/feather/image.svg +1 -0
  139. package/assets/feather/inbox.svg +1 -0
  140. package/assets/feather/info.svg +1 -0
  141. package/assets/feather/instagram.svg +1 -0
  142. package/assets/feather/italic.svg +1 -0
  143. package/assets/feather/key.svg +1 -0
  144. package/assets/feather/layers.svg +1 -0
  145. package/assets/feather/layout.svg +1 -0
  146. package/assets/feather/life-buoy.svg +1 -0
  147. package/assets/feather/link-2.svg +1 -0
  148. package/assets/feather/link.svg +1 -0
  149. package/assets/feather/linkedin.svg +1 -0
  150. package/assets/feather/list.svg +1 -0
  151. package/assets/feather/loader.svg +1 -0
  152. package/assets/feather/lock.svg +1 -0
  153. package/assets/feather/log-in.svg +1 -0
  154. package/assets/feather/log-out.svg +1 -0
  155. package/assets/feather/mail.svg +1 -0
  156. package/assets/feather/map-pin.svg +1 -0
  157. package/assets/feather/map.svg +1 -0
  158. package/assets/feather/maximize-2.svg +1 -0
  159. package/assets/feather/maximize.svg +1 -0
  160. package/assets/feather/meh.svg +1 -0
  161. package/assets/feather/menu.svg +1 -0
  162. package/assets/feather/message-circle.svg +1 -0
  163. package/assets/feather/message-square.svg +1 -0
  164. package/assets/feather/mic-off.svg +1 -0
  165. package/assets/feather/mic.svg +1 -0
  166. package/assets/feather/minimize-2.svg +1 -0
  167. package/assets/feather/minimize.svg +1 -0
  168. package/assets/feather/minus-circle.svg +1 -0
  169. package/assets/feather/minus-square.svg +1 -0
  170. package/assets/feather/minus.svg +1 -0
  171. package/assets/feather/monitor.svg +1 -0
  172. package/assets/feather/moon.svg +1 -0
  173. package/assets/feather/more-horizontal.svg +1 -0
  174. package/assets/feather/more-vertical.svg +1 -0
  175. package/assets/feather/mouse-pointer.svg +1 -0
  176. package/assets/feather/move.svg +1 -0
  177. package/assets/feather/music.svg +1 -0
  178. package/assets/feather/navigation-2.svg +1 -0
  179. package/assets/feather/navigation.svg +1 -0
  180. package/assets/feather/octagon.svg +1 -0
  181. package/assets/feather/package.svg +1 -0
  182. package/assets/feather/paperclip.svg +1 -0
  183. package/assets/feather/pause-circle.svg +1 -0
  184. package/assets/feather/pause.svg +1 -0
  185. package/assets/feather/pen-tool.svg +1 -0
  186. package/assets/feather/percent.svg +1 -0
  187. package/assets/feather/phone-call.svg +1 -0
  188. package/assets/feather/phone-forwarded.svg +1 -0
  189. package/assets/feather/phone-incoming.svg +1 -0
  190. package/assets/feather/phone-missed.svg +1 -0
  191. package/assets/feather/phone-off.svg +1 -0
  192. package/assets/feather/phone-outgoing.svg +1 -0
  193. package/assets/feather/phone.svg +1 -0
  194. package/assets/feather/pie-chart.svg +1 -0
  195. package/assets/feather/play-circle.svg +1 -0
  196. package/assets/feather/play.svg +1 -0
  197. package/assets/feather/plus-circle.svg +1 -0
  198. package/assets/feather/plus-square.svg +1 -0
  199. package/assets/feather/plus.svg +1 -0
  200. package/assets/feather/pocket.svg +1 -0
  201. package/assets/feather/power.svg +1 -0
  202. package/assets/feather/printer.svg +1 -0
  203. package/assets/feather/radio.svg +1 -0
  204. package/assets/feather/refresh-ccw.svg +1 -0
  205. package/assets/feather/refresh-cw.svg +1 -0
  206. package/assets/feather/repeat.svg +1 -0
  207. package/assets/feather/rewind.svg +1 -0
  208. package/assets/feather/rotate-ccw.svg +1 -0
  209. package/assets/feather/rotate-cw.svg +1 -0
  210. package/assets/feather/rss.svg +1 -0
  211. package/assets/feather/save.svg +1 -0
  212. package/assets/feather/scissors.svg +1 -0
  213. package/assets/feather/search.svg +1 -0
  214. package/assets/feather/send.svg +1 -0
  215. package/assets/feather/server.svg +1 -0
  216. package/assets/feather/settings.svg +1 -0
  217. package/assets/feather/share-2.svg +1 -0
  218. package/assets/feather/share.svg +1 -0
  219. package/assets/feather/shield-off.svg +1 -0
  220. package/assets/feather/shield.svg +1 -0
  221. package/assets/feather/shopping-bag.svg +1 -0
  222. package/assets/feather/shopping-cart.svg +1 -0
  223. package/assets/feather/shuffle.svg +1 -0
  224. package/assets/feather/sidebar.svg +1 -0
  225. package/assets/feather/skip-back.svg +1 -0
  226. package/assets/feather/skip-forward.svg +1 -0
  227. package/assets/feather/slack.svg +1 -0
  228. package/assets/feather/slash.svg +1 -0
  229. package/assets/feather/sliders.svg +1 -0
  230. package/assets/feather/smartphone.svg +1 -0
  231. package/assets/feather/smile.svg +1 -0
  232. package/assets/feather/speaker.svg +1 -0
  233. package/assets/feather/square.svg +1 -0
  234. package/assets/feather/star.svg +1 -0
  235. package/assets/feather/stop-circle.svg +1 -0
  236. package/assets/feather/sun.svg +1 -0
  237. package/assets/feather/sunrise.svg +1 -0
  238. package/assets/feather/sunset.svg +1 -0
  239. package/assets/feather/table.svg +1 -0
  240. package/assets/feather/tablet.svg +1 -0
  241. package/assets/feather/tag.svg +1 -0
  242. package/assets/feather/target.svg +1 -0
  243. package/assets/feather/terminal.svg +1 -0
  244. package/assets/feather/thermometer.svg +1 -0
  245. package/assets/feather/thumbs-down.svg +1 -0
  246. package/assets/feather/thumbs-up.svg +1 -0
  247. package/assets/feather/toggle-left.svg +1 -0
  248. package/assets/feather/toggle-right.svg +1 -0
  249. package/assets/feather/tool.svg +1 -0
  250. package/assets/feather/trash-2.svg +1 -0
  251. package/assets/feather/trash.svg +1 -0
  252. package/assets/feather/trello.svg +1 -0
  253. package/assets/feather/trending-down.svg +1 -0
  254. package/assets/feather/trending-up.svg +1 -0
  255. package/assets/feather/triangle.svg +1 -0
  256. package/assets/feather/truck.svg +1 -0
  257. package/assets/feather/tv.svg +1 -0
  258. package/assets/feather/twitch.svg +1 -0
  259. package/assets/feather/twitter.svg +1 -0
  260. package/assets/feather/type.svg +1 -0
  261. package/assets/feather/umbrella.svg +1 -0
  262. package/assets/feather/underline.svg +1 -0
  263. package/assets/feather/unlock.svg +1 -0
  264. package/assets/feather/upload-cloud.svg +1 -0
  265. package/assets/feather/upload.svg +1 -0
  266. package/assets/feather/user-check.svg +1 -0
  267. package/assets/feather/user-minus.svg +1 -0
  268. package/assets/feather/user-plus.svg +1 -0
  269. package/assets/feather/user-x.svg +1 -0
  270. package/assets/feather/user.svg +1 -0
  271. package/assets/feather/users.svg +1 -0
  272. package/assets/feather/video-off.svg +1 -0
  273. package/assets/feather/video.svg +1 -0
  274. package/assets/feather/voicemail.svg +1 -0
  275. package/assets/feather/volume-1.svg +1 -0
  276. package/assets/feather/volume-2.svg +1 -0
  277. package/assets/feather/volume-x.svg +1 -0
  278. package/assets/feather/volume.svg +1 -0
  279. package/assets/feather/watch.svg +1 -0
  280. package/assets/feather/wifi-off.svg +1 -0
  281. package/assets/feather/wifi.svg +1 -0
  282. package/assets/feather/wind.svg +1 -0
  283. package/assets/feather/x-circle.svg +1 -0
  284. package/assets/feather/x-octagon.svg +1 -0
  285. package/assets/feather/x-square.svg +1 -0
  286. package/assets/feather/x.svg +1 -0
  287. package/assets/feather/youtube.svg +1 -0
  288. package/assets/feather/zap-off.svg +1 -0
  289. package/assets/feather/zap.svg +1 -0
  290. package/assets/feather/zoom-in.svg +1 -0
  291. package/assets/feather/zoom-out.svg +1 -0
  292. package/assets/icons/calendar.svg +6 -0
  293. package/assets/icons/check.svg +1 -0
  294. package/assets/icons/close-sm.svg +1 -0
  295. package/assets/icons/close.svg +1 -0
  296. package/assets/icons/copy.svg +1 -0
  297. package/assets/icons/dropdown.svg +8 -0
  298. package/assets/icons/invalid.svg +1 -0
  299. package/assets/icons/menu.svg +1 -0
  300. package/assets/icons/nav-next.svg +1 -0
  301. package/assets/icons/nav-prev.svg +1 -0
  302. package/assets/icons/sort-asc.svg +1 -0
  303. package/assets/icons/sort-desc.svg +1 -0
  304. package/assets/test/README.md +1 -0
  305. package/assets/test/trash.svg +8 -0
  306. package/babel.config.js +16 -0
  307. package/components/PxAspect.vue +127 -0
  308. package/components/PxAutoClamp.vue +75 -0
  309. package/components/PxBalancedText.vue +118 -0
  310. package/components/PxBase.vue +15 -0
  311. package/components/PxBaseDate.vue +27 -0
  312. package/components/PxBaseItems.vue +72 -0
  313. package/components/PxBaseItemsSelect.vue +230 -0
  314. package/components/PxBaseResize.vue +60 -0
  315. package/components/PxBaseToggle.vue +56 -0
  316. package/components/PxBaseVariants.vue +62 -0
  317. package/components/PxBaseVisible.vue +40 -0
  318. package/components/PxCalendar.vue +385 -0
  319. package/components/PxCard.vue +47 -0
  320. package/components/PxCardGrid.vue +386 -0
  321. package/components/PxClock.vue +510 -0
  322. package/components/PxCopyText.vue +78 -0
  323. package/components/PxDatePicker.vue +249 -0
  324. package/components/PxDropdown.vue +181 -0
  325. package/components/PxExpander.vue +46 -0
  326. package/components/PxFeatherIcon.vue +29 -0
  327. package/components/PxFeatherIconButton.vue +19 -0
  328. package/components/PxFit.vue +274 -0
  329. package/components/PxFlex.vue +93 -0
  330. package/components/PxFloat.vue +32 -0
  331. package/components/PxIcon.vue +43 -0
  332. package/components/PxIconButton.vue +115 -0
  333. package/components/PxIdUniquer.vue +59 -0
  334. package/components/PxModal.vue +365 -0
  335. package/components/PxNineGrid.vue +94 -0
  336. package/components/PxPivot.vue +207 -0
  337. package/components/PxPopup.vue +230 -0
  338. package/components/PxPortal.vue +138 -0
  339. package/components/PxPortalTarget.vue +25 -0
  340. package/components/PxProgressCircle.vue +73 -0
  341. package/components/PxRadioButton.vue +83 -0
  342. package/components/PxSideDrawer.vue +164 -0
  343. package/components/PxSlideTransition.vue +116 -0
  344. package/components/PxSlides.vue +217 -0
  345. package/components/PxStylesPreview.vue +129 -0
  346. package/components/PxSvg.vue +157 -0
  347. package/components/PxSwiper.vue +271 -0
  348. package/components/PxSwiperSlide.vue +42 -0
  349. package/components/PxSyncHeight.vue +137 -0
  350. package/components/PxTable.vue +323 -0
  351. package/components/PxTabs.vue +1 -0
  352. package/components/PxTextbox.vue +90 -0
  353. package/components/PxToggle.vue +125 -0
  354. package/components/PxToggleButton.vue +139 -0
  355. package/components/PxToggleButtonList.vue +131 -0
  356. package/components/PxTransitionExpand.vue +100 -0
  357. package/components/PxValidator.vue +431 -0
  358. package/components/PxVueTest.vue +761 -0
  359. package/components/README.md +0 -0
  360. package/dev/data/fruits.js +59 -0
  361. package/dev/data/random.js +13 -0
  362. package/dev/demos/Demo-PxBaseDrag.vue +94 -0
  363. package/dev/demos/Demo-PxCardGrid.vue +53 -0
  364. package/dev/demos/Demo-PxPivot.vue +58 -0
  365. package/dev/demos/Demo-PxSideDrawer.vue +72 -0
  366. package/dev/demos/Demo-PxSlideTransition.vue +86 -0
  367. package/dev/demos/Demo-PxSlides.vue +142 -0
  368. package/dev/demos/Demo-PxStylesPreview.vue +46 -0
  369. package/dev/demos/Demo-PxSwiper.vue +44 -0
  370. package/dev/demos/DemoPicker.vue +79 -0
  371. package/dev/dev.vue +56 -0
  372. package/dev/serve.js +17 -0
  373. package/package.json +45 -0
  374. package/plugins/common-client.js +13 -0
  375. package/plugins/common-lib.js +4 -0
  376. package/plugins/common.js +39 -0
  377. package/plugins/filters/aspect.js +14 -0
  378. package/plugins/filters/date.js +26 -0
  379. package/plugins/filters/kebab.js +9 -0
  380. package/plugins/filters/phone.js +7 -0
  381. package/plugins/filters/slug.js +26 -0
  382. package/plugins/filters/spacenator.js +11 -0
  383. package/plugins/filters/stringToItems.js +28 -0
  384. package/plugins/filters/striphtml.js +10 -0
  385. package/plugins/mixins/eventBus.js +23 -0
  386. package/px-styles.config.scss +12 -0
  387. package/styles/helpers.scss +14 -0
  388. package/styles/px.scss +6 -0
  389. package/utils/balanceText.js +123 -0
  390. package/utils/bem.js +99 -0
  391. package/utils/cardGrid.js +383 -0
  392. package/utils/cssStr.js +45 -0
  393. package/utils/drag.js +363 -0
  394. package/utils/fit.js +73 -0
  395. package/utils/tween.js +129 -0
  396. package/utils/utils.js +167 -0
  397. package/utils/variants.js +33 -0
  398. package/vue.config.js +12 -0
@@ -0,0 +1,230 @@
1
+ <!--
2
+
3
+ Simple popup attached to a reference element. Most common scenarios would be tooltips or menus.
4
+ Uses popper.js for placement and PxModal for the popup itself. Has built in support for click
5
+ and hover triggers.
6
+
7
+ Usage as a menu:
8
+
9
+ <px-popup tag="button" trigger="click">
10
+
11
+ Button Label
12
+
13
+ <template #popup>
14
+ <div class="popup-menu">
15
+ <button>Menu Option 1</button>
16
+ <button>Menu Option 2</button>
17
+ </div>
18
+ </template>
19
+ </px-popup>
20
+
21
+ Usage as a tooltip:
22
+
23
+ <px-popup trigger="hover" tag="a" href="https://thinkpixellab.com">
24
+ Pixel Lab
25
+ <template #popup>
26
+ <div class="tooltip">
27
+ Best website ever!
28
+ </div>
29
+ </template>
30
+ </px-popup>
31
+
32
+ -->
33
+ <template>
34
+ <component
35
+ :is="tag"
36
+ :class="bem()"
37
+ @click="onClick"
38
+ @contextmenu.stop="onContextMenu"
39
+ @mouseenter="onMouseEnter"
40
+ @mouseleave="onMouseLeave"
41
+ >
42
+ <slot name="default" />
43
+ <px-modal v-if="calcUseModal" :visible.sync="syncPopupVisible" v-bind="modalAttrs">
44
+ <div
45
+ ref="popup"
46
+ :class="[bem('popup'), popupClass]"
47
+ :style="{
48
+ minWidth: cssPx(popupMinWidth),
49
+ maxWidth: setPopupMaxWidth ? cssPx(popupMinWidth) : null,
50
+ }"
51
+ >
52
+ <slot name="popup" />
53
+ </div>
54
+ </px-modal>
55
+ <div v-else>
56
+ <div
57
+ ref="popup"
58
+ :class="[bem('popup', { nonModal: true }), popupClass]"
59
+ :style="{
60
+ minWidth: cssPx(popupMinWidth),
61
+ maxWidth: setPopupMaxWidth ? cssPx(popupMinWidth) : null,
62
+ }"
63
+ v-show="syncPopupVisible"
64
+ >
65
+ <slot name="popup" />
66
+ </div>
67
+ </div>
68
+ </component>
69
+ </template>
70
+
71
+ <script>
72
+ import PxBase from './PxBase.vue';
73
+ import PxModal from './PxModal.vue';
74
+ import { createPopper } from '@popperjs/core';
75
+ export default {
76
+ name: 'px-popup',
77
+ components: { PxModal },
78
+ mixins: [PxBase],
79
+ props: {
80
+ // the tag to use for the primary / root / reference element
81
+ tag: { type: String, default: 'button' },
82
+
83
+ // automatically toggle popup visibility on click or hover, possible values: click, hover, contextmenu
84
+ trigger: { type: String, default: 'click' },
85
+
86
+ // whether the popup is visible (syncable)
87
+ popupVisible: { type: Boolean, default: false },
88
+
89
+ // the placement strategy to use with popper.js, possible values: fixed, absolute
90
+ strategy: { type: String, default: 'fixed' },
91
+
92
+ // the placement of the popup (proxy for popper.js placement), possible values are: auto,
93
+ // auto-start, auto-end, top, top-start, top-end, bottom, bottom-start, bottom-end, right,
94
+ // right-start, right-end, left, left-start, left-end
95
+ placement: { type: String, default: 'bottom' },
96
+
97
+ // the number of pixels to shift the popup in the direction perpendicular to it's alignment,
98
+ // e.g. if placement is bottom-start then a value of -10 would shift the popup 10px to the
99
+ // left (in non-rtl layouts)
100
+ skidding: { type: Number, default: 0 },
101
+
102
+ // additional spacing between the main element and popup in px
103
+ distance: { type: Number, default: 0 },
104
+
105
+ // whether to use PxModal for the popup, leave as null for auto based on trigger (click =>
106
+ // true, hover => false)
107
+ useModal: { type: Boolean, default: null },
108
+
109
+ // properties that get passed to the modal element (see PxModal for details)
110
+ modalAttrs: { default: null },
111
+
112
+ // class that gets set on the popup element
113
+ popupClass: { default: null },
114
+
115
+ // for the popup to be at least as wide as the reference element
116
+ setPopupMinWidth: { type: Boolean, default: true },
117
+
118
+ // for the popup to never be wider than the reference element
119
+ setPopupMaxWidth: { type: Boolean, default: false },
120
+ },
121
+
122
+ data() {
123
+ return { syncPopupVisible: this.popupVisible, popupMinWidth: null };
124
+ },
125
+
126
+ watch: {
127
+ popupVisible(nv) {
128
+ // update syncPopupVisible when visible changes
129
+ this.syncPopupVisible = nv;
130
+ },
131
+
132
+ async syncPopupVisible(nv) {
133
+ // emit update when syncPopupVisible changes (enables .sync on parent)
134
+ this.$emit('update:popupVisible', nv);
135
+
136
+ if (nv) {
137
+ if (this.setPopupMinWidth) {
138
+ this.popupMinWidth = this.$el.getBoundingClientRect().width;
139
+ } else {
140
+ this.popupMinWidth = null;
141
+ }
142
+
143
+ let popperOptions = {
144
+ placement: this.placement,
145
+ strategy: this.strategy,
146
+ modifiers: [
147
+ {
148
+ name: 'offset',
149
+ options: {
150
+ offset: [this.skidding, this.distance],
151
+ },
152
+ },
153
+ ],
154
+ };
155
+
156
+ if (this.calcUseModal) {
157
+ // if we're using a modal we need to delay the creation of the popper so that
158
+ // we have the popup element in the right place in the DOM
159
+ await this.$nextTick();
160
+ await this.$nextTick();
161
+ this.popper = createPopper(this.$el, this.$refs.popup, popperOptions);
162
+ } else {
163
+ // but if we don't have a modal, we want to create it immediately to avoid
164
+ // layout flashes
165
+ this.popper = createPopper(this.$el, this.$refs.popup, popperOptions);
166
+ }
167
+ } else {
168
+ if (this.popper) {
169
+ await this.$nextTick();
170
+ this.popper.destroy();
171
+ }
172
+ }
173
+ },
174
+ },
175
+ computed: {
176
+ calcUseModal() {
177
+ if (this.useModal === null) {
178
+ return this.trigger != 'hover';
179
+ }
180
+ return this.useModal;
181
+ },
182
+ },
183
+ methods: {
184
+ openPopup() {
185
+ this.syncPopupVisible = true;
186
+ },
187
+ closePopup() {
188
+ this.syncPopupVisible = false;
189
+ },
190
+ togglePopup() {
191
+ this.syncPopupVisible = !this.syncPopupVisible;
192
+ },
193
+ onClick() {
194
+ if (this.trigger == 'click') {
195
+ this.syncPopupVisible = !this.syncPopupVisible;
196
+ }
197
+ },
198
+ onContextMenu(e) {
199
+ if (this.trigger == 'contextmenu') {
200
+ e.stopPropagation();
201
+ e.preventDefault();
202
+ this.syncPopupVisible = !this.syncPopupVisible;
203
+ }
204
+ },
205
+ onMouseEnter() {
206
+ if (this.trigger == 'hover') {
207
+ this.syncPopupVisible = true;
208
+ }
209
+ },
210
+ onMouseLeave() {
211
+ if (this.trigger == 'hover') {
212
+ this.syncPopupVisible = false;
213
+ }
214
+ },
215
+ },
216
+ };
217
+ </script>
218
+
219
+ <style lang="scss">
220
+ @use '../styles/px.scss' as *;
221
+
222
+ .px-popup {
223
+ display: inline-block;
224
+
225
+ @include bem('popup', 'non-modal') {
226
+ position: absolute;
227
+ z-index: 1;
228
+ }
229
+ }
230
+ </style>
@@ -0,0 +1,138 @@
1
+ <script>
2
+ // Based on this: https://github.com/LinusBorg/vue-simple-portal
3
+ // The npm version used a conflicting version of Vue and had an issue that prevented proper render
4
+
5
+ import PxPortalTarget from './PxPortalTarget';
6
+
7
+ let uniqueIdIterator = 1000;
8
+ let isBrowser = !process.server && typeof window !== 'undefined' && typeof document !== undefined;
9
+
10
+ export default {
11
+ name: 'PxPortal',
12
+ props: {
13
+ disabled: { type: Boolean },
14
+ prepend: { type: Boolean },
15
+ selectorPrefix: { type: String, default: 'px-portal-' },
16
+ selector: { type: String, default: null },
17
+ tag: { type: String, default: 'DIV' },
18
+ },
19
+ computed: {
20
+ computedSelector() {
21
+ return this.selector
22
+ ? this.selector
23
+ : `#${this.selectorPrefix}${(uniqueIdIterator++ + '').padStart(4, '0')}`;
24
+ },
25
+ },
26
+ watch: {
27
+ disabled: {
28
+ immediate: true,
29
+ handler(disabled) {
30
+ if (!process.server) {
31
+ if (disabled) {
32
+ this.unmount();
33
+ } else {
34
+ this.$nextTick(this.mount);
35
+ }
36
+ }
37
+ },
38
+ },
39
+ },
40
+ mounted() {
41
+ if (!this.getTargetEl()) {
42
+ this.insertTargetEl();
43
+ }
44
+ },
45
+ updated() {
46
+ // We only update the target container component if the scoped slot function is a fresh one
47
+ // The new slot syntax (since Vue 2.6) can cache unchanged slot functions and we want to
48
+ // respect that here.
49
+
50
+ this.$nextTick(() => {
51
+ if (!this.disabled && this.slotFn !== this.$scopedSlots.default) {
52
+ this.container.updatedNodes = this.$scopedSlots.default;
53
+ }
54
+ this.slotFn = this.$scopedSlots.default;
55
+ });
56
+ },
57
+ beforeDestroy() {
58
+ this.unmount();
59
+ },
60
+ methods: {
61
+ // This returns the element into which the content should be mounted.
62
+ getTargetEl() {
63
+ if (!isBrowser) return;
64
+ return document.querySelector(this.computedSelector);
65
+ },
66
+ insertTargetEl() {
67
+ if (!isBrowser) return;
68
+ const parent = document.body;
69
+ const child = document.createElement(this.tag);
70
+ if (parent && child) {
71
+ child.id = this.computedSelector.substring(1);
72
+ try {
73
+ parent.appendChild(child);
74
+ } catch (error) {
75
+ console.error('PxPortal: insertTargetEl failure');
76
+ console.error(error);
77
+ console.log(parent);
78
+ console.log(child);
79
+ throw error;
80
+ }
81
+ }
82
+ },
83
+ mount() {
84
+ if (!isBrowser) return;
85
+
86
+ const targetEl = this.getTargetEl();
87
+ if (targetEl) {
88
+ this.portal = document.createElement('DIV');
89
+ if (this.prepend && targetEl.firstChild) {
90
+ targetEl.insertBefore(this.portal, targetEl.firstChild);
91
+ } else {
92
+ try {
93
+ targetEl.appendChild(this.portal);
94
+ } catch (error) {
95
+ console.error('PxPortal: mount failure');
96
+ console.error(error);
97
+ console.log(targetEl);
98
+ console.log(this.portal);
99
+ throw error;
100
+ }
101
+ }
102
+
103
+ this.container = new PxPortalTarget({
104
+ el: this.portal,
105
+ parent: this,
106
+ propsData: {
107
+ tag: this.tag,
108
+ nodes: this.$scopedSlots.default,
109
+ },
110
+ });
111
+ }
112
+ },
113
+ unmount() {
114
+ if (this.container) {
115
+ this.container.$destroy();
116
+ delete this.container;
117
+ }
118
+
119
+ // clean up auto-created target el
120
+ if (!this.selector) {
121
+ let targetElement = this.getTargetEl();
122
+ if (targetElement) {
123
+ targetElement.remove();
124
+ }
125
+ }
126
+ },
127
+ },
128
+ render(h) {
129
+ if (!isBrowser) return;
130
+ if (this.disabled) {
131
+ const nodes = this.$scopedSlots && this.$scopedSlots.default();
132
+ if (!nodes) return h();
133
+ return nodes.length < 2 && !nodes[0].text ? nodes : h(this.tag, nodes);
134
+ }
135
+ return h();
136
+ },
137
+ };
138
+ </script>
@@ -0,0 +1,25 @@
1
+ <script>
2
+ import Vue from 'vue';
3
+ export default Vue.extend({
4
+ // as an abstract component, it doesn't appear in the $parent chain of components. which means
5
+ // the next parent of any component rendered inside of this oen will be the parent from which is
6
+ // was portal'd
7
+ abstract: true,
8
+ name: 'PxPortalTarget',
9
+
10
+ // eslint-disable-next-line vue/require-prop-types
11
+ props: ['nodes', 'tag'],
12
+ data: vm => ({
13
+ updatedNodes: vm.nodes,
14
+ }),
15
+ destroyed() {
16
+ const { $el: el } = this;
17
+ el.parentNode.removeChild(el);
18
+ },
19
+ render(h) {
20
+ const nodes = this.updatedNodes && this.updatedNodes();
21
+ if (!nodes) return h();
22
+ return nodes.length < 2 && !nodes[0].text ? nodes : h(this.tag || 'DIV', nodes);
23
+ },
24
+ });
25
+ </script>
@@ -0,0 +1,73 @@
1
+ <!--
2
+ Basic circular progress bar that uses SVG and stroke offset to produce the effect. Stroke
3
+ color is derived from currentColor. Sizes to container and maintains a 1:1 aspect.
4
+
5
+ <px-progress-circle stroke-width="4" progress=".5" :style="{color: green}" />
6
+
7
+ -->
8
+ <template>
9
+ <div :class="bem()" v-resize="resize">
10
+ <svg
11
+ width="100%"
12
+ height="100%"
13
+ :viewBox="`0 0 ${width} ${width}`"
14
+ version="1.1"
15
+ xmlns="http://www.w3.org/2000/svg"
16
+ xmlns:xlink="http://www.w3.org/1999/xlink"
17
+ >
18
+ <circle
19
+ stroke="currentColor"
20
+ :stroke-width="strokeWidth"
21
+ :stroke-dasharray="strokeDashArray"
22
+ fill="transparent"
23
+ :cx="width ? width / 2 : 0"
24
+ :cy="width ? width / 2 : 0"
25
+ :r="width ? Math.max(0, width / 2 - strokeWidth / 2) : 0"
26
+ ></circle>
27
+ </svg>
28
+ </div>
29
+ </template>
30
+
31
+ <script>
32
+ import PxBase from './PxBase.vue';
33
+
34
+ export default {
35
+ name: 'progress-circle',
36
+ mixins: [PxBase],
37
+ props: {
38
+ strokeWidth: { type: Number, default: 10 },
39
+ progress: { type: Number, default: 0 },
40
+ },
41
+ data() {
42
+ return { width: 0, p: 0 };
43
+ },
44
+ computed: {
45
+ strokeDashArray() {
46
+ let c = (this.width - this.strokeWidth) * Math.PI;
47
+ return `${c * Math.max(0, Math.min(1, this.progress))},${c}`;
48
+ },
49
+ },
50
+ mounted() {
51
+ this.resize();
52
+ },
53
+ methods: {
54
+ resize() {
55
+ this.width = this.$el.getBoundingClientRect()?.width;
56
+ },
57
+ },
58
+ };
59
+ </script>
60
+
61
+ <style lang="scss">
62
+ @use '../styles/px.scss' as *;
63
+ .progress-circle {
64
+ aspect-ratio: 1;
65
+ font-size: 0;
66
+ svg {
67
+ width: 100%;
68
+ height: 100%;
69
+ display: block;
70
+ transform: rotate(-90deg);
71
+ }
72
+ }
73
+ </style>
@@ -0,0 +1,83 @@
1
+ <!--
2
+ Creates a toggle button (a control with the appearance of a normal button that can be toggle
3
+ between an on/off state).
4
+
5
+ <px-radio-button v-model="checked" />
6
+ -->
7
+
8
+ <template>
9
+ <button
10
+ :class="[
11
+ bem({ checked: syncChecked, ...variantsMap }),
12
+ checkedClass && syncChecked ? checkedClass : null,
13
+ ]"
14
+ :aria-checked="syncChecked"
15
+ role="radio"
16
+ v-on="$listeners"
17
+ @click="toggleChecked"
18
+ >
19
+ <div :class="bem('check', { checked: syncChecked })"></div>
20
+ <slot />
21
+ </button>
22
+ </template>
23
+
24
+ <script>
25
+ import PxBaseToggle from './PxBaseToggle.vue';
26
+ import PxBaseVariants from './PxBaseVariants.vue';
27
+
28
+ export default {
29
+ name: 'px-radio-button',
30
+ mixins: [PxBaseToggle, PxBaseVariants],
31
+ };
32
+ </script>
33
+
34
+ <style lang="scss">
35
+ @use '../styles/px.scss' as *;
36
+
37
+ .px-radio-button {
38
+ @include control-reset();
39
+ background: transparent;
40
+
41
+ &--default {
42
+ display: inline-flex;
43
+ align-items: center;
44
+ cursor: pointer;
45
+
46
+ &:hover {
47
+ @include bem(check) {
48
+ &:after {
49
+ opacity: 0.5;
50
+ }
51
+ }
52
+ }
53
+
54
+ @include bem(check) {
55
+ width: 1.2em;
56
+ height: 1.2em;
57
+ border-radius: 50%;
58
+ border: 1px solid currentColor;
59
+ margin-right: 0.5em;
60
+ position: relative;
61
+ padding: 0.25em;
62
+ box-sizing: border-box;
63
+ flex: none;
64
+ @include after() {
65
+ width: 100%;
66
+ height: 100%;
67
+ border-radius: 50%;
68
+ background-color: accent();
69
+ opacity: 0;
70
+ }
71
+
72
+ &--checked {
73
+ &:after {
74
+ opacity: 1 !important;
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ @include block(px-radio-button, 'default') {
82
+ }
83
+ </style>