fleetio_spark 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +43 -0
  4. data/app/assets/javascripts/spark/_cookie.js +23 -0
  5. data/app/assets/javascripts/spark/_esvg.js +73 -0
  6. data/app/assets/javascripts/spark/_icons.js +19 -0
  7. data/app/assets/javascripts/spark/_modal.js +421 -0
  8. data/app/assets/javascripts/spark/_search.js +79 -0
  9. data/app/assets/javascripts/spark/_sidebar.js +13 -0
  10. data/app/assets/javascripts/spark/_stack.js +248 -0
  11. data/app/assets/javascripts/spark/_tree.js +68 -0
  12. data/app/assets/javascripts/spark/shims/_dataset.js +241 -0
  13. data/app/assets/javascripts/spark/spark.js +31 -0
  14. data/app/assets/stylesheets/spark/_icons.scss +15 -0
  15. data/app/assets/stylesheets/spark/_index.scss +5 -0
  16. data/app/assets/stylesheets/spark/components/_index.scss +6 -0
  17. data/app/assets/stylesheets/spark/components/_modal.scss +73 -0
  18. data/app/assets/stylesheets/spark/components/_nav-menu.scss +102 -0
  19. data/app/assets/stylesheets/spark/components/_sidebar.scss +280 -0
  20. data/app/assets/stylesheets/spark/components/_tooltip.scss +42 -0
  21. data/app/assets/stylesheets/spark/components/_tree-nav.scss +13 -0
  22. data/app/assets/stylesheets/spark/components/header/_app-admin-header.scss +82 -0
  23. data/app/assets/stylesheets/spark/components/header/_app-nav-header.scss +154 -0
  24. data/app/assets/stylesheets/spark/components/header/_index.scss +5 -0
  25. data/app/assets/stylesheets/spark/components/header/_search-results.scss +29 -0
  26. data/app/assets/stylesheets/spark/components/header/_search.scss +195 -0
  27. data/app/assets/stylesheets/spark/components/header/_trial-status.scss +43 -0
  28. data/app/assets/stylesheets/spark/core/_animations.scss +154 -0
  29. data/app/assets/stylesheets/spark/core/_base.scss +11 -0
  30. data/app/assets/stylesheets/spark/core/_colors.scss +94 -0
  31. data/app/assets/stylesheets/spark/core/_index.scss +7 -0
  32. data/app/assets/stylesheets/spark/core/_layout.scss +39 -0
  33. data/app/assets/stylesheets/spark/core/_mixins.scss +86 -0
  34. data/app/assets/stylesheets/spark/core/_text.scss +5 -0
  35. data/app/assets/stylesheets/spark/core/_vars.scss +76 -0
  36. data/app/assets/stylesheets/spark/form/_base.scss +124 -0
  37. data/app/assets/stylesheets/spark/form/_check-switch.scss +99 -0
  38. data/app/assets/stylesheets/spark/form/_index.scss +2 -0
  39. data/app/assets/stylesheets/spark/spark.scss +1 -0
  40. data/app/assets/svgs/spark/add.svg +3 -0
  41. data/app/assets/svgs/spark/admin-user.svg +5 -0
  42. data/app/assets/svgs/spark/chevron-down.svg +3 -0
  43. data/app/assets/svgs/spark/chevron-up.svg +3 -0
  44. data/app/assets/svgs/spark/close.svg +3 -0
  45. data/app/assets/svgs/spark/contact.svg +6 -0
  46. data/app/assets/svgs/spark/dashboard.svg +3 -0
  47. data/app/assets/svgs/spark/fuel.svg +3 -0
  48. data/app/assets/svgs/spark/inspection.svg +3 -0
  49. data/app/assets/svgs/spark/issue.svg +3 -0
  50. data/app/assets/svgs/spark/leaderboard.svg +5 -0
  51. data/app/assets/svgs/spark/logo.svg +1 -0
  52. data/app/assets/svgs/spark/map.svg +4 -0
  53. data/app/assets/svgs/spark/nav-menu.svg +5 -0
  54. data/app/assets/svgs/spark/part.svg +6 -0
  55. data/app/assets/svgs/spark/place.svg +5 -0
  56. data/app/assets/svgs/spark/question.svg +10 -0
  57. data/app/assets/svgs/spark/reminder.svg +3 -0
  58. data/app/assets/svgs/spark/report.svg +5 -0
  59. data/app/assets/svgs/spark/search.svg +3 -0
  60. data/app/assets/svgs/spark/service.svg +3 -0
  61. data/app/assets/svgs/spark/settings.svg +3 -0
  62. data/app/assets/svgs/spark/trip.svg +4 -0
  63. data/app/assets/svgs/spark/vehicle.svg +3 -0
  64. data/app/assets/svgs/spark/vendor.svg +4 -0
  65. data/app/helpers/spark/application_helper.rb +42 -0
  66. data/app/helpers/spark/icon_helper.rb +40 -0
  67. data/app/helpers/spark/input_helper.rb +163 -0
  68. data/app/helpers/spark/menu_helper.rb +113 -0
  69. data/app/helpers/spark/modal_helper.rb +52 -0
  70. data/app/helpers/spark/nav_menu_helper.rb +167 -0
  71. data/app/helpers/spark/tag_helper.rb +27 -0
  72. data/app/helpers/spark/trial_helper.rb +23 -0
  73. data/app/views/layouts/spark/application.html.slim +28 -0
  74. data/app/views/layouts/spark/blank.html.slim +9 -0
  75. data/app/views/layouts/spark/default.html.slim +13 -0
  76. data/config/autoprefixer.yml +4 -0
  77. data/config/esvg.yml +20 -0
  78. data/lib/fleetio_spark.rb +14 -0
  79. data/lib/fleetio_spark/helper.rb +163 -0
  80. data/lib/fleetio_spark/version.rb +3 -0
  81. data/public/spark-0.1.0.css +1442 -0
  82. data/public/spark-0.1.0.css.gz +0 -0
  83. data/public/spark-0.1.0.js +11927 -0
  84. data/public/spark-0.1.0.js.gz +0 -0
  85. metadata +211 -0
@@ -0,0 +1,4 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M19.012 14.552C18.9988 14.5198 18.9787 14.4908 18.9531 14.4671C18.9276 14.4435 18.8971 14.4257 18.864 14.415C18.5501 14.3134 18.2667 14.1346 18.04 13.895C16.34 12.08 13.5 8.609 13.5 5.75C13.5 5.579 13.509 5.411 13.524 5.244C13.539 5.077 13.604 4.75 13.275 4.75H12C11.9337 4.75 11.8701 4.77634 11.8232 4.82322C11.7763 4.87011 11.75 4.9337 11.75 5V7.75C11.75 7.94891 11.6709 8.13968 11.5303 8.28033C11.3896 8.42098 11.1989 8.5 11 8.5C10.801 8.5 10.6103 8.42098 10.4696 8.28033C10.329 8.13968 10.25 7.94891 10.25 7.75V5C10.25 4.9337 10.2236 4.87011 10.1767 4.82322C10.1299 4.77634 10.0663 4.75 9.99996 4.75H7.18096C7.08059 4.75006 6.98256 4.78033 6.89963 4.83687C6.81669 4.8934 6.7527 4.97359 6.71596 5.067L0.0339605 22.067C0.00412291 22.1429 -0.00671146 22.2249 0.00240122 22.3059C0.0115139 22.3869 0.0402972 22.4645 0.0862436 22.5318C0.13219 22.5991 0.193906 22.6542 0.266014 22.6923C0.338123 22.7303 0.418437 22.7501 0.49996 22.75H9.99996C10.0663 22.75 10.1299 22.7237 10.1767 22.6768C10.2236 22.6299 10.25 22.5663 10.25 22.5V19.75C10.25 19.5511 10.329 19.3603 10.4696 19.2197C10.6103 19.079 10.801 19 11 19C11.1989 19 11.3896 19.079 11.5303 19.2197C11.6709 19.3603 11.75 19.5511 11.75 19.75V22.5C11.75 22.5663 11.7763 22.6299 11.8232 22.6768C11.8701 22.7237 11.9337 22.75 12 22.75H21.5C21.5815 22.7501 21.6618 22.7303 21.7339 22.6923C21.806 22.6542 21.8677 22.5991 21.9137 22.5318C21.9596 22.4645 21.9884 22.3869 21.9975 22.3059C22.0066 22.2249 21.9958 22.1429 21.966 22.067L19.012 14.552ZM11.75 15.752C11.75 15.9509 11.6709 16.1417 11.5303 16.2823C11.3896 16.423 11.1989 16.502 11 16.502C10.801 16.502 10.6103 16.423 10.4696 16.2823C10.329 16.1417 10.25 15.9509 10.25 15.752V11.752C10.25 11.5531 10.329 11.3623 10.4696 11.2217C10.6103 11.081 10.801 11.002 11 11.002C11.1989 11.002 11.3896 11.081 11.5303 11.2217C11.6709 11.3623 11.75 11.5531 11.75 11.752V15.752Z" fill="black"/>
3
+ <path d="M19.864 12.87C20.935 11.723 24 8.226 24 5.75C24 4.55653 23.5259 3.41193 22.682 2.56802C21.8381 1.72411 20.6935 1.25 19.5 1.25C18.3065 1.25 17.1619 1.72411 16.318 2.56802C15.4741 3.41193 15 4.55653 15 5.75C15 8.226 18.065 11.723 19.136 12.87C19.1827 12.9196 19.2392 12.9592 19.3018 12.9862C19.3643 13.0133 19.4318 13.0272 19.5 13.0272C19.5682 13.0272 19.6357 13.0133 19.6982 12.9862C19.7608 12.9592 19.8173 12.9196 19.864 12.87V12.87ZM18 5.75C18 5.45333 18.088 5.16332 18.2528 4.91664C18.4176 4.66997 18.6519 4.47771 18.926 4.36418C19.2001 4.25065 19.5017 4.22094 19.7926 4.27882C20.0836 4.3367 20.3509 4.47956 20.5607 4.68934C20.7704 4.89912 20.9133 5.16639 20.9712 5.45736C21.0291 5.74834 20.9993 6.04994 20.8858 6.32403C20.7723 6.59811 20.58 6.83238 20.3334 6.9972C20.0867 7.16203 19.7967 7.25 19.5 7.25C19.1022 7.25 18.7206 7.09196 18.4393 6.81066C18.158 6.52936 18 6.14782 18 5.75Z" fill="black"/>
4
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M22.1929 10.3308C22.2048 10.3578 22.2214 10.3826 22.242 10.404C23.048 11.2339 23.4992 12.3451 23.5 13.502V15.502C23.4984 16.0032 23.3457 16.4924 23.0618 16.9055C22.7966 17.2916 22.4284 17.5946 22 17.7806V20C22 20.5523 21.5523 21 21 21H19C18.4477 21 18 20.5523 18 20V17.8172L6 17.8148V20C6 20.5523 5.55228 21 5 21H3C2.44772 21 2 20.5523 2 20V17.7766C1.57156 17.5906 1.20334 17.2876 0.938115 16.9015C0.654299 16.4884 0.501613 15.9992 0.499983 15.498V13.498C0.501514 12.3436 0.951506 11.2349 1.75498 10.406C1.78137 10.3786 1.80119 10.3455 1.81297 10.3093L1.81341 10.3088C1.81453 10.3042 1.81553 10.2995 1.81639 10.2947C1.82517 10.2465 1.81956 10.1967 1.80027 10.1517C1.78098 10.1066 1.74885 10.0681 1.70789 10.0412C1.66693 10.0142 1.61894 9.9999 1.5699 10H1.28198C1.01677 10 0.762411 9.89464 0.574875 9.70711C0.387338 9.51957 0.281982 9.26522 0.281982 9V8C0.281982 7.73478 0.387338 7.48043 0.574875 7.29289C0.762411 7.10536 1.01677 7 1.28198 7H2.63198C2.86474 7.00062 3.0942 7.0551 3.30238 7.1592C3.4838 7.24991 3.64477 7.37614 3.77591 7.53007L3.78758 7.50165C3.81197 7.46945 3.82823 7.43184 3.83498 7.39201L4.23498 5.00901C4.34955 4.30737 4.71029 3.66948 5.25253 3.2097C5.79477 2.74992 6.48305 2.49832 7.19398 2.50001H16.802C17.5126 2.49825 18.2007 2.74956 18.7429 3.20894C19.2851 3.66832 19.646 4.30574 19.761 5.00701L20.161 7.39001C20.1676 7.42981 20.1837 7.46743 20.208 7.49964C20.2145 7.50829 20.2216 7.51648 20.2291 7.52417C20.3593 7.37291 20.5185 7.24874 20.6976 7.1592C20.9058 7.0551 21.1352 7.00062 21.368 7H22.718C22.9832 7 23.2376 7.10536 23.4251 7.29289C23.6126 7.48043 23.718 7.73478 23.718 8V9C23.718 9.26522 23.6126 9.51957 23.4251 9.70711C23.2376 9.89464 22.9832 10 22.718 10H22.4301C22.381 9.9999 22.333 10.0142 22.2921 10.0412C22.2511 10.0681 22.219 10.1066 22.1997 10.1517C22.1804 10.1967 22.1748 10.2465 22.1836 10.2947C22.1858 10.307 22.1889 10.3191 22.1929 10.3308ZM7.19398 4.50201H16.806C17.0427 4.50212 17.2717 4.58619 17.4522 4.73927C17.6328 4.89235 17.7532 5.10451 17.792 5.33801L18.271 8.21101C18.2763 8.24641 18.2741 8.28254 18.2645 8.31702C18.2548 8.3515 18.2379 8.38353 18.215 8.41101C18.1915 8.43867 18.1622 8.46087 18.1292 8.47607C18.0962 8.49127 18.0603 8.49909 18.024 8.49901H5.97598C5.93965 8.49907 5.90374 8.4912 5.87076 8.47597C5.83778 8.46073 5.80851 8.43849 5.785 8.41079C5.76149 8.38309 5.7443 8.3506 5.73462 8.31558C5.72495 8.28056 5.72302 8.24385 5.72898 8.20801L6.20798 5.33501C6.24744 5.10206 6.3681 4.8906 6.54859 4.73812C6.72907 4.58565 6.95771 4.502 7.19398 4.50201ZM7 13.5C7 14.3284 6.32843 15 5.5 15C4.67157 15 4 14.3284 4 13.5C4 12.6716 4.67157 12 5.5 12C6.32843 12 7 12.6716 7 13.5ZM18.5 15C19.3284 15 20 14.3284 20 13.5C20 12.6716 19.3284 12 18.5 12C17.6716 12 17 12.6716 17 13.5C17 14.3284 17.6716 15 18.5 15Z" fill="black"/>
3
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M21.379 11.9C20.8074 11.8915 20.2455 11.7506 19.7375 11.4884C19.2295 11.2263 18.7891 10.8499 18.451 10.389C18.4277 10.358 18.3975 10.3328 18.3628 10.3154C18.3281 10.298 18.2898 10.289 18.251 10.289C18.2122 10.289 18.1739 10.298 18.1392 10.3154C18.1045 10.3328 18.0743 10.358 18.051 10.389C17.7189 10.8563 17.2799 11.2373 16.7705 11.5002C16.2611 11.7631 15.6962 11.9003 15.123 11.9003C14.5498 11.9003 13.9849 11.7631 13.4755 11.5002C12.9661 11.2373 12.527 10.8563 12.195 10.389C12.1717 10.358 12.1415 10.3328 12.1068 10.3154C12.0721 10.298 12.0338 10.289 11.995 10.289C11.9562 10.289 11.9179 10.298 11.8832 10.3154C11.8485 10.3328 11.8183 10.358 11.795 10.389C11.4576 10.849 11.0183 11.2248 10.5116 11.4869C10.0049 11.749 9.44441 11.8904 8.87399 11.9C8.30221 11.8916 7.74016 11.7508 7.23196 11.4886C6.72376 11.2265 6.28324 10.8501 5.94499 10.389C5.9217 10.358 5.89151 10.3328 5.85679 10.3154C5.82208 10.298 5.7838 10.289 5.74499 10.289C5.70618 10.289 5.6679 10.298 5.63319 10.3154C5.59847 10.3328 5.56828 10.358 5.54499 10.389C5.20725 10.8494 4.76753 11.2254 4.26025 11.4875C3.75298 11.7497 3.19192 11.8908 2.62099 11.9C2.49268 11.8998 2.36449 11.8924 2.23699 11.878C2.20194 11.8739 2.16642 11.8773 2.13278 11.8879C2.09913 11.8986 2.06814 11.9163 2.04186 11.9398C2.01557 11.9634 1.99459 11.9922 1.9803 12.0245C1.96601 12.0568 1.95875 12.0917 1.95899 12.127V21.15C1.95899 21.5478 2.11703 21.9294 2.39833 22.2107C2.67963 22.492 3.06117 22.65 3.45899 22.65H20.459C20.8568 22.65 21.2383 22.492 21.5197 22.2107C21.801 21.9294 21.959 21.5478 21.959 21.15V12.134C21.9588 12.0992 21.9515 12.0648 21.9374 12.0329C21.9233 12.0011 21.9027 11.9725 21.877 11.949C21.8514 11.9256 21.8212 11.9078 21.7883 11.8967C21.7554 11.8857 21.7205 11.8817 21.686 11.885C21.584 11.894 21.482 11.9 21.379 11.9ZM14.957 15.01C14.9624 14.9092 15.0075 14.8146 15.0825 14.747C15.1575 14.6793 15.2561 14.6441 15.357 14.649H18.557C18.6578 14.6441 18.7565 14.6793 18.8315 14.747C18.9064 14.8146 18.9516 14.9092 18.957 15.01V20.149C18.957 20.2816 18.9043 20.4088 18.8105 20.5026C18.7168 20.5963 18.5896 20.649 18.457 20.649H15.457C15.3244 20.649 15.1972 20.5963 15.1034 20.5026C15.0097 20.4088 14.957 20.2816 14.957 20.149V15.01ZM5.45699 14.982C5.46266 14.8883 5.50519 14.8007 5.57527 14.7383C5.64536 14.6759 5.7373 14.6438 5.83099 14.649H11.078C11.1718 14.6438 11.2638 14.6759 11.3341 14.7383C11.4043 14.8006 11.4471 14.8882 11.453 14.982V18.316C11.4471 18.4098 11.4043 18.4974 11.3341 18.5597C11.2638 18.6221 11.1718 18.6542 11.078 18.649H5.83099C5.7373 18.6542 5.64536 18.6221 5.57527 18.5597C5.50519 18.4973 5.46266 18.4097 5.45699 18.316V14.982Z" fill="black"/>
3
+ <path d="M21.379 10.4C21.9018 10.3658 22.3999 10.1654 22.8007 9.82812C23.2016 9.49081 23.4841 9.03421 23.607 8.52499C23.7443 8.07794 23.7398 7.59935 23.594 7.15499L21.794 1.68499C21.7757 1.60101 21.7327 1.52443 21.6705 1.46509C21.6083 1.40575 21.5298 1.36637 21.445 1.35199H2.55104C2.46629 1.36637 2.38778 1.40575 2.32559 1.46509C2.2634 1.52443 2.22037 1.60101 2.20204 1.68499L0.405038 7.15299C0.260149 7.59788 0.255959 8.07663 0.393038 8.52399C0.515827 9.0334 0.798259 9.49021 1.19909 9.82772C1.59992 10.1652 2.09816 10.3657 2.62104 10.4C3.31538 10.3276 3.95359 9.98564 4.39846 9.44764C4.84333 8.90965 5.05934 8.21857 5.00004 7.52299C5.00004 7.32408 5.07906 7.13331 5.21971 6.99266C5.36036 6.85201 5.55113 6.77299 5.75004 6.77299C5.94895 6.77299 6.13972 6.85201 6.28037 6.99266C6.42102 7.13331 6.50004 7.32408 6.50004 7.52299C6.44067 8.21779 6.656 8.90818 7.09982 9.44604C7.54364 9.9839 8.1806 10.3264 8.87404 10.4C9.56784 10.3269 10.2053 9.9846 10.6495 9.44668C11.0938 8.90877 11.3094 8.2181 11.25 7.52299C11.25 7.32408 11.3291 7.13331 11.4697 6.99266C11.6104 6.85201 11.8011 6.77299 12 6.77299C12.199 6.77299 12.3897 6.85201 12.5304 6.99266C12.671 7.13331 12.75 7.32408 12.75 7.52299C12.6907 8.21826 12.9064 8.90906 13.3509 9.447C13.7953 9.98494 14.4331 10.3271 15.127 10.4C15.8204 10.3264 16.4573 9.98387 16.9009 9.44598C17.3446 8.90808 17.5597 8.21769 17.5 7.52299C17.5 7.32408 17.5791 7.13331 17.7197 6.99266C17.8604 6.85201 18.0511 6.77299 18.25 6.77299C18.449 6.77299 18.6397 6.85201 18.7804 6.99266C18.921 7.13331 19 7.32408 19 7.52299C18.941 8.21851 19.1571 8.90945 19.6019 9.44739C20.0467 9.98532 20.6848 10.3273 21.379 10.4Z" fill="black"/>
4
+ </svg>
@@ -0,0 +1,42 @@
1
+ module Spark
2
+ module ApplicationHelper
3
+
4
+ def tree_cookie
5
+ @_tree_cookie ||= begin
6
+ JSON.parse(cookies[:tree_nav]) if cookies[:tree_nav].present?
7
+ rescue
8
+ nil
9
+ end
10
+ end
11
+
12
+ def is_tree_expanded?( item )
13
+ tree_cookie.present? && !!tree_cookie( item )
14
+ end
15
+
16
+ def ng_attrs
17
+ attrs = {}
18
+
19
+ [:ng_init, :ng_controller].each do |sym|
20
+ attrs[sym] = content_for(sym) if content_for?(sym)
21
+ end
22
+
23
+ attrs
24
+
25
+ end
26
+
27
+ def yield_if(symbol, &block)
28
+ yield content_for(symbol) if content_for?(symbol)
29
+ end
30
+
31
+ def body_class(classnames=nil)
32
+ unless classnames.nil?
33
+ content_for(:body_classes) do
34
+ [classnames].flatten.join(' ') + ' '
35
+ end
36
+ end
37
+ if classes = content_for(:body_classes)
38
+ classes.strip
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,40 @@
1
+ module Spark
2
+ module IconHelper
3
+ def svg_symbols(*keys)
4
+ unless Rails.env.production?
5
+ Esvg.embed(keys)
6
+ end
7
+ end
8
+
9
+ def status_icon (status, options={})
10
+ options[:height] ||= '1em'
11
+ span_options = {}
12
+
13
+ span_options['aria-label'] = status.titlecase
14
+ span_options[:class] = 'status-icon inline-icon has-tooltip'
15
+ options[:desc] ||= status
16
+
17
+ content_tag :span, span_options do
18
+ use_svg "status-#{status}", options
19
+ end
20
+ end
21
+
22
+ def small_icon(name, options={})
23
+ use_svg(name, options.merge({width: '25px'}))
24
+ end
25
+
26
+ def inline_icon(name, options={}, &block)
27
+ options[:height] ||= '100%'
28
+ options[:width] ||= '100%'
29
+ content_tag :span, class: 'svg-wrapper inline-icon' do
30
+ use_svg name, options, &block
31
+ end
32
+ end
33
+
34
+ def svg(name, options={}, &block)
35
+ content_tag :span, class: 'svg-wrapper' do
36
+ use_svg name, options, &block
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,163 @@
1
+ module Spark
2
+ module InputHelper
3
+
4
+ def input_tag(type, name, value, options=nil, &block)
5
+ type.to_sym! if type.is_a?( String )
6
+
7
+ if value.is_a? Hash
8
+ options = value
9
+ value = nil
10
+ end
11
+
12
+ options = Spark::Helpers.set_type_defaults( type, options )
13
+ options = Spark::Helpers.set_data_keys( options, 'default' )
14
+ options = Spark::Helpers.set_aria_keys( options )
15
+
16
+ icon = Esvg.use( icon ) if icon = options.delete('icon')
17
+ icon_after = Esvg.use( icon_after ) if icon_after = options.delete('icon_after')
18
+
19
+ options['data']['unique-id'] = "input-#{SecureRandom.hex(8)}"
20
+ options['autocomplete'] ||= 'off' if type != :textarea
21
+
22
+ label_options = {
23
+ data: { 'input-type' => type },
24
+ class: [ label_class( type ), options.delete( 'class' ) ]
25
+ }
26
+
27
+ # Move modal options to label
28
+ %w(show-panel show-dialog show-menu).each do |opt|
29
+ if val = options['data'].delete(opt)
30
+ label_options[:data][opt] = val
31
+ end
32
+ end
33
+
34
+ # Add a placeholder element unless textarea
35
+ if type != :textarea && placeholder = options['placeholder']
36
+ placeholder = content_tag(:span, class: 'input-placeholder-text') { placeholder }
37
+ label_options = add_class label_options, 'placeholder-label'
38
+ end
39
+
40
+ if label_description = options.delete('description')
41
+ options['aria-describedby'] = options['data']['unique-id'] + '-description'
42
+ label_description = content_tag(:span, id: options['aria-describedby'], class: 'label-description') { label_description }
43
+ label_options = add_class label_options, 'has-description'
44
+ end
45
+
46
+ if options['label'] && label_text = options.delete('label')
47
+ options['aria-labelledby'] = options['data']['unique-id'] + '-label'
48
+
49
+ label_text = content_tag(:span, class: 'input-label-text') {
50
+ content_tag(:span, id: options['aria-labelledby']){ label_text }
51
+ }
52
+ end
53
+
54
+ # Be sure the input has a label if there is no label text
55
+ options['aria-label'] = options['placeholder'] if placeholder && !label_text
56
+
57
+ input = base_input_tag( name, value, options, type, &block )
58
+
59
+ content_tag(:label, label_options) do
60
+ concat( label_text )
61
+ concat( label_description )
62
+
63
+ concat content_tag( :span, class: 'input-wrapper' ) {
64
+ if type == :select
65
+ concat( input )
66
+ #concat placeholder
67
+ else
68
+ concat content_tag( :span, class: 'input-icon' ) { icon } if icon
69
+
70
+ concat content_tag( :span, class: 'input-container' ) {
71
+ concat( input )
72
+ #concat placeholder
73
+ }
74
+
75
+ if type == :search
76
+ concat button_tag( type: 'button', class: 'clear-search', tabindex: -1, "aria-label" => 'Clear search' ) { 'x' }
77
+ end
78
+ concat content_tag( :span, class: 'input-icon after' ) { icon_after } if icon_after
79
+
80
+ if block_given? && type != :textarea
81
+ concat content_tag( :span, class: 'input-extra', &block )
82
+ end
83
+ end
84
+ }
85
+ end
86
+
87
+ end
88
+
89
+ def base_input_tag( name, value, options, type, &block )
90
+ case type
91
+ when :range
92
+ range_input_tag( name, options )
93
+ when :select
94
+ value = value.html_safe if value
95
+ select_tag( name, value, options )
96
+ when :textarea
97
+ value ||= capture(&block).html_safe if block_given?
98
+ options[:class] = "#{options[:class]} empty".strip if value.nil?
99
+ text_area_tag( name, value, options )
100
+ else
101
+ options[:class] = "#{options[:class]} empty".strip if value.nil?
102
+ text_field_tag( name, value, options )
103
+ end
104
+
105
+ end
106
+
107
+ def range_input_tag(name, options)
108
+ options.merge!({ type: "range", })
109
+
110
+ tag :input, options
111
+ end
112
+
113
+ def label_class( type )
114
+ type = case type
115
+ when :tel, :password, :number, :url, :email, :search
116
+ "text"
117
+ when :checkbox, :radio
118
+ "tick"
119
+ else
120
+ type.to_s
121
+ end
122
+
123
+ "#{type}-input-label"
124
+ end
125
+
126
+ def switch_input_tag(name, checked = false, options = {})
127
+ type = :checkbox
128
+
129
+ if checked.is_a? Hash
130
+ options = checked
131
+ checked = false
132
+ end
133
+
134
+ options = add_class( options, [ label_class( type ), 'check-switch switch-label'] )
135
+
136
+ label_options = {
137
+ data: {
138
+ 'input-type' => type,
139
+ 'input' => 'checkbox'
140
+ },
141
+ class: options.delete('class')
142
+ }
143
+
144
+ if label_text = options.delete('label')
145
+ label_text = content_tag(:span, class: 'label-text') { label_text }
146
+ end
147
+
148
+ content_tag(:label, label_options ) do
149
+ concat tag :input, name: name, type: :hidden, value: false
150
+ concat label_text
151
+ concat check_box_tag(name, true, checked, options)
152
+
153
+ concat content_tag(:span, class: 'check-switch-panel') {
154
+ concat content_tag(:span, class: 'check-switch-tick') { '' }
155
+ }
156
+
157
+ concat content_tag(:span, class: 'check-switch-label') { 'Enable' }
158
+ end
159
+
160
+ end
161
+
162
+ end
163
+ end
@@ -0,0 +1,113 @@
1
+ module Spark
2
+ module MenuHelper
3
+ class Menu < Spark::Helper
4
+ DEFAULTS = {
5
+ tag: :div,
6
+ role: :menu,
7
+ base_class: 'menu',
8
+ header_tag: :h4,
9
+ group_tag: :ul,
10
+ item_tag: :li
11
+ }
12
+
13
+ def initialize( title = nil, options = {} )
14
+ options, title = title, nil if title.is_a? Hash
15
+
16
+ @options = add_class( options, config[:base_class] )
17
+ @options['aria-label'] = title if title
18
+ end
19
+
20
+ def display( body )
21
+ @options.merge!({ role: config[:role] })
22
+ content_tag( config[:tag], @options ) do
23
+ concat( body )
24
+ end
25
+ end
26
+
27
+ def header( text = nil, options = {}, &block )
28
+ options, text = text, nil if text.is_a?( Hash )
29
+ options = add_class( options, config[:base_class] + "-header" )
30
+
31
+ content_tag( :header, options ) {
32
+ concat( content_tag( config[:header_tag], text, class: config[:base_class] + '-title' ) ) if text
33
+ concat( capture( &block ).html_safe ) if block_given?
34
+ }
35
+ end
36
+
37
+ def link( content=nil, url=nil, options=nil, &block )
38
+ content, url, options = parse_item_args( content, url, options, &block)
39
+ content, options = set_content( content, options )
40
+ options = add_class( options, config[:base_class] + "-item" )
41
+
42
+ options['role'] ||= 'menuitem'
43
+ options['tabindex'] ||= 0
44
+
45
+ link_to( url, options, &content )
46
+ end
47
+
48
+ def group( title=nil, options={}, &block )
49
+ options = add_class( options, config[:base_class] + "-group" )
50
+ options['role'] = 'group'
51
+
52
+ concat header( title ) if title
53
+ content_tag( config[:group_tag], options, &block )
54
+ end
55
+
56
+ def item( content=nil, url=nil, options=nil, &block )
57
+ content, url, options = parse_item_args( content, url, options, &block)
58
+
59
+ if url
60
+ content_tag( config[:item_tag], role: 'none', class: config[:base_class] + "-item-wrapper" ) do
61
+ link( url, options ) { content }
62
+ end
63
+ else
64
+ content, options = set_content( content, options )
65
+ options = add_class( options, config[:base_class] + "-item" )
66
+ content_tag( config[:item_tag], options, &content )
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ # add icons, wrap content, strip bad option keys
73
+ def set_content( content, options )
74
+ icon = options.delete('icon')
75
+ after_icon = options.delete('after-icon')
76
+
77
+ icon_options = {
78
+ class: config[:base_class] + "-item-icon"
79
+ }.merge( options.delete('icon-options') || {} )
80
+
81
+ after_icon_options = {
82
+ class: config[:base_class] + "-item-after-icon"
83
+ }.merge( options.delete('after-icon-options') || {} )
84
+
85
+ inner_content = lambda {
86
+ concat use_svg( icon, icon_options ) if icon
87
+ concat content_tag( :div, class: config[:base_class] + "-item-content" ) { content }
88
+ concat use_svg( after_icon, after_icon_options ) if after_icon
89
+ }
90
+
91
+ [inner_content, options]
92
+ end
93
+
94
+ def config(options=nil)
95
+ @_config = DEFAULTS.merge(options) if options
96
+ @_config ||= DEFAULTS
97
+ end
98
+
99
+ # Simplify setting up options and content
100
+ def parse_item_args( content=nil, url=nil, options=nil, &block )
101
+ # If block passed, shift args so content = block
102
+ options, url, content = url, content, capture( &block ) if block_given?
103
+ # If url is a hash, url wasn't passed, set to nil, an shift args
104
+ options, url = url, nil if url.is_a?(Hash)
105
+ options ||= {}
106
+
107
+ options = Spark::Helpers.set_data_keys( options )
108
+
109
+ [content, url, options]
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,52 @@
1
+ module Spark
2
+ module ModalHelper
3
+ class ModalPanel < Spark::Helper
4
+
5
+ def initialize( options = {} )
6
+ @options = add_class( options, 'modal-panel' )
7
+ @options = Spark::Helpers.set_aria_keys( @options )
8
+ puts @options
9
+ @options = ({ 'aria-modal'=> true, 'aria-hidden'=> true }).merge(@options)
10
+ end
11
+
12
+ def display( body )
13
+ if first_header = body.scan(/\A<header.+?\/header>/m).first
14
+ body = body.sub( first_header, '' ).html_safe
15
+ first_header = first_header.html_safe
16
+ end
17
+
18
+ if last_footer = body.scan(/<footer.+?\/footer>\z/m).first
19
+ body = body.sub(last_footer, '').html_safe
20
+ last_footer = last_footer.html_safe
21
+ end
22
+
23
+ content_tag( :section, @options ) do
24
+ concat first_header
25
+ concat content_tag( :div, class: 'modal-panel-content' ) {
26
+ concat body
27
+ }
28
+ concat last_footer
29
+ end
30
+ end
31
+
32
+ def header( text = nil, options = {}, &block )
33
+ options, text = text, nil if text.is_a? Hash
34
+
35
+ options = add_class( options, "modal-panel-header" )
36
+
37
+ content_tag( :header, options ) {
38
+ concat content_tag( :h4, text, class: 'modal-panel-title' ) if text
39
+ concat capture( &block ).html_safe if block_given?
40
+ }
41
+ end
42
+
43
+ def footer( options = {}, &block )
44
+ options = add_class options, "modal-panel-footer"
45
+
46
+ content_tag( :footer, options ) {
47
+ concat capture( &block ).html_safe if block_given?
48
+ }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,167 @@
1
+ module Spark
2
+ module NavMenuHelper
3
+ def parse_cookie( key )
4
+ JSON.parse( cookies[ key ] ) if cookies[ key ].present?
5
+ end
6
+
7
+ class NavMenu < Spark::MenuHelper::Menu
8
+
9
+ def initialize( title = nil, options = {} )
10
+ config({
11
+ tag: :nav,
12
+ base_class: 'nav-menu'
13
+ })
14
+ super( title, options )
15
+ end
16
+
17
+ def more( content=nil, url=nil, options=nil, &block )
18
+ content, url, options = parse_item_args( content, url, options, &block)
19
+ options['aria-haspopup'] = 'true'
20
+ options = add_class( options, config[:base_class] + "-more" )
21
+ url ||= '#'
22
+
23
+ item( content, url, options )
24
+ end
25
+ end
26
+
27
+ class TreeNav < Spark::MenuHelper::Menu
28
+
29
+ def initialize( title = nil, options = {} )
30
+ config({
31
+ tag: :ul,
32
+ base_class: 'nav-tree',
33
+ role: 'tree'
34
+ })
35
+ super( title, options )
36
+ end
37
+
38
+ def item(content, url, options={}, &block)
39
+ options['role'] = 'treeitem'
40
+
41
+ super( content, url, options, &block )
42
+ end
43
+
44
+ def item_tree( name, options={}, &block )
45
+ content, url, options = parse_item_args( "#", options, &block)
46
+
47
+ node = Spark::Helpers.dasherize( name.strip.downcase ).gsub('-','_')
48
+ active = !!(options.delete( 'active' ) || content.match(/nav-item-active/))
49
+
50
+ options.merge!({
51
+ 'role' => 'treeitem',
52
+ 'aria-expanded' => active || is_expanded?(node),
53
+ 'data-node' => node
54
+ })
55
+
56
+ name, options = set_content( name, options )
57
+ options = add_class( options, config[:base_class] + "-item-wrapper" )
58
+
59
+ content_tag( config[:item_tag], options ) do
60
+ concat link_to( "#", class: config[:base_class] + '-item' ){
61
+ concat name.call
62
+ concat use_svg( 'chevron-down', class: 'expand-icon' )
63
+ }
64
+ concat content_tag( :ul, role: 'group', class: config[:base_class] + '-group' ) { content }
65
+ end
66
+ end
67
+
68
+ #def group( name, options={}, &block )
69
+ #options = options.deep_stringify_keys
70
+ #content = capture( &block )
71
+ #active = !!(options.delete( 'active' ) || content.match(/nav-item-active/))
72
+ #new = is_new?( options.delete( 'new' ) ) || content.match(/nav-item-new/)
73
+
74
+ #icon = options.delete('icon')
75
+ #node = Spark::Helpers.dasherize( name.strip.downcase ).gsub('-','_')
76
+
77
+ #item_options = {
78
+ #role: 'treeitem',
79
+ #'aria-expanded': active || is_expanded?(node),
80
+ #'data-node': node,
81
+ #active: active,
82
+ #new: new,
83
+ #icon: icon,
84
+ #icon_options: { preset: 'icon_l' }
85
+ #}
86
+
87
+ #item('#', item_options ) {
88
+ #concat use_svg( icon, preset: 'icon_l' ) if icon
89
+ #concat name
90
+ #if new
91
+ #concat " "
92
+ #concat content_tag( :span, class: 'nav-item-new' ) { "New" }
93
+ #end
94
+ #concat use_svg( 'chevron-down', height: 9, class: 'expand-tree-icon' )
95
+
96
+ #concat content_tag( :ul, role: 'group', class: 'nav-tree-group', &block )
97
+ #}
98
+
99
+ #end
100
+
101
+ private
102
+
103
+ def _cookie
104
+ @_cookie ||= begin
105
+ parse_cookie( @tree )
106
+ rescue
107
+ nil
108
+ end
109
+ end
110
+
111
+ def is_expanded?( item )
112
+ !@tree.nil? && _cookie.present? && !!_cookie[ item ]
113
+ end
114
+ end
115
+
116
+ class SidebarNav < TreeNav
117
+ def initialize( title, options = {} )
118
+ @tree = 'sidebar_nav'
119
+ options['data-tree'] = @tree
120
+ super( title, options )
121
+ end
122
+
123
+ def item( content, url, options={}, &block )
124
+ options = options.stringify_keys
125
+ new = is_new?( options.delete( 'new' ) )
126
+ active = is_active?( options.delete( 'active' ) )
127
+
128
+ classes = []
129
+ classes.push( 'new' ) if new
130
+ classes.push( 'active' ) if active
131
+ options = add_class( options, classes )
132
+
133
+
134
+ super( content, url, options, &block)
135
+ end
136
+
137
+
138
+ def item_tree( name, options={}, &block )
139
+ options = options.stringify_keys
140
+ content = capture( &block )
141
+
142
+ classes = []
143
+ classes.push( 'new' ) if is_new?( options.delete( 'new' ) ) || content.match(/nav-item-new/)
144
+ classes.push( 'active' ) if !!( options.delete( 'active' ) || content.match(/nav-item-active/))
145
+
146
+ options = add_class( options, classes )
147
+
148
+ super( name, options, &block )
149
+ end
150
+
151
+ private
152
+
153
+ def is_new?( new )
154
+ if new.is_a?(String)
155
+ 30.days.ago <= Time.zone.parse( new )
156
+ else
157
+ new
158
+ end
159
+ end
160
+
161
+ def is_active?( active )
162
+ active
163
+ end
164
+
165
+ end
166
+ end
167
+ end