pulse_view_components 0.3.0

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 (221) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +88 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +78 -0
  5. data/app/assets/builds/js/pulse_view_components.js +9543 -0
  6. data/app/assets/builds/js/pulse_view_components.js.map +7 -0
  7. data/app/assets/builds/pulse_view_components.css +1 -0
  8. data/app/assets/config/manifest.js +2 -0
  9. data/app/assets/images/pulse_view_components/icons/alert.svg +3 -0
  10. data/app/assets/images/pulse_view_components/icons/archive.svg +1 -0
  11. data/app/assets/images/pulse_view_components/icons/arrow-both.svg +1 -0
  12. data/app/assets/images/pulse_view_components/icons/arrow-down.svg +1 -0
  13. data/app/assets/images/pulse_view_components/icons/arrow-left.svg +1 -0
  14. data/app/assets/images/pulse_view_components/icons/arrow-right.svg +1 -0
  15. data/app/assets/images/pulse_view_components/icons/arrow-switch.svg +1 -0
  16. data/app/assets/images/pulse_view_components/icons/arrow-up.svg +1 -0
  17. data/app/assets/images/pulse_view_components/icons/beaker.svg +1 -0
  18. data/app/assets/images/pulse_view_components/icons/bell-slash.svg +1 -0
  19. data/app/assets/images/pulse_view_components/icons/bell.svg +1 -0
  20. data/app/assets/images/pulse_view_components/icons/bookmark-slash.svg +1 -0
  21. data/app/assets/images/pulse_view_components/icons/bookmark.svg +1 -0
  22. data/app/assets/images/pulse_view_components/icons/calendar.svg +1 -0
  23. data/app/assets/images/pulse_view_components/icons/check-circle.svg +1 -0
  24. data/app/assets/images/pulse_view_components/icons/check.svg +1 -0
  25. data/app/assets/images/pulse_view_components/icons/chevron-down.svg +1 -0
  26. data/app/assets/images/pulse_view_components/icons/circle.svg +1 -0
  27. data/app/assets/images/pulse_view_components/icons/clock.svg +1 -0
  28. data/app/assets/images/pulse_view_components/icons/close.svg +9 -0
  29. data/app/assets/images/pulse_view_components/icons/cloud.svg +1 -0
  30. data/app/assets/images/pulse_view_components/icons/comment-discussion.svg +1 -0
  31. data/app/assets/images/pulse_view_components/icons/comment.svg +1 -0
  32. data/app/assets/images/pulse_view_components/icons/copy.svg +1 -0
  33. data/app/assets/images/pulse_view_components/icons/database.svg +1 -0
  34. data/app/assets/images/pulse_view_components/icons/dot.svg +1 -0
  35. data/app/assets/images/pulse_view_components/icons/dots-outline.svg +1 -0
  36. data/app/assets/images/pulse_view_components/icons/download.svg +1 -0
  37. data/app/assets/images/pulse_view_components/icons/duplicate.svg +1 -0
  38. data/app/assets/images/pulse_view_components/icons/eye.svg +1 -0
  39. data/app/assets/images/pulse_view_components/icons/file-added.svg +1 -0
  40. data/app/assets/images/pulse_view_components/icons/file-directory.svg +1 -0
  41. data/app/assets/images/pulse_view_components/icons/file-media.svg +1 -0
  42. data/app/assets/images/pulse_view_components/icons/file.svg +1 -0
  43. data/app/assets/images/pulse_view_components/icons/filter.svg +1 -0
  44. data/app/assets/images/pulse_view_components/icons/flame.svg +1 -0
  45. data/app/assets/images/pulse_view_components/icons/gear.svg +1 -0
  46. data/app/assets/images/pulse_view_components/icons/gift.svg +1 -0
  47. data/app/assets/images/pulse_view_components/icons/globe.svg +1 -0
  48. data/app/assets/images/pulse_view_components/icons/goal.svg +1 -0
  49. data/app/assets/images/pulse_view_components/icons/graph.svg +1 -0
  50. data/app/assets/images/pulse_view_components/icons/heart-fill.svg +1 -0
  51. data/app/assets/images/pulse_view_components/icons/heart.svg +1 -0
  52. data/app/assets/images/pulse_view_components/icons/history.svg +1 -0
  53. data/app/assets/images/pulse_view_components/icons/home.svg +1 -0
  54. data/app/assets/images/pulse_view_components/icons/hourglass.svg +1 -0
  55. data/app/assets/images/pulse_view_components/icons/image.svg +1 -0
  56. data/app/assets/images/pulse_view_components/icons/inbox.svg +1 -0
  57. data/app/assets/images/pulse_view_components/icons/info.svg +1 -0
  58. data/app/assets/images/pulse_view_components/icons/issue.svg +3 -0
  59. data/app/assets/images/pulse_view_components/icons/key.svg +1 -0
  60. data/app/assets/images/pulse_view_components/icons/law.svg +1 -0
  61. data/app/assets/images/pulse_view_components/icons/link-external.svg +1 -0
  62. data/app/assets/images/pulse_view_components/icons/link.svg +1 -0
  63. data/app/assets/images/pulse_view_components/icons/location.svg +1 -0
  64. data/app/assets/images/pulse_view_components/icons/log.svg +1 -0
  65. data/app/assets/images/pulse_view_components/icons/mail.svg +1 -0
  66. data/app/assets/images/pulse_view_components/icons/mark-github.svg +1 -0
  67. data/app/assets/images/pulse_view_components/icons/mark-jira.svg +3 -0
  68. data/app/assets/images/pulse_view_components/icons/megaphone.svg +1 -0
  69. data/app/assets/images/pulse_view_components/icons/no-entry.svg +1 -0
  70. data/app/assets/images/pulse_view_components/icons/note.svg +1 -0
  71. data/app/assets/images/pulse_view_components/icons/organization.svg +1 -0
  72. data/app/assets/images/pulse_view_components/icons/package.svg +1 -0
  73. data/app/assets/images/pulse_view_components/icons/paintbrush.svg +1 -0
  74. data/app/assets/images/pulse_view_components/icons/paperclip.svg +1 -0
  75. data/app/assets/images/pulse_view_components/icons/paste.svg +1 -0
  76. data/app/assets/images/pulse_view_components/icons/pencil.svg +1 -0
  77. data/app/assets/images/pulse_view_components/icons/people.svg +1 -0
  78. data/app/assets/images/pulse_view_components/icons/person-add.svg +1 -0
  79. data/app/assets/images/pulse_view_components/icons/person.svg +1 -0
  80. data/app/assets/images/pulse_view_components/icons/pin-slash.svg +1 -0
  81. data/app/assets/images/pulse_view_components/icons/pin.svg +1 -0
  82. data/app/assets/images/pulse_view_components/icons/play.svg +1 -0
  83. data/app/assets/images/pulse_view_components/icons/plus-circle.svg +1 -0
  84. data/app/assets/images/pulse_view_components/icons/plus.svg +1 -0
  85. data/app/assets/images/pulse_view_components/icons/project.svg +1 -0
  86. data/app/assets/images/pulse_view_components/icons/pulse.svg +1 -0
  87. data/app/assets/images/pulse_view_components/icons/question.svg +1 -0
  88. data/app/assets/images/pulse_view_components/icons/redo.svg +1 -0
  89. data/app/assets/images/pulse_view_components/icons/reply.svg +1 -0
  90. data/app/assets/images/pulse_view_components/icons/report.svg +1 -0
  91. data/app/assets/images/pulse_view_components/icons/rss.svg +1 -0
  92. data/app/assets/images/pulse_view_components/icons/ruby.svg +1 -0
  93. data/app/assets/images/pulse_view_components/icons/search.svg +1 -0
  94. data/app/assets/images/pulse_view_components/icons/share.svg +1 -0
  95. data/app/assets/images/pulse_view_components/icons/shield.svg +1 -0
  96. data/app/assets/images/pulse_view_components/icons/sliders.svg +1 -0
  97. data/app/assets/images/pulse_view_components/icons/smiley.svg +1 -0
  98. data/app/assets/images/pulse_view_components/icons/sort.svg +1 -0
  99. data/app/assets/images/pulse_view_components/icons/sort_asc.svg +1 -0
  100. data/app/assets/images/pulse_view_components/icons/sort_desc.svg +1 -0
  101. data/app/assets/images/pulse_view_components/icons/stack.svg +1 -0
  102. data/app/assets/images/pulse_view_components/icons/star-fill.svg +1 -0
  103. data/app/assets/images/pulse_view_components/icons/star.svg +1 -0
  104. data/app/assets/images/pulse_view_components/icons/stopwatch.svg +1 -0
  105. data/app/assets/images/pulse_view_components/icons/sun.svg +1 -0
  106. data/app/assets/images/pulse_view_components/icons/sync.svg +1 -0
  107. data/app/assets/images/pulse_view_components/icons/table.svg +1 -0
  108. data/app/assets/images/pulse_view_components/icons/tag.svg +1 -0
  109. data/app/assets/images/pulse_view_components/icons/tasklist.svg +1 -0
  110. data/app/assets/images/pulse_view_components/icons/telescope.svg +1 -0
  111. data/app/assets/images/pulse_view_components/icons/three-bars.svg +1 -0
  112. data/app/assets/images/pulse_view_components/icons/thumbsdown.svg +1 -0
  113. data/app/assets/images/pulse_view_components/icons/thumbsup.svg +1 -0
  114. data/app/assets/images/pulse_view_components/icons/tools.svg +1 -0
  115. data/app/assets/images/pulse_view_components/icons/trash.svg +1 -0
  116. data/app/assets/images/pulse_view_components/icons/trophy.svg +1 -0
  117. data/app/assets/images/pulse_view_components/icons/undo.svg +1 -0
  118. data/app/assets/images/pulse_view_components/icons/unlink.svg +1 -0
  119. data/app/assets/images/pulse_view_components/icons/upload.svg +1 -0
  120. data/app/assets/images/pulse_view_components/icons/x-circle.svg +1 -0
  121. data/app/assets/images/pulse_view_components/icons/x.svg +1 -0
  122. data/app/assets/images/pulse_view_components/icons/zap.svg +1 -0
  123. data/app/assets/javascripts/pulse_view_components.js +0 -0
  124. data/app/assets/stylesheets/pulse_view_components/application.tailwind.css +10 -0
  125. data/app/components/pulse/action_list/divider.rb +35 -0
  126. data/app/components/pulse/action_list/form_wrapper.html.slim +9 -0
  127. data/app/components/pulse/action_list/form_wrapper.rb +63 -0
  128. data/app/components/pulse/action_list/heading.rb +52 -0
  129. data/app/components/pulse/action_list/item.html.slim +43 -0
  130. data/app/components/pulse/action_list/item.rb +319 -0
  131. data/app/components/pulse/action_list.css +568 -0
  132. data/app/components/pulse/action_list.rb +261 -0
  133. data/app/components/pulse/badge.rb +59 -0
  134. data/app/components/pulse/base_component.rb +36 -0
  135. data/app/components/pulse/blank_slate.html.slim +10 -0
  136. data/app/components/pulse/blank_slate.rb +19 -0
  137. data/app/components/pulse/blank_slate.yml +2 -0
  138. data/app/components/pulse/border_box/header.html.slim +4 -0
  139. data/app/components/pulse/border_box/header.rb +48 -0
  140. data/app/components/pulse/border_box.html.slim +10 -0
  141. data/app/components/pulse/border_box.rb +124 -0
  142. data/app/components/pulse/box.rb +17 -0
  143. data/app/components/pulse/breadcrumb_item.rb +40 -0
  144. data/app/components/pulse/breadcrumbs.html.slim +9 -0
  145. data/app/components/pulse/breadcrumbs.rb +17 -0
  146. data/app/components/pulse/button.rb +148 -0
  147. data/app/components/pulse/component.rb +99 -0
  148. data/app/components/pulse/conditional_wrapper.rb +21 -0
  149. data/app/components/pulse/content.rb +11 -0
  150. data/app/components/pulse/counter.css +10 -0
  151. data/app/components/pulse/counter.rb +107 -0
  152. data/app/components/pulse/flash.html.slim +9 -0
  153. data/app/components/pulse/flash.rb +52 -0
  154. data/app/components/pulse/forms/error_explanation.html.slim +8 -0
  155. data/app/components/pulse/forms/error_explanation.rb +36 -0
  156. data/app/components/pulse/icon.rb +30 -0
  157. data/app/components/pulse/label.html.slim +5 -0
  158. data/app/components/pulse/label.rb +42 -0
  159. data/app/components/pulse/layout.css +239 -0
  160. data/app/components/pulse/layout.html.slim +7 -0
  161. data/app/components/pulse/layout.rb +141 -0
  162. data/app/components/pulse/link.html.slim +7 -0
  163. data/app/components/pulse/link.rb +52 -0
  164. data/app/components/pulse/modal.html.slim +51 -0
  165. data/app/components/pulse/modal.rb +64 -0
  166. data/app/components/pulse/modal_controller.js +77 -0
  167. data/app/components/pulse/nav_link.html.slim +16 -0
  168. data/app/components/pulse/nav_link.rb +25 -0
  169. data/app/components/pulse/nav_list/divider.rb +13 -0
  170. data/app/components/pulse/nav_list/group.html.slim +6 -0
  171. data/app/components/pulse/nav_list/group.rb +110 -0
  172. data/app/components/pulse/nav_list/heading.rb +36 -0
  173. data/app/components/pulse/nav_list/item.rb +171 -0
  174. data/app/components/pulse/nav_list.html.slim +11 -0
  175. data/app/components/pulse/nav_list.rb +225 -0
  176. data/app/components/pulse/popover.html.slim +5 -0
  177. data/app/components/pulse/popover.rb +88 -0
  178. data/app/components/pulse/progress_bar.html.slim +5 -0
  179. data/app/components/pulse/progress_bar.rb +23 -0
  180. data/app/components/pulse/progress_bar.yml +2 -0
  181. data/app/components/pulse/table/cell.html.slim +10 -0
  182. data/app/components/pulse/table/cell.rb +90 -0
  183. data/app/components/pulse/table/cell.yml +5 -0
  184. data/app/components/pulse/table/column.rb +22 -0
  185. data/app/components/pulse/table.html.slim +50 -0
  186. data/app/components/pulse/table.rb +111 -0
  187. data/app/components/pulse/table.yml +2 -0
  188. data/app/components/pulse/text.rb +72 -0
  189. data/app/components/pulse/toast.html.slim +14 -0
  190. data/app/components/pulse/toast.rb +85 -0
  191. data/app/components/pulse/toast_controller.js +32 -0
  192. data/app/javascript/pulse_view_components/application.js +24 -0
  193. data/app/javascript/pulse_view_components.js +4 -0
  194. data/app/lib/pulse/attributes_helper.rb +107 -0
  195. data/app/lib/pulse/fetch_or_fallback_helper.rb +53 -0
  196. data/app/lib/pulse/svg_helper.rb +28 -0
  197. data/lib/pulse/view_components/engine.rb +74 -0
  198. data/lib/pulse/view_components/version.rb +17 -0
  199. data/lib/pulse/view_components.rb +14 -0
  200. data/lib/pulse_view_components.rb +3 -0
  201. data/lib/tasks/pulse_view_components_tasks.rake +8 -0
  202. data/previews/pulse/badge_preview.rb +51 -0
  203. data/previews/pulse/blank_slate_preview.rb +14 -0
  204. data/previews/pulse/border_box_preview.rb +48 -0
  205. data/previews/pulse/breadcrumbs_preview.rb +13 -0
  206. data/previews/pulse/button_preview.rb +137 -0
  207. data/previews/pulse/counter_preview.rb +14 -0
  208. data/previews/pulse/flash_preview.rb +85 -0
  209. data/previews/pulse/icon_preview.rb +12 -0
  210. data/previews/pulse/label_preview.rb +10 -0
  211. data/previews/pulse/layout_preview.rb +34 -0
  212. data/previews/pulse/link_preview.rb +55 -0
  213. data/previews/pulse/modal_preview.rb +48 -0
  214. data/previews/pulse/nav_link_preview.rb +48 -0
  215. data/previews/pulse/nav_list_preview.rb +138 -0
  216. data/previews/pulse/popover_preview.rb +77 -0
  217. data/previews/pulse/progress_bar_preview.rb +23 -0
  218. data/previews/pulse/table_preview.rb +168 -0
  219. data/previews/pulse/text_preview.rb +102 -0
  220. data/previews/pulse/toast_preview.rb +67 -0
  221. metadata +344 -0
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M2 2h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1Zm4.655 8.595a.75.75 0 0 1 0 1.06L4.03 14.28a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.095-2.095a.75.75 0 0 1 1.06 0ZM9.75 2.5h5.5a.75.75 0 0 1 0 1.5h-5.5a.75.75 0 0 1 0-1.5Zm0 5h5.5a.75.75 0 0 1 0 1.5h-5.5a.75.75 0 0 1 0-1.5Zm0 5h5.5a.75.75 0 0 1 0 1.5h-5.5a.75.75 0 0 1 0-1.5Zm-7.25-9v3h3v-3Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M14.184 1.143v-.001l1.422 2.464a1.75 1.75 0 0 1-.757 2.451L3.104 11.713a1.75 1.75 0 0 1-2.275-.702l-.447-.775a1.75 1.75 0 0 1 .53-2.32L11.682.573a1.748 1.748 0 0 1 2.502.57Zm-4.709 9.32h-.001l2.644 3.863a.75.75 0 1 1-1.238.848l-1.881-2.75v2.826a.75.75 0 0 1-1.5 0v-2.826l-1.881 2.75a.75.75 0 1 1-1.238-.848l2.049-2.992a.746.746 0 0 1 .293-.253l1.809-.87a.749.749 0 0 1 .944.252ZM9.436 3.92h-.001l-4.97 3.39.942 1.63 5.42-2.61Zm3.091-2.108h.001l-1.85 1.26 1.505 2.605 2.016-.97a.247.247 0 0 0 .13-.151.247.247 0 0 0-.022-.199l-1.422-2.464a.253.253 0 0 0-.161-.119.254.254 0 0 0-.197.038ZM1.756 9.157a.25.25 0 0 0-.075.33l.447.775a.25.25 0 0 0 .325.1l1.598-.769-.83-1.436-1.465 1Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M1 2.75A.75.75 0 0 1 1.75 2h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 2.75Zm0 5A.75.75 0 0 1 1.75 7h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 7.75ZM1.75 12h12.5a.75.75 0 0 1 0 1.5H1.75a.75.75 0 0 1 0-1.5Z"></path></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M7.653 15.369a.75.75 0 0 1-.776.371l-.238-.04a3.25 3.25 0 0 1-2.591-4.099L4.506 10h-.665A3.25 3.25 0 0 1 .723 5.833l1.135-3.859A2.75 2.75 0 0 1 4.482 0H9.43c.78.003 1.538.25 2.168.702A1.752 1.752 0 0 1 12.989 0h1.272A1.75 1.75 0 0 1 16 1.75v6.5A1.75 1.75 0 0 1 14.25 10h-3.417a.25.25 0 0 0-.217.127ZM11.25 2.351l-.396-.33a2.248 2.248 0 0 0-1.44-.521H4.496a1.25 1.25 0 0 0-1.199.897L2.162 6.256A1.75 1.75 0 0 0 3.841 8.5H5.5a.75.75 0 0 1 .721.956l-.731 2.558a1.75 1.75 0 0 0 1.127 2.14L9.31 9.389a1.75 1.75 0 0 1 1.523-.889h.417Zm1.5 6.149h1.5a.25.25 0 0 0 .25-.25v-6.5a.25.25 0 0 0-.25-.25H13a.25.25 0 0 0-.25.25Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M8.347.631A.75.75 0 0 1 9.123.26l.238.04a3.25 3.25 0 0 1 2.591 4.098L11.494 6h.665a3.25 3.25 0 0 1 3.118 4.167l-1.135 3.859A2.751 2.751 0 0 1 11.503 16H6.586a3.75 3.75 0 0 1-2.184-.702A1.75 1.75 0 0 1 3 16H1.75A1.75 1.75 0 0 1 0 14.25v-6.5C0 6.784.784 6 1.75 6h3.417a.25.25 0 0 0 .217-.127ZM4.75 13.649l.396.33c.404.337.914.521 1.44.521h4.917a1.25 1.25 0 0 0 1.2-.897l1.135-3.859A1.75 1.75 0 0 0 12.159 7.5H10.5a.75.75 0 0 1-.721-.956l.731-2.558a1.75 1.75 0 0 0-1.127-2.14L6.69 6.611a1.75 1.75 0 0 1-1.523.889H4.75ZM3.25 7.5h-1.5a.25.25 0 0 0-.25.25v6.5c0 .138.112.25.25.25H3a.25.25 0 0 0 .25-.25Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M5.433 2.304A4.492 4.492 0 0 0 3.5 6c0 1.598.832 3.002 2.09 3.802.518.328.929.923.902 1.64v.008l-.164 3.337a.75.75 0 1 1-1.498-.073l.163-3.33c.002-.085-.05-.216-.207-.316A5.996 5.996 0 0 1 2 6a5.993 5.993 0 0 1 2.567-4.92 1.482 1.482 0 0 1 1.673-.04c.462.296.76.827.76 1.423v2.82c0 .082.041.16.11.206l.75.51a.25.25 0 0 0 .28 0l.75-.51A.249.249 0 0 0 9 5.282V2.463c0-.596.298-1.127.76-1.423a1.482 1.482 0 0 1 1.673.04A5.993 5.993 0 0 1 14 6a5.996 5.996 0 0 1-2.786 5.068c-.157.1-.209.23-.207.315l.163 3.33a.752.752 0 0 1-1.094.714.75.75 0 0 1-.404-.64l-.164-3.345c-.027-.717.384-1.312.902-1.64A4.495 4.495 0 0 0 12.5 6a4.492 4.492 0 0 0-1.933-3.696c-.024.017-.067.067-.067.16v2.818a1.75 1.75 0 0 1-.767 1.448l-.75.51a1.75 1.75 0 0 1-1.966 0l-.75-.51A1.75 1.75 0 0 1 5.5 5.282V2.463c0-.092-.043-.142-.067-.159Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"></path></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M3.217 6.962A3.75 3.75 0 0 1 0 3.25v-.5C0 1.784.784 1 1.75 1h1.356c.228-.585.796-1 1.462-1h6.864c.647 0 1.227.397 1.462 1h1.356c.966 0 1.75.784 1.75 1.75v.5a3.75 3.75 0 0 1-3.217 3.712 5.014 5.014 0 0 1-2.771 3.117l.144 1.446c.005.05.03.12.114.204.086.087.217.17.373.227.283.103.618.274.89.568.285.31.467.723.467 1.226v.75h1.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H4v-.75c0-.503.182-.916.468-1.226.27-.294.606-.465.889-.568.139-.048.266-.126.373-.227.084-.085.109-.153.114-.204l.144-1.446a5.015 5.015 0 0 1-2.77-3.117ZM4.5 1.568V5.5a3.5 3.5 0 1 0 7 0V1.568a.068.068 0 0 0-.068-.068H4.568a.068.068 0 0 0-.068.068Zm2.957 8.902-.12 1.204c-.093.925-.858 1.47-1.467 1.691a.766.766 0 0 0-.3.176c-.037.04-.07.093-.07.21v.75h5v-.75c0-.117-.033-.17-.07-.21a.766.766 0 0 0-.3-.176c-.609-.221-1.374-.766-1.466-1.69l-.12-1.204a5.064 5.064 0 0 1-1.087 0ZM13 2.5v2.872a2.25 2.25 0 0 0 1.5-2.122v-.5a.25.25 0 0 0-.25-.25H13Zm-10 0H1.75a.25.25 0 0 0-.25.25v.5c0 .98.626 1.813 1.5 2.122Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M1.22 6.28a.749.749 0 0 1 0-1.06l3.5-3.5a.749.749 0 1 1 1.06 1.06L3.561 5h7.188l.001.007L10.749 5c.058 0 .116.007.171.019A4.501 4.501 0 0 1 10.5 14H8.796a.75.75 0 0 1 0-1.5H10.5a3 3 0 1 0 0-6H3.561L5.78 8.72a.749.749 0 1 1-1.06 1.06l-3.5-3.5Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M12.914 5.914a2 2 0 0 0-2.828-2.828l-.837.837a.75.75 0 1 1-1.06-1.061l.836-.837a3.5 3.5 0 1 1 4.95 4.95l-.195.194a.75.75 0 0 1-1.06-1.06l.194-.195Zm-1.87 3.482a.759.759 0 0 1-.07.079c-.63.63-1.468 1.108-2.343 1.263-.89.159-1.86-.017-2.606-.763a.75.75 0 1 1 1.06-1.06c.329.327.767.438 1.284.347.493-.088 1.018-.36 1.445-.752l-1.247-.897a.709.709 0 0 1-.01-.008l-.295-.212c-.94-.597-1.984-.499-2.676.193l-2.5 2.5a2 2 0 1 0 2.828 2.828l.837-.836a.75.75 0 0 1 1.06 1.06l-.836.837a3.5 3.5 0 0 1-4.95-4.95l2.5-2.5a3.472 3.472 0 0 1 1.354-.848L2.312 3.109a.75.75 0 0 1 .876-1.218l5.93 4.27c.115.074.226.155.335.24l6.235 4.49a.75.75 0 0 1-.876 1.218l-3.768-2.713Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"/><path d="M11.78 4.72a.749.749 0 1 1-1.06 1.06L8.75 3.811V9.5a.75.75 0 0 1-1.5 0V3.811L5.28 5.78a.749.749 0 1 1-1.06-1.06l3.25-3.25a.749.749 0 0 1 1.06 0l3.25 3.25Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M2.344 2.343h-.001a8 8 0 0 1 11.314 11.314A8.002 8.002 0 0 1 .234 10.089a8 8 0 0 1 2.11-7.746Zm1.06 10.253a6.5 6.5 0 1 0 9.108-9.275 6.5 6.5 0 0 0-9.108 9.275ZM6.03 4.97 8 6.94l1.97-1.97a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l1.97 1.97a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-1.97 1.97a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L6.94 8 4.97 6.03a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M9.504.43a1.516 1.516 0 0 1 2.437 1.713L10.415 5.5h2.123c1.57 0 2.346 1.909 1.22 3.004l-7.34 7.142a1.249 1.249 0 0 1-.871.354h-.302a1.25 1.25 0 0 1-1.157-1.723L5.633 10.5H3.462c-1.57 0-2.346-1.909-1.22-3.004L9.503.429Zm1.047 1.074L3.286 8.571A.25.25 0 0 0 3.462 9H6.75a.75.75 0 0 1 .694 1.034l-1.713 4.188 6.982-6.793A.25.25 0 0 0 12.538 7H9.25a.75.75 0 0 1-.683-1.06l2.008-4.418.003-.006a.036.036 0 0 0-.004-.009l-.006-.006-.008-.001c-.003 0-.006.002-.009.004Z"/></svg>
File without changes
@@ -0,0 +1,10 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ --pulse-fgColor-onEmphasis: #ffffff;
7
+ --pulse-focus-outlineColor: theme("colors.blue.700");
8
+ --pulse-layout-sidebar-width: 220px;
9
+ --pulse-layout-gutter: 16px;
10
+ }
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pulse
4
+ class ActionList
5
+ # Separator with optional text rendered above groups or between individual items.
6
+ class Divider < Pulse::Component
7
+ DEFAULT_SCHEME = :subtle
8
+ SCHEME_MAPPINGS = {
9
+ DEFAULT_SCHEME => nil,
10
+ :filled => 'pulse-border-t-color-gray pulse-border-b-color-gray ' \
11
+ 'pulse-border-y-solid empty:pulse-h-2 empty:pulse-box-border'
12
+ }.freeze
13
+ SCHEME_OPTIONS = SCHEME_MAPPINGS.keys.freeze
14
+
15
+ # @param scheme [Symbol] Display a background color if scheme is `filled`.
16
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
17
+ def initialize(scheme: DEFAULT_SCHEME, **system_arguments)
18
+ @system_arguments = system_arguments
19
+ @system_arguments[:tag] = :li
20
+ @system_arguments[:role] = :presentation
21
+ @system_arguments[:'aria-hidden'] = true
22
+ @scheme = fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)
23
+ @system_arguments[:classes] = merge_classes(
24
+ 'pulse-block pulse-h-[1px] pulse-p-0 pulse-border-0 pulse-ms-2 ',
25
+ 'pulse-me-2 pulse-bg-gray-100',
26
+ SCHEME_MAPPINGS[@scheme]
27
+ )
28
+ end
29
+
30
+ def call
31
+ render(Pulse::BaseComponent.new(**@system_arguments)) { content }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ - if form_required?
2
+ = form_with(url: @action, method: @http_method, **@form_arguments) do
3
+ - if render_input?
4
+ = render Pulse::BaseComponent.new(tag: :input, **@input_arguments)
5
+
6
+ = content
7
+
8
+ - else
9
+ = content
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pulse
4
+ class ActionList
5
+ # Utility component for wrapping ActionLists or individual `ActionList::Item`s in forms.
6
+ class FormWrapper < Pulse::Component
7
+ DEFAULT_HTTP_METHOD = :get
8
+ HTTP_METHOD_OPTIONS = [
9
+ DEFAULT_HTTP_METHOD,
10
+ :post,
11
+ :patch,
12
+ :put,
13
+ :delete,
14
+ :head
15
+ ].freeze
16
+
17
+ def initialize(list:, action: nil, **form_arguments)
18
+ @list = list
19
+ @form_arguments = form_arguments
20
+
21
+ @action = action
22
+ @http_method = extract_http_method(@form_arguments)
23
+
24
+ name = @form_arguments.delete(:name)
25
+ value = @form_arguments.delete(:value) || name
26
+
27
+ @input_arguments = {
28
+ type: :hidden,
29
+ name:,
30
+ value:,
31
+ data: { list_item_input: true },
32
+ **(@form_arguments.delete(:input_arguments) || {})
33
+ }
34
+ end
35
+
36
+ def get?
37
+ @http_method == :get
38
+ end
39
+
40
+ def form_required?
41
+ @action && !get?
42
+ end
43
+
44
+ def render_input?
45
+ @input_arguments[:name].present?
46
+ end
47
+
48
+ private
49
+
50
+ def extract_http_method(args)
51
+ if (http_method = args.delete(:method))
52
+ if HTTP_METHOD_OPTIONS.include?(http_method)
53
+ http_method
54
+ else
55
+ DEFAULT_HTTP_METHOD
56
+ end
57
+ else
58
+ DEFAULT_HTTP_METHOD
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pulse
4
+ class ActionList
5
+ # Heading used to describe each sub list within an action list.
6
+ class Heading < Pulse::Component
7
+ DEFAULT_SCHEME = :subtle
8
+ SCHEME_MAPPINGS = {
9
+ DEFAULT_SCHEME => nil,
10
+ :filled => 'ActionList-sectionDivider--filled'
11
+ }.freeze
12
+ SCHEME_OPTIONS = SCHEME_MAPPINGS.keys.freeze
13
+ HEADING_MIN = 1
14
+ HEADING_MAX = 6
15
+ HEADING_LEVELS = (HEADING_MIN..HEADING_MAX).to_a.freeze
16
+
17
+ attr_reader :title_id, :subtitle_id
18
+
19
+ # @param title [String] Sub list title.
20
+ # @param heading_level [Integer] Heading level. Level 2 results in an `<h2>` tag, level 3 an `<h3>` tag, etc.
21
+ # @param subtitle [String] Optional sub list description.
22
+ # @param scheme [Symbol] Display a background color if scheme is `filled`.
23
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
24
+ def initialize(title:, heading_level: 3, scheme: DEFAULT_SCHEME,
25
+ subtitle: nil, **system_arguments)
26
+ unless HEADING_LEVELS.include?(heading_level)
27
+ raise "Heading level must be between #{HEADING_MIN} and " \
28
+ "#{HEADING_MAX}"
29
+ end
30
+
31
+ @heading_level = heading_level
32
+ @tag = :"h#{heading_level}"
33
+ @system_arguments = deny_tag_argument(**system_arguments)
34
+ @title = title
35
+ @subtitle = subtitle
36
+ @scheme = fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)
37
+ @system_arguments[:classes] = class_names(
38
+ 'ActionList-sectionDivider',
39
+ SCHEME_MAPPINGS[@scheme],
40
+ @system_arguments[:classes]
41
+ )
42
+
43
+ @title_id = self.class.generate_id(base_name: 'heading-title')
44
+ @subtitle_id = self.class.generate_id(base_name: 'heading-subtitle')
45
+ end
46
+
47
+ def subtitle?
48
+ @subtitle.present?
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,43 @@
1
+ /! components/pulse/action_list/item
2
+ = render(Pulse::BaseComponent.new(tag: :li, **@system_arguments)) do
3
+ = render(@form_wrapper) do
4
+ = render(Pulse::BaseComponent.new(**@content_arguments)) do
5
+ - if private_leading_action_icon
6
+ span class="pulse-fill-gray-900"
7
+ = private_leading_action_icon
8
+
9
+ - if list.select_variant == :single || list.select_variant == :multiple
10
+ span class="pulse-fill-gray-900"
11
+ = render(Pulse::Icon.new(icon: :check, width: 16, height: 16, classes: "ActionListItem-singleSelectCheckmark"))
12
+
13
+ - elsif list.select_variant == :multiple_checkbox
14
+ span class="pulse-fill-gray-900"
15
+ svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" class="ActionListItem-multiSelectIcon"
16
+ rect x="2" y="2" width="12" height="12" rx="4" class="ActionListItem-multiSelectIconRect"
17
+ path fill-rule="evenodd" d="M4.03231 8.69862C3.84775 8.20646 4.49385 7.77554 4.95539 7.77554C5.41693 7.77554 6.80154 9.85246 6.80154 9.85246C6.80154 9.85246 10.2631 4.314 10.4938 4.08323C10.7246 3.85246 11.8785 4.08323 11.4169 5.00631C11.0081 5.82388 7.26308 11.4678 7.26308 11.4678C7.26308 11.4678 6.80154 12.1602 6.34 11.4678C5.87846 10.7755 4.21687 9.19077 4.03231 8.69862Z" class="ActionListItem-multiSelectCheckmark"
18
+
19
+ - if leading_visual
20
+ span class="pulse-fill-gray-900"
21
+ = leading_visual
22
+
23
+ = render(Pulse::ConditionalWrapper.new(condition: description?, tag: :span, **@description_wrapper_arguments)) do
24
+ = render(Pulse::BaseComponent.new(tag: :span, **@label_arguments)) do
25
+ = @label || content
26
+
27
+ - if description?
28
+ span class="ActionListItem-description"
29
+ = description
30
+
31
+ - if trailing_visual
32
+ span class="pulse-fill-gray-100 ActionListItem-visual--trailing"
33
+ = trailing_visual
34
+
35
+ - if private_trailing_action_icon
36
+ span class="pulse-fill-gray-100 ActionListItem-action--trailing"
37
+ = private_trailing_action_icon
38
+
39
+ = tooltip
40
+ - if trailing_action
41
+ = trailing_action
42
+
43
+ = private_content
@@ -0,0 +1,319 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pulse
4
+ class ActionList
5
+ # An individual `ActionList` item. Items can optionally include leading and/or trailing visuals,
6
+ # such as icons, avatars, and counters.
7
+ class Item < Pulse::Component
8
+ DEFAULT_SIZE = :medium
9
+ SIZE_MAPPINGS = {
10
+ DEFAULT_SIZE => nil
11
+ # :large => "ActionListContent--sizeLarge",
12
+ # :xlarge => "ActionListContent--sizeXLarge"
13
+ }.freeze
14
+ SIZE_OPTIONS = SIZE_MAPPINGS.keys.freeze
15
+
16
+ DEFAULT_DESCRIPTION_SCHEME = :block
17
+ DESCRIPTION_SCHEME_MAPPINGS = {
18
+ :inline => 'ActionListItem-descriptionWrap--inline',
19
+ DEFAULT_DESCRIPTION_SCHEME => 'ActionListItem-descriptionWrap'
20
+ }.freeze
21
+ DESCRIPTION_SCHEME_OPTIONS = DESCRIPTION_SCHEME_MAPPINGS.keys.freeze
22
+
23
+ DEFAULT_SCHEME = :default
24
+ SCHEME_MAPPINGS = {
25
+ DEFAULT_SCHEME => nil,
26
+ :danger => 'ActionListItem--danger'
27
+ }.freeze
28
+ SCHEME_OPTIONS = SCHEME_MAPPINGS.keys.freeze
29
+
30
+ # Description content that complements the item's label. See `ActionList`'s `description_scheme` argument
31
+ # for layout options.
32
+ renders_one :description
33
+
34
+ # An icon, avatar, SVG, or custom content that will render to the left of the label.
35
+ #
36
+ # To render an icon, call the `with_leading_visual_icon` method, which accepts the arguments accepted by <%= link_to_component(Pulse::Icon) %>.
37
+ #
38
+ # To render an SVG, call the `with_leading_visual_svg` method.
39
+ #
40
+ # To render custom content, call the `with_leading_visual_content` method and pass a block that returns a string.
41
+ renders_one :leading_visual, types: {
42
+ icon: lambda { |**system_arguments, &block|
43
+ deny_aria_key(
44
+ :label,
45
+ 'Avoid using `aria-label` on leading visual icons, as they are ' \
46
+ 'purely decorative.',
47
+ **system_arguments
48
+ )
49
+
50
+ Pulse::Icon.new(**system_arguments, &block)
51
+ },
52
+ avatar: lambda { |*|
53
+ return unless should_raise_error?
54
+
55
+ raise 'Leading visual avatars are no longer supported. Please use ' \
56
+ 'the #with_avatar_item slot instead.'
57
+ },
58
+ svg: lambda { |**system_arguments|
59
+ Pulse::BaseComponent.new(tag: :svg, width: '16', height: '16',
60
+ **system_arguments)
61
+ },
62
+ content: lambda { |**system_arguments|
63
+ Pulse::BaseComponent.new(tag: :span, **system_arguments)
64
+ },
65
+ raw_content: nil
66
+ }
67
+
68
+ # Used internally.
69
+ #
70
+ # @private
71
+ renders_one :private_leading_action_icon, Pulse::Icon
72
+
73
+ # An icon, label, counter, or text to render to the right of the label.
74
+ #
75
+ # To render an icon, call the `with_leading_visual_icon` method, which accepts the arguments accepted by <%= link_to_component(Pulse::Icon) %>.
76
+ #
77
+ # To render a label, call the `with_leading_visual_label` method, which accepts the arguments accepted by <%= link_to_component(Pulse::Label) %>.
78
+ #
79
+ # To render a counter, call the `with_leading_visual_counter` method, which accepts the arguments accepted by <%= link_to_component(Pulse::Counter) %>.
80
+ #
81
+ # To render text, call the `with_leading_visual_text` method and pass a block that returns a string. Eg:
82
+ # ```ruby
83
+ # with_leading_visual_text { "Text here" }
84
+ # ```
85
+ renders_one :trailing_visual, types: {
86
+ icon: Pulse::Icon,
87
+ label: Pulse::Label,
88
+ counter: Pulse::Counter,
89
+ text: ->(text) { text }
90
+ }
91
+
92
+ # Used internally.
93
+ #
94
+ # @private
95
+ renders_one :private_trailing_action_icon, Pulse::Icon
96
+
97
+ # A button rendered after the trailing icon that can be used to show a menu, activate
98
+ # a dialog, etc.
99
+ #
100
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Pulse::IconButton) %>.
101
+ renders_one :trailing_action, lambda { |**system_arguments|
102
+ Pulse::IconButton.new(
103
+ scheme: :invisible,
104
+ classes: merge_classes(
105
+ system_arguments[:classes],
106
+ 'ActionListItem-trailingAction'
107
+ ),
108
+
109
+ **system_arguments
110
+ )
111
+ }
112
+
113
+ # `Tooltip` that appears on mouse hover or keyboard focus over the trailing action button. Use tooltips sparingly and as
114
+ # a last resort. **Important:** This tooltip defaults to `type: :description`. In a few scenarios, `type: :label` may be
115
+ # more appropriate. Consult the <%= link_to_component(Pulse::Tooltip) %> documentation for more information.
116
+ #
117
+ # @param type [Symbol] (:description) <%= one_of(Pulse::Tooltip::TYPE_OPTIONS) %>
118
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Pulse::Tooltip) %>.
119
+ renders_one :tooltip, lambda { |**system_arguments|
120
+ if @id.blank? && !Rails.env.production?
121
+ raise ArgumentError,
122
+ 'Buttons with a tooltip must have a unique `id` set on ' \
123
+ 'the `Button`.'
124
+ end
125
+
126
+ system_arguments[:for_id] = @id
127
+ system_arguments[:type] ||= :description
128
+
129
+ Pulse::Tooltip.new(**system_arguments)
130
+ }
131
+
132
+ # Used internally.
133
+ #
134
+ # @private
135
+ renders_one :private_content
136
+
137
+ attr_reader :id, :list, :href, :active, :disabled, :parent
138
+
139
+ # Whether or not this item is active.
140
+ #
141
+ # @return [Boolean]
142
+ alias active? active
143
+
144
+ # Whether or not this item is disabled.
145
+ #
146
+ # @return [Boolean]
147
+ alias disabled? disabled
148
+
149
+ # @param list [Pulse::ActionList] The list that contains this item. Used internally.
150
+ # @param parent [Pulse::ActionList::Item] This item's parent item. `nil` if this item is at the root. Used internally.
151
+ # @param label [String] Item label. If no label is provided, content is used.
152
+ # @param label_classes [String] CSS classes that will be added to the label.
153
+ # @param label_arguments [Hash] <%= link_to_system_arguments_docs %> used to construct the label.
154
+ # @param content_arguments [Hash] <%= link_to_system_arguments_docs %> used to construct the item's anchor or button tag.
155
+ # @param form_arguments [Hash] Allows the item to submit a form on click. The URL passed in the `href:` option will be used as the form action. Pass the `method:` option to this hash to control what kind of request is made, <%= one_of(Pulse::ActionList::FormWrapper::HTTP_METHOD_OPTIONS) %> The `name:` option is required and specifies the desired name of the field that will be included in the params sent to the server on form submission. Specify the `value:` option to send a custom value to the server; otherwise the value of `name:` is sent.
156
+ # @param truncate_label [Boolean] Truncate label with ellipsis.
157
+ # @param href [String] Link URL.
158
+ # @param role [String] ARIA role describing the function of the item.
159
+ # @param size [Symbol] Controls block sizing of the item.
160
+ # @param scheme [Symbol] Controls color/style based on behavior.
161
+ # @param disabled [Boolean] Disabled items are not clickable and visually dim.
162
+ # @param description_scheme [Symbol] Display description inline with label, or block on the next line. <%= one_of(Pulse::ActionList::Item::DESCRIPTION_SCHEME_OPTIONS) %>
163
+ # @param active [Boolean] If the parent list's `select_variant` is set to `:single` or `:multiple`, causes this item to render checked.
164
+ # @param on_click [String] JavaScript to execute when the item is clicked.
165
+ # @param id [String] Used internally.
166
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
167
+ def initialize(
168
+ list:,
169
+ label: nil,
170
+ label_classes: nil,
171
+ label_arguments: {},
172
+ content_arguments: {},
173
+ form_arguments: {},
174
+ parent: nil,
175
+ truncate_label: false,
176
+ href: nil,
177
+ role: nil,
178
+ size: DEFAULT_SIZE,
179
+ scheme: DEFAULT_SCHEME,
180
+ disabled: false,
181
+ description_scheme: DEFAULT_DESCRIPTION_SCHEME,
182
+ active: false,
183
+ on_click: nil,
184
+ id: self.class.generate_id,
185
+ **system_arguments
186
+ )
187
+ @list = list
188
+ @parent = parent
189
+ @label = label
190
+ @href = href || content_arguments[:href]
191
+ @truncate_label = truncate_label
192
+ @disabled = disabled
193
+ @active = active
194
+ @id = id
195
+ @system_arguments = system_arguments
196
+ @content_arguments = content_arguments
197
+ @form_wrapper = FormWrapper.new(list: @list, action: @href,
198
+ **form_arguments)
199
+
200
+ @size = fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)
201
+ @scheme = fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)
202
+ @description_scheme = fetch_or_fallback(
203
+ DESCRIPTION_SCHEME_OPTIONS,
204
+ description_scheme,
205
+ DEFAULT_DESCRIPTION_SCHEME
206
+ )
207
+
208
+ @system_arguments[:classes] = merge_classes(
209
+ @system_arguments[:classes],
210
+ SCHEME_MAPPINGS[@scheme],
211
+ 'pulse-relative pulse-rounded selected:pulse-font-normal',
212
+ 'ActionListItem--disabled' => @disabled
213
+ )
214
+
215
+ @system_arguments[:data] ||= {}
216
+ @system_arguments[:data][:targets] =
217
+ "#{list_class.custom_element_name}.items"
218
+
219
+ @label_arguments = {
220
+ **label_arguments,
221
+ classes: merge_classes(
222
+ label_classes,
223
+ label_arguments[:classes],
224
+ 'pulse-font-semibold',
225
+ 'ActionListItem-label--truncate' => @truncate_label
226
+ )
227
+ }
228
+
229
+ @content_arguments[:id] = @id
230
+ @content_arguments[:classes] = merge_classes(
231
+ @content_arguments[:classes],
232
+ 'pulse-relative pulse-grid pulse-w-full pulse-text-start',
233
+ 'pulse-select-none pulse-bg-transparent pulse-rounded',
234
+ 'pulse-grid-rows-[min-content]',
235
+ 'pulse-grid-cols-[min-content_min-content_minmax(0,auto)_min-content_min-content]', # rubocop:disable Layout/LineLength
236
+ 'pulse-border-none hover:pulse-no-underline pulse-py-2',
237
+ 'pulse-items-start pulse-gap-2 pulse-items-center',
238
+ SIZE_MAPPINGS[@size]
239
+ )
240
+
241
+ unless @content_arguments[:tag]
242
+ if @href && @form_wrapper.get? && !@disabled
243
+ @content_arguments[:tag] = :a
244
+ @content_arguments[:href] = @href
245
+ else
246
+ @content_arguments[:tag] = :button
247
+ @content_arguments[:type] =
248
+ @form_wrapper.form_required? ? :submit : :button
249
+ @content_arguments[:onclick] = on_click if on_click
250
+ end
251
+ end
252
+
253
+ if @content_arguments[:tag] != :button && @form_wrapper.form_required?
254
+ raise ArgumentError,
255
+ "items that submit forms must use a \"button\" tag instead " \
256
+ "of \"#{@content_arguments[:tag]}\""
257
+ end
258
+
259
+ if @content_arguments[:tag] != :button && @list.acts_as_form_input?
260
+ raise ArgumentError,
261
+ "items within lists/menus that act as form inputs must use " \
262
+ "\"button\" tags instead of \"#{@content_arguments[:tag]}\""
263
+ end
264
+ if @disabled
265
+ @content_arguments[:aria] ||= merge_aria(
266
+ @content_arguments,
267
+ { aria: { disabled: 'true' } }
268
+ )
269
+ end
270
+
271
+ @content_arguments[:role] =
272
+ role ||
273
+ if @list.allows_selection?
274
+ ActionList::SELECT_VARIANT_ROLE_MAP[@list.select_variant]
275
+ elsif @list.acts_as_menu?
276
+ ActionList::DEFAULT_MENU_ITEM_ROLE
277
+ end
278
+
279
+ @system_arguments[:role] = @list.acts_as_menu? ? :none : nil
280
+
281
+ @description_wrapper_arguments = {
282
+ classes: merge_classes(
283
+ 'ActionListItem-descriptionWrap',
284
+ DESCRIPTION_SCHEME_MAPPINGS[@description_scheme]
285
+ )
286
+ }
287
+ end
288
+
289
+ private
290
+
291
+ def before_render
292
+ if @list.allows_selection?
293
+ @content_arguments[:aria] = merge_aria(
294
+ @content_arguments,
295
+ { aria: { checked: active? } }
296
+ )
297
+ end
298
+
299
+ @system_arguments[:classes] = merge_classes(
300
+ @system_arguments[:classes],
301
+ 'ActionListItem--withActions' => trailing_action.present?
302
+ )
303
+
304
+ return unless leading_visual
305
+
306
+ @content_arguments[:classes] = merge_classes(
307
+ @content_arguments[:classes],
308
+ 'pulse-pl-2' => leading_visual,
309
+ 'ActionListContent--blockDescription' =>
310
+ description && @description_scheme == :block
311
+ )
312
+ end
313
+
314
+ def list_class
315
+ Pulse::ActionList
316
+ end
317
+ end
318
+ end
319
+ end