ariadne_view_components 0.0.59 → 0.0.65

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 (279) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -0
  3. data/LICENSE.txt +661 -49
  4. data/README.md +52 -4
  5. data/app/assets/javascripts/ariadne_view_components.js +98 -7
  6. data/app/assets/javascripts/ariadne_view_components.js.br +0 -0
  7. data/app/assets/javascripts/ariadne_view_components.js.gz +0 -0
  8. data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
  9. data/app/assets/stylesheets/ariadne_view_components.css +1 -7
  10. data/app/assets/stylesheets/ariadne_view_components.css.br +0 -0
  11. data/app/assets/stylesheets/ariadne_view_components.css.gz +0 -0
  12. data/app/components/ariadne/base_component.rb +79 -27
  13. data/app/components/ariadne/behaviors/tooltipable.rb +120 -0
  14. data/app/components/ariadne/conditional_wrapper.rb +21 -0
  15. data/app/components/ariadne/form/base_component.rb +74 -0
  16. data/app/components/ariadne/form/base_input_component.rb +60 -0
  17. data/app/components/ariadne/form/caption/component.html.erb +10 -0
  18. data/app/components/ariadne/form/caption/component.rb +29 -0
  19. data/app/components/ariadne/form/form_control/component.html.erb +19 -0
  20. data/app/components/ariadne/form/form_control/component.rb +27 -0
  21. data/app/components/ariadne/form/form_reference/component.html.erb +1 -0
  22. data/app/components/ariadne/form/form_reference/component.rb +18 -0
  23. data/app/components/ariadne/form/group/component.html.erb +5 -0
  24. data/app/components/ariadne/form/group/component.rb +27 -0
  25. data/app/components/ariadne/form/hidden_field/component.html.erb +1 -0
  26. data/app/components/ariadne/form/hidden_field/component.rb +15 -0
  27. data/app/components/ariadne/form/separator/component.html.erb +1 -0
  28. data/app/components/ariadne/form/separator/component.rb +8 -0
  29. data/app/components/ariadne/form/spacing_wrapper/component.html.erb +3 -0
  30. data/app/components/ariadne/form/spacing_wrapper/component.rb +8 -0
  31. data/app/components/ariadne/form/text_field/component.html.erb +25 -0
  32. data/app/components/ariadne/form/text_field/component.rb +132 -0
  33. data/app/components/ariadne/form/validation_message/component.html.erb +5 -0
  34. data/app/components/ariadne/form/validation_message/component.rb +14 -0
  35. data/app/components/ariadne/layout/narrow/component.html.erb +10 -0
  36. data/app/components/ariadne/layout/narrow/component.rb +24 -0
  37. data/app/components/ariadne/layout/nav_bar/component.css +0 -0
  38. data/app/components/ariadne/layout/nav_bar/component.html.erb +123 -0
  39. data/app/components/ariadne/layout/nav_bar/component.rb +77 -0
  40. data/app/components/ariadne/ui/button/component.html.erb +5 -0
  41. data/app/components/ariadne/ui/button/component.rb +184 -0
  42. data/app/components/ariadne/ui/clipboard_copy/component.html.erb +8 -0
  43. data/app/components/ariadne/ui/clipboard_copy/component.rb +102 -0
  44. data/app/components/ariadne/ui/clipboard_copy/component.ts +54 -0
  45. data/app/components/ariadne/ui/combobox/component.html.erb +32 -0
  46. data/app/components/ariadne/ui/combobox/component.rb +83 -0
  47. data/app/components/ariadne/ui/combobox/component.ts +119 -0
  48. data/app/components/ariadne/ui/combobox/menu_item/component.html.erb +9 -0
  49. data/app/components/ariadne/ui/combobox/menu_item/component.rb +53 -0
  50. data/app/components/ariadne/ui/combobox/option/component.html.erb +11 -0
  51. data/app/components/ariadne/ui/combobox/option/component.rb +45 -0
  52. data/app/components/ariadne/ui/heroicon/component.html.erb +3 -0
  53. data/app/components/ariadne/ui/heroicon/component.rb +141 -0
  54. data/app/components/ariadne/ui/image/component.rb +69 -0
  55. data/app/components/ariadne/ui/link/component.html.erb +3 -0
  56. data/app/components/ariadne/ui/link/component.rb +56 -0
  57. data/app/components/ariadne/ui/typography/component.html.erb +3 -0
  58. data/app/components/ariadne/ui/typography/component.rb +41 -0
  59. data/app/frontend/ariadne/index.ts +14 -0
  60. data/app/frontend/ariadne/stimulus_app.ts +53 -0
  61. data/app/frontend/ariadne/theme.ts +8 -0
  62. data/app/frontend/controllers/tooltip.ts +75 -0
  63. data/app/frontend/entrypoints/application.ts +1 -0
  64. data/app/frontend/stylesheets/ariadne_view_components.css +18 -0
  65. data/app/frontend/stylesheets/scrollbar.css +28 -0
  66. data/app/frontend/stylesheets/tippy.js/themes/tomato.css +4 -0
  67. data/app/frontend/stylesheets/typography.css +117 -0
  68. data/app/frontend/utils/createController.ts +95 -0
  69. data/app/helpers/ariadne/form_helper.rb +31 -0
  70. data/app/lib/ariadne/attributes_helper.rb +119 -0
  71. data/app/lib/ariadne/fetch_or_fallback_helper.rb +1 -1
  72. data/app/lib/ariadne/form.rb +16 -0
  73. data/app/lib/ariadne/view_helper.rb +2 -5
  74. data/app/lib/view_components_contrib/html_attrs.rb +64 -0
  75. data/app/lib/view_components_contrib/style_variants.rb +14 -0
  76. data/lib/ariadne/forms/acts_as_component.rb +125 -0
  77. data/lib/ariadne/forms/base.html.erb +8 -0
  78. data/lib/ariadne/forms/base.rb +132 -0
  79. data/lib/ariadne/forms/buffer_rewriter.rb +51 -0
  80. data/lib/ariadne/forms/builder.rb +88 -0
  81. data/lib/ariadne/forms/dsl/button_input.rb +33 -0
  82. data/lib/ariadne/forms/dsl/form_object.rb +26 -0
  83. data/lib/ariadne/forms/dsl/input.rb +322 -0
  84. data/lib/ariadne/forms/dsl/input_group.rb +34 -0
  85. data/lib/ariadne/forms/dsl/input_methods.rb +157 -0
  86. data/lib/ariadne/forms/dsl/submit_button_input.rb +36 -0
  87. data/lib/ariadne/forms/dsl/text_field_input.rb +73 -0
  88. data/lib/ariadne/forms/utils.rb +34 -0
  89. data/lib/ariadne/generate.rb +11 -0
  90. data/lib/ariadne/view_components/engine.rb +24 -7
  91. data/lib/ariadne/view_components/version.rb +1 -1
  92. data/lib/ariadne/view_components.rb +1 -1
  93. data/lib/ariadne/yard/backend.rb +24 -0
  94. data/lib/ariadne/yard/component_manifest.rb +148 -0
  95. data/lib/ariadne/yard/component_ref.rb +49 -0
  96. data/lib/ariadne/yard/docs_helper.rb +98 -0
  97. data/lib/ariadne/yard/info_arch_docs_helper.rb +31 -0
  98. data/lib/ariadne/yard/lookbook_docs_helper.rb +32 -0
  99. data/lib/ariadne/yard/lookbook_pages_backend.rb +235 -0
  100. data/lib/ariadne/yard/registry.rb +136 -0
  101. data/lib/ariadne/yard/renders_many_handler.rb +23 -0
  102. data/lib/ariadne/yard/renders_one_handler.rb +23 -0
  103. data/lib/ariadne/yard.rb +19 -0
  104. data/static/arguments.yml +141 -48
  105. data/static/audited_at.json +0 -9
  106. data/static/classes.yml +210 -209
  107. data/static/constants.json +2 -209
  108. data/static/statuses.json +0 -9
  109. metadata +140 -210
  110. data/app/assets/builds/ariadne_view_components.css +0 -2202
  111. data/app/assets/javascripts/components/ariadne/accumulator_controller/accumulator_controller.d.ts +0 -22
  112. data/app/assets/javascripts/components/ariadne/ariadne-form.d.ts +0 -22
  113. data/app/assets/javascripts/components/ariadne/ariadne.d.ts +0 -2
  114. data/app/assets/javascripts/components/ariadne/clipboard_copy_component/clipboard-copy-component.d.ts +0 -4
  115. data/app/assets/javascripts/components/ariadne/dropdown/menu_component.d.ts +0 -1
  116. data/app/assets/javascripts/components/ariadne/events_controller/events_controller.d.ts +0 -4
  117. data/app/assets/javascripts/components/ariadne/options_controller/options_controller.d.ts +0 -39
  118. data/app/assets/javascripts/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +0 -42
  119. data/app/assets/javascripts/components/ariadne/slideover_component/slideover-component.d.ts +0 -9
  120. data/app/assets/javascripts/components/ariadne/string_match_controller/string_match_controller.d.ts +0 -27
  121. data/app/assets/javascripts/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +0 -48
  122. data/app/assets/javascripts/components/ariadne/tab_container_component/tab-container-component.d.ts +0 -1
  123. data/app/assets/javascripts/components/ariadne/tab_nav_component/tab-nav-component.d.ts +0 -9
  124. data/app/assets/javascripts/components/ariadne/time_ago_component/time-ago-component.d.ts +0 -1
  125. data/app/assets/javascripts/components/ariadne/toggleable_controller/toggleable_controller.d.ts +0 -34
  126. data/app/assets/javascripts/components/ariadne/tooltip_component/tooltip-component.d.ts +0 -24
  127. data/app/assets/stylesheets/dropdown.css +0 -46
  128. data/app/assets/stylesheets/prosemirror.css +0 -323
  129. data/app/assets/stylesheets/tooltip-component.css +0 -37
  130. data/app/components/ariadne/accumulator_controller/accumulator_controller.d.ts +0 -22
  131. data/app/components/ariadne/accumulator_controller/accumulator_controller.js +0 -39
  132. data/app/components/ariadne/accumulator_controller/accumulator_controller.ts +0 -48
  133. data/app/components/ariadne/action_card_component.html.erb +0 -13
  134. data/app/components/ariadne/action_card_component.rb +0 -88
  135. data/app/components/ariadne/ariadne-form.d.ts +0 -22
  136. data/app/components/ariadne/ariadne-form.js +0 -85
  137. data/app/components/ariadne/ariadne.d.ts +0 -2
  138. data/app/components/ariadne/ariadne.js +0 -24
  139. data/app/components/ariadne/ariadne.ts +0 -29
  140. data/app/components/ariadne/avatar_component.rb +0 -81
  141. data/app/components/ariadne/avatar_stack_component/avatar_stack_component.html.erb +0 -12
  142. data/app/components/ariadne/avatar_stack_component.rb +0 -75
  143. data/app/components/ariadne/base_button.rb +0 -70
  144. data/app/components/ariadne/blankslate_component/blankslate_component.html.erb +0 -26
  145. data/app/components/ariadne/blankslate_component.rb +0 -148
  146. data/app/components/ariadne/body_component.rb +0 -30
  147. data/app/components/ariadne/bottom_tab_component.html.erb +0 -4
  148. data/app/components/ariadne/bottom_tab_component.rb +0 -44
  149. data/app/components/ariadne/bottom_tab_nav_component.html.erb +0 -5
  150. data/app/components/ariadne/bottom_tab_nav_component.rb +0 -33
  151. data/app/components/ariadne/breadcrumbs_component.html.erb +0 -13
  152. data/app/components/ariadne/breadcrumbs_component.rb +0 -31
  153. data/app/components/ariadne/button_component/button_component.html.erb +0 -4
  154. data/app/components/ariadne/button_component.rb +0 -165
  155. data/app/components/ariadne/checkbox_component.html.erb +0 -5
  156. data/app/components/ariadne/checkbox_component.rb +0 -43
  157. data/app/components/ariadne/clipboard_copy_component/clipboard-copy-component.d.ts +0 -4
  158. data/app/components/ariadne/clipboard_copy_component/clipboard-copy-component.js +0 -18
  159. data/app/components/ariadne/clipboard_copy_component/clipboard-copy-component.ts +0 -19
  160. data/app/components/ariadne/clipboard_copy_component/clipboard_copy_component.html.erb +0 -9
  161. data/app/components/ariadne/clipboard_copy_component.rb +0 -90
  162. data/app/components/ariadne/close_button_component.html.erb +0 -4
  163. data/app/components/ariadne/close_button_component.rb +0 -33
  164. data/app/components/ariadne/combobox_component.html.erb +0 -14
  165. data/app/components/ariadne/combobox_component.rb +0 -76
  166. data/app/components/ariadne/component.rb +0 -127
  167. data/app/components/ariadne/container_component/container_component.html.erb +0 -3
  168. data/app/components/ariadne/container_component.rb +0 -25
  169. data/app/components/ariadne/content.rb +0 -12
  170. data/app/components/ariadne/counter_component.rb +0 -100
  171. data/app/components/ariadne/details_component/details_component.html.erb +0 -4
  172. data/app/components/ariadne/details_component.rb +0 -81
  173. data/app/components/ariadne/dropdown/menu_component.d.ts +0 -1
  174. data/app/components/ariadne/dropdown/menu_component.html.erb +0 -20
  175. data/app/components/ariadne/dropdown/menu_component.js +0 -1
  176. data/app/components/ariadne/dropdown/menu_component.rb +0 -101
  177. data/app/components/ariadne/dropdown/menu_component.ts +0 -1
  178. data/app/components/ariadne/dropdown_component/dropdown_component.html.erb +0 -8
  179. data/app/components/ariadne/dropdown_component.rb +0 -172
  180. data/app/components/ariadne/events_controller/events_controller.d.ts +0 -4
  181. data/app/components/ariadne/events_controller/events_controller.js +0 -6
  182. data/app/components/ariadne/events_controller/events_controller.ts +0 -7
  183. data/app/components/ariadne/flash_component/flash_component.html.erb +0 -31
  184. data/app/components/ariadne/flash_component.rb +0 -128
  185. data/app/components/ariadne/flex_component/flex_component.html.erb +0 -5
  186. data/app/components/ariadne/flex_component.rb +0 -56
  187. data/app/components/ariadne/footer_component/footer_component.html.erb +0 -7
  188. data/app/components/ariadne/footer_component.rb +0 -23
  189. data/app/components/ariadne/grid_component/grid_component.html.erb +0 -26
  190. data/app/components/ariadne/grid_component.rb +0 -67
  191. data/app/components/ariadne/header_component/header_component.html.erb +0 -29
  192. data/app/components/ariadne/header_component.rb +0 -111
  193. data/app/components/ariadne/heading_component.rb +0 -49
  194. data/app/components/ariadne/heroicon_component/heroicon_component.html.erb +0 -4
  195. data/app/components/ariadne/heroicon_component.rb +0 -166
  196. data/app/components/ariadne/image_component.rb +0 -53
  197. data/app/components/ariadne/inline_flex_component/inline_flex_component.html.erb +0 -6
  198. data/app/components/ariadne/inline_flex_component.rb +0 -72
  199. data/app/components/ariadne/layout_component.html.erb +0 -21
  200. data/app/components/ariadne/layout_component.rb +0 -69
  201. data/app/components/ariadne/link_component.rb +0 -65
  202. data/app/components/ariadne/list_component/list_component.html.erb +0 -3
  203. data/app/components/ariadne/list_component.rb +0 -70
  204. data/app/components/ariadne/modal_component.html.erb +0 -11
  205. data/app/components/ariadne/modal_component.rb +0 -88
  206. data/app/components/ariadne/narrow_container_component/narrow_container_component.html.erb +0 -3
  207. data/app/components/ariadne/narrow_container_component.rb +0 -30
  208. data/app/components/ariadne/options_controller/options_controller.d.ts +0 -39
  209. data/app/components/ariadne/options_controller/options_controller.js +0 -89
  210. data/app/components/ariadne/options_controller/options_controller.ts +0 -122
  211. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +0 -42
  212. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.js +0 -237
  213. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.ts +0 -278
  214. data/app/components/ariadne/panel_bar_component/panel_bar_component.html.erb +0 -20
  215. data/app/components/ariadne/panel_bar_component.rb +0 -80
  216. data/app/components/ariadne/pill_component/pill_component.html.erb +0 -3
  217. data/app/components/ariadne/pill_component.rb +0 -44
  218. data/app/components/ariadne/popover_component.html.erb +0 -10
  219. data/app/components/ariadne/popover_component.rb +0 -81
  220. data/app/components/ariadne/progress_bar_component.html.erb +0 -5
  221. data/app/components/ariadne/progress_bar_component.rb +0 -63
  222. data/app/components/ariadne/relative_time_component.html.erb +0 -3
  223. data/app/components/ariadne/relative_time_component.rb +0 -61
  224. data/app/components/ariadne/show_more_button_component.html.erb +0 -11
  225. data/app/components/ariadne/show_more_button_component.rb +0 -47
  226. data/app/components/ariadne/slideover_component/slideover-component.d.ts +0 -9
  227. data/app/components/ariadne/slideover_component/slideover-component.js +0 -11
  228. data/app/components/ariadne/slideover_component/slideover-component.ts +0 -17
  229. data/app/components/ariadne/slideover_component/slideover_component.html.erb +0 -9
  230. data/app/components/ariadne/slideover_component.rb +0 -66
  231. data/app/components/ariadne/spinner_component.html.erb +0 -16
  232. data/app/components/ariadne/spinner_component.rb +0 -45
  233. data/app/components/ariadne/string_match_controller/string_match_controller.d.ts +0 -27
  234. data/app/components/ariadne/string_match_controller/string_match_controller.js +0 -51
  235. data/app/components/ariadne/string_match_controller/string_match_controller.ts +0 -65
  236. data/app/components/ariadne/subheader_component.html.erb +0 -11
  237. data/app/components/ariadne/subheader_component.rb +0 -65
  238. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +0 -48
  239. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.js +0 -207
  240. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.ts +0 -256
  241. data/app/components/ariadne/tab_component/tab_component.html.erb +0 -3
  242. data/app/components/ariadne/tab_component.rb +0 -98
  243. data/app/components/ariadne/tab_container_component/tab-container-component.d.ts +0 -1
  244. data/app/components/ariadne/tab_container_component/tab-container-component.js +0 -23
  245. data/app/components/ariadne/tab_container_component/tab-container-component.ts +0 -24
  246. data/app/components/ariadne/tab_container_component.erb +0 -10
  247. data/app/components/ariadne/tab_container_component.rb +0 -68
  248. data/app/components/ariadne/tab_nav_component/tab-nav-component.d.ts +0 -9
  249. data/app/components/ariadne/tab_nav_component/tab-nav-component.js +0 -33
  250. data/app/components/ariadne/tab_nav_component/tab-nav-component.ts +0 -34
  251. data/app/components/ariadne/tab_nav_component/tab_nav_component.html.erb +0 -7
  252. data/app/components/ariadne/tab_nav_component.rb +0 -72
  253. data/app/components/ariadne/table_nav_component/table_nav_component.html.erb +0 -52
  254. data/app/components/ariadne/table_nav_component.rb +0 -338
  255. data/app/components/ariadne/text.rb +0 -25
  256. data/app/components/ariadne/time_ago_component/time-ago-component.d.ts +0 -1
  257. data/app/components/ariadne/time_ago_component/time-ago-component.js +0 -1
  258. data/app/components/ariadne/time_ago_component/time-ago-component.ts +0 -1
  259. data/app/components/ariadne/time_ago_component.rb +0 -56
  260. data/app/components/ariadne/timeline_component/timeline_component.html.erb +0 -19
  261. data/app/components/ariadne/timeline_component.rb +0 -34
  262. data/app/components/ariadne/toggle_component/toggle_component.html.erb +0 -15
  263. data/app/components/ariadne/toggle_component.rb +0 -95
  264. data/app/components/ariadne/toggleable_controller/toggleable_controller.d.ts +0 -34
  265. data/app/components/ariadne/toggleable_controller/toggleable_controller.js +0 -54
  266. data/app/components/ariadne/toggleable_controller/toggleable_controller.ts +0 -77
  267. data/app/components/ariadne/tooltip_component/tooltip-component.d.ts +0 -24
  268. data/app/components/ariadne/tooltip_component/tooltip-component.js +0 -43
  269. data/app/components/ariadne/tooltip_component/tooltip-component.ts +0 -57
  270. data/app/components/ariadne/tooltip_component/tooltip_component.html.erb +0 -4
  271. data/app/components/ariadne/tooltip_component.rb +0 -108
  272. data/app/lib/ariadne/action_view_extensions/form_helper.rb +0 -30
  273. data/app/lib/ariadne/audited/dsl.rb +0 -32
  274. data/app/lib/ariadne/form_builder.rb +0 -80
  275. data/app/lib/ariadne/status/dsl.rb +0 -41
  276. data/config/importmap.rb +0 -3
  277. data/exe/tailwindcss +0 -21
  278. data/lib/rubocop/cop/ariadne/base_cop.rb +0 -26
  279. data/tailwind.config.js +0 -70
@@ -0,0 +1,25 @@
1
+ <div class="ariadne-space-y-2">
2
+ <label
3
+ class="<%= style(:label) %>"
4
+ for="<%= @name %>"><%= @label %></label>
5
+ <% if required? %>
6
+ <span aria-hidden="true">*</span>
7
+ <% end %>
8
+
9
+ <%= content_tag(
10
+ :input,
11
+ nil,
12
+ class: html_attrs[:class],
13
+ **html_attrs.except(:class)
14
+ ) %>
15
+
16
+ <% if @validation_message %>
17
+ <%= render(Primer::BaseComponent.new(tag: :div, **@validation_arguments)) do %>
18
+ <span class="FormControl-inlineValidation--visual"><%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %></span>
19
+ <span><%= @validation_message %></span>
20
+ <% end %>
21
+ <% end %>
22
+ <% if caption? %>
23
+ <p id="<%= @name %>-description" class="<%= style(:caption, theme:, size:, width:) %>"><%= @caption %></p>
24
+ <% end %>
25
+ </div>
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ module Form
5
+ module TextField
6
+ class Component < Ariadne::Form::BaseInputComponent
7
+ option :name
8
+ option :label
9
+ option :type, default: proc { :text }
10
+
11
+ # renders_one :leading_visual, ACCEPT_ANYTHING
12
+ # renders_one :trailing_visual, ACCEPT_ANYTHING
13
+
14
+ option :theme, default: proc { :primary }
15
+ option :size, default: proc { :base }
16
+ option :width, default: proc { :narrow }
17
+
18
+ accepts_html_attributes do |html_attrs|
19
+ html_attrs[:class] = style(theme:, size:, width:)
20
+ html_attrs[:type] = @type
21
+ end
22
+
23
+ def type
24
+ :text_field
25
+ end
26
+
27
+ def focusable?
28
+ true
29
+ end
30
+
31
+ style do
32
+ base do
33
+ [
34
+ "focus:ariadne-border-blue-300",
35
+ "focus:ariadne-bg-blue-300/20",
36
+ "dark:focus:ariadne-border-blue-600",
37
+ "dark:focus:ariadne-bg-blue-600/20",
38
+
39
+ "placeholder:ariadne-text-zinc-600",
40
+ "dark:placeholder:ariadne-text-zinc-400",
41
+
42
+ "disabled:ariadne-bg-zinc-200",
43
+ "disabled:ariadne-text-zinc-400",
44
+ "dark:disabled:ariadne-bg-zinc-800",
45
+ "dark:disabled:ariadne-text-zinc-600",
46
+ "disabled:ariadne-cursor-not-allowed",
47
+
48
+ "ariadne-bg-white",
49
+ "dark:ariadne-bg-zinc-900",
50
+
51
+ "ariadne-border",
52
+ "ariadne-border-solid",
53
+ "ariadne-border-zinc-200",
54
+ "ariadne-dark:border-zinc-700",
55
+
56
+ "[&:not(:focus)]:enabled:hover:ariadne-border-zinc-300",
57
+ "[&:not(:focus)]:enabled:hover:ariadne-bg-zinc-200/20",
58
+ "[&:not(:focus)]:dark:enabled:hover:ariadne-border-zinc-600",
59
+ "[&:not(:focus)]:dark:enabled:hover:ariadne-bg-zinc-700/20",
60
+
61
+ "focus:ariadne-border-blue-300",
62
+ "focus:ariadne-bg-blue-300/20",
63
+ "dark:focus:ariadne-border-blue-600",
64
+ "dark:focus:ariadne-bg-blue-600/20",
65
+ ]
66
+ end
67
+
68
+ variants do
69
+ theme do
70
+ primary do
71
+ []
72
+ end
73
+
74
+ error do
75
+ [
76
+ "ariadne-border",
77
+ "ariadne-border-solid",
78
+ "ariadne-border-red-600",
79
+ "ariadne-bg-red-200",
80
+ "dark:ariadne-bg-red-900",
81
+ "[&:not(:focus)]:enabled:hover:ariadne-border-red-700",
82
+ "[&:not(:focus)]:enabled:hover:ariadne-bg-red-300/80",
83
+ "[&:not(:focus)]:dark:enabled:hover:ariadne-border-red-700",
84
+ "[&:not(:focus)]:dark:enabled:hover:ariadne-bg-red-900/80",
85
+ ]
86
+ end
87
+ end
88
+
89
+ size do
90
+ sm { "ariadne-text-sm ariadne-px-1 ariadne-leading-5 ariadne-rounded" }
91
+ base { "ariadne-text-base ariadne-px-1.5 ariadne-leading-7 ariadne-rounded-md" }
92
+ lg { "ariadne-text-lg ariadne-leading-10 ariadne-px-2.5 ariadne-rounded-lg" }
93
+ end
94
+
95
+ width do
96
+ narrow { "" }
97
+ full { "ariadne-w-full" }
98
+ end
99
+ end
100
+ end
101
+
102
+ style(:label) do
103
+ base do
104
+ [
105
+ "peer-disabled:ariadne-cursor-not-allowed",
106
+ "peer-disabled:ariadne-opacity-70",
107
+ "ariadne-leading-none",
108
+ "ariadne-font-medium",
109
+ ]
110
+ end
111
+
112
+ variants do
113
+ size do
114
+ sm { "ariadne-px-1 ariadne-rounded" }
115
+ base { "ariadne-px-1.5 ariadne-rounded-md" }
116
+ md { "ariadne-px-1.5 ariadne-rounded-md" }
117
+ lg { "ariadne-px-2.5 ariadne-rounded-lg" }
118
+ end
119
+ end
120
+ end
121
+
122
+ style(:caption) do
123
+ [
124
+ "ariadne-mt-2",
125
+ "ariadne-text-sm",
126
+ "ariadne-text-gray-500",
127
+ ]
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,5 @@
1
+ <%= content_tag(:div, **@input.validation_arguments) do %>
2
+ <span class="FormControl-inlineValidation--visual" data-target="<%= @input.validation_success_icon_target %>" hidden><%= render(Ariadne::UI::Heroicon::Component.new(icon: :"check-circle", variant: HeroiconsHelper::Icon::VARIANT_SOLID, size: :xs, html_attrs: { aria: { hidden: true }})) %></span>
3
+ <span class=" FormControl-inlineValidation--visual" data-target="<%= @input.validation_error_icon_target %>"><%= render(Ariadne::UI::Heroicon::Component.new(icon: :"exclamation-triangle", variant: HeroiconsHelper::Icon::VARIANT_SOLID, size: :xs, html_attrs: { aria: { hidden: true }})) %></span>
4
+ <%= content_tag(:span, @input.invalid? ? @input.validation_messages.first : "", **@input.validation_message_arguments) %>
5
+ <% end %>
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ module Form
5
+ # :nodoc:
6
+ class ValidationMessage < BaseComponent
7
+ attr_reader :input
8
+
9
+ def initialize(input:)
10
+ @input = input
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ <main class="ariadne-grow ariadne-py-6 ariadne-px-1">
2
+ <div class="ariadne-mt-10 sm:ariadne-mx-auto sm:ariadne-w-full sm:ariadne-max-w-[480px]">
3
+ <div class="ariadne-bg-white ariadne-px-6 ariadne-py-12 ariadne-shadow sm:ariadne-rounded-lg sm:ariadne-px-12">
4
+ <%= content %>
5
+ </div>
6
+ <% if footer? %>
7
+ <%= footer %>
8
+ <% end %>
9
+ </div>
10
+ </main>
@@ -0,0 +1,24 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ module Ariadne
5
+ module Layout
6
+ module Narrow
7
+ class Component < BaseComponent
8
+ renders_one :footer, Ariadne::BaseComponent::ACCEPT_ANYTHING
9
+
10
+ style do
11
+ base do
12
+ [
13
+ "ariadne-grow",
14
+ "ariadne-bg-zinc-50",
15
+ "dark:ariadne-bg-zinc-900",
16
+ "ariadne-py-6",
17
+ "ariadne-px-1",
18
+ ]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,123 @@
1
+ <header class="<%= style %>">
2
+ <div class="ariadne-mx-auto ariadne-px-2 sm:ariadne-px-4 lg:ariadne-px-8">
3
+ <nav class="ariadne-flex ariadne-h-16 ariadne-justify-between">
4
+ <div class="ariadne-flex ariadne-w-16 ariadne-px-2 lg:ariadne-px-0">
5
+ <% leading_items.each_with_index do |leading_item, idx| %>
6
+ <div class="<%= style(:leading_item, initial: initial?(idx)) %>">
7
+ <%= leading_item %>
8
+ </div>
9
+ <% end %>
10
+ </div>
11
+ <%# <div class="flex flex-1 items-center justify-center px-2 lg:ml-6 lg:justify-end">
12
+ <div class="w-full max-w-lg lg:max-w-xs">
13
+ <label for="search" class="sr-only">Search</label>
14
+ <div class="relative">
15
+ <div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
16
+ Heroicon(icon: :search)
17
+ </div>
18
+ <input id="search" name="search" class="block w-full rounded-md border-0 bg-white py-1.5 pl-10 pr-3 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" placeholder="Search" type="search">
19
+ </div>
20
+ </div>
21
+ </div> %>
22
+ <%# <div class="flex items-center lg:hidden">
23
+ <!-- Mobile menu button -->
24
+ <button type="button" class="relative inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-100 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500" aria-controls="mobile-menu" aria-expanded="false">
25
+ <span class="absolute -inset-0.5"></span>
26
+ <span class="sr-only">Open main menu</span>
27
+ <!--
28
+ Icon when menu is closed.
29
+
30
+ Menu open: "hidden", Menu closed: "block"
31
+ -->
32
+ <svg class="block h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
33
+ <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
34
+ </svg>
35
+ <!--
36
+ Icon when menu is open.
37
+
38
+ Menu open: "block", Menu closed: "hidden"
39
+ -->
40
+ <svg class="hidden h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
41
+ <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
42
+ </svg>
43
+ </button>
44
+ </div> %>
45
+ <div class="ariadne-hidden lg:ariadne-ml-4 lg:ariadne-flex lg:ariadne-items-center">
46
+ <% trailing_items.each_with_index do |trailing_item, idx| %>
47
+ <div class="<%= style(:trailing_item, initial: final?(idx)) %>">
48
+ <%= trailing_item %>
49
+ </div>
50
+ <% end %>
51
+ <%# <button type="button" class="relative flex-shrink-0 rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
52
+ <span class="absolute -inset-1.5"></span>
53
+ <span class="sr-only">View notifications</span>
54
+ <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
55
+ <path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
56
+ </svg>
57
+ </button> %>
58
+
59
+ <!-- Profile dropdown -->
60
+ <%# <div class="relative ml-4 flex-shrink-0">
61
+ <div>
62
+ <button type="button" class="relative flex rounded-full bg-white text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2" id="user-menu-button" aria-expanded="false" aria-haspopup="true">
63
+ <span class="absolute -inset-1.5"></span>
64
+ <span class="sr-only">Open user menu</span>
65
+ <img class="h-8 w-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
66
+ </button>
67
+ </div>
68
+
69
+ <!--
70
+ Dropdown menu, show/hide based on menu state.
71
+
72
+ Entering: "transition ease-out duration-100"
73
+ From: "transform opacity-0 scale-95"
74
+ To: "transform opacity-100 scale-100"
75
+ Leaving: "transition ease-in duration-75"
76
+ From: "transform opacity-100 scale-100"
77
+ To: "transform opacity-0 scale-95"
78
+ -->
79
+ <div class="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none" role="menu" aria-orientation="vertical" aria-labelledby="user-menu-button" tabindex="-1">
80
+ <!-- Active: "bg-gray-100", Not Active: "" -->
81
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1" id="user-menu-item-0">Your Profile</a>
82
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1" id="user-menu-item-1">Settings</a>
83
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1" id="user-menu-item-2">Sign out</a>
84
+ </div>
85
+ </div> %>
86
+ </div>
87
+ </nav>
88
+ </div>
89
+
90
+ <!-- Mobile menu, show/hide based on menu state. -->
91
+ <%# <div class="lg:hidden" id="mobile-menu">
92
+ <div class="space-y-1 pb-3 pt-2">
93
+ <!-- Current: "bg-indigo-50 border-indigo-500 text-indigo-700", Default: "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800" -->
94
+ <a href="#" class="block border-l-4 border-indigo-500 bg-indigo-50 py-2 pl-3 pr-4 text-base font-medium text-indigo-700">Dashboard</a>
95
+ <a href="#" class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800">Team</a>
96
+ <a href="#" class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800">Projects</a>
97
+ <a href="#" class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800">Calendar</a>
98
+ </div>
99
+ <div class="border-t border-gray-200 pb-3 pt-4">
100
+ <div class="flex items-center px-4">
101
+ <div class="flex-shrink-0">
102
+ <img class="h-10 w-10 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
103
+ </div>
104
+ <div class="ml-3">
105
+ <div class="text-base font-medium text-gray-800">Tom Cook</div>
106
+ <div class="text-sm font-medium text-gray-500">tom@example.com</div>
107
+ </div>
108
+ <button type="button" class="relative ml-auto flex-shrink-0 rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
109
+ <span class="absolute -inset-1.5"></span>
110
+ <span class="sr-only">View notifications</span>
111
+ <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
112
+ <path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
113
+ </svg>
114
+ </button>
115
+ </div>
116
+ <div class="mt-3 space-y-1">
117
+ <a href="#" class="block px-4 py-2 text-base font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-800">Your Profile</a>
118
+ <a href="#" class="block px-4 py-2 text-base font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-800">Settings</a>
119
+ <a href="#" class="block px-4 py-2 text-base font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-800">Sign out</a>
120
+ </div>
121
+ </div>
122
+ </div> %>
123
+ </header>
@@ -0,0 +1,77 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ module Ariadne
5
+ module Layout
6
+ module NavBar
7
+ class Component < Ariadne::BaseComponent
8
+ # Leading items at the far left of the header.
9
+ renders_many :leading_items, BaseComponent::ACCEPT_ANYTHING
10
+
11
+ # Leading items at the far left of the header.
12
+ renders_many :trailing_items, lambda { |static_content = nil, &block|
13
+ next static_content if static_content.present?
14
+
15
+ view_context.capture { block&.call }
16
+ }
17
+
18
+ renders_many :navigation_items, lambda { |static_content = nil, &block|
19
+ next static_content if static_content.present?
20
+
21
+ view_context.capture { block&.call }
22
+ }
23
+
24
+ def initial?(position)
25
+ position.zero?
26
+ end
27
+
28
+ def final?(position)
29
+ position == (leading_items.size - 1)
30
+ end
31
+
32
+ style do
33
+ base do
34
+ [
35
+ "ariadne-bg-white",
36
+ "ariadne-border-b",
37
+ "ariadne-z-50",
38
+ "ariadne-overflow-hidden",
39
+ "ariadne-border-zinc-100",
40
+ "dark:ariadne-border-zinc-900",
41
+ ]
42
+ end
43
+ end
44
+
45
+ style(:leading_item) do
46
+ base do
47
+ [
48
+ "",
49
+ ]
50
+ end
51
+
52
+ variants do
53
+ initial do
54
+ yes { "ariadne-flex ariadne-flex-shrink-0 ariadne-items-center" }
55
+ no { "ariadne-hidden lg:ariadne-ml-6 lg:ariadne-flex lg:ariadne-space-x-8" }
56
+ end
57
+ end
58
+ end
59
+
60
+ style(:trailing_item) do
61
+ base do
62
+ [
63
+ "ariadne-flex",
64
+ "ariadne-flex-1",
65
+ "ariadne-items-center",
66
+ "ariadne-justify-end",
67
+ "ariadne-gap-x-1",
68
+ ]
69
+ end
70
+
71
+ variants do
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,5 @@
1
+ <%= content_tag(button? ? :button : :a, class: html_attrs[:class], **html_attrs.except(:class)) do %>
2
+ <span class="ariadne-flex ariadne-display-grid ariadne-gap-x-1.5">
3
+ <%= leading_visual_icon %><%= content %>
4
+ </span>
5
+ <% end %>
@@ -0,0 +1,184 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ module Ariadne
5
+ module UI
6
+ module Button
7
+ class Component < Ariadne::BaseComponent
8
+ include Ariadne::Behaviors::Tooltipable
9
+
10
+ option :as, default: proc { :button }
11
+ option :href, default: proc { nil }
12
+
13
+ option :type, default: proc { "button" }
14
+ option :state, default: proc { "" }
15
+ option :theme, default: proc { :primary }
16
+ option :size, default: proc { :base }
17
+ option :icon_only, default: proc { :no }
18
+ option :width, default: proc { :narrow }
19
+
20
+ renders_one :leading_visual_icon, lambda { |**attrs|
21
+ Ariadne::UI::Heroicon::Component.new(**attrs)
22
+ }
23
+
24
+ accepts_html_attributes do |html_attrs|
25
+ html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(theme:, size:, icon_only:, width:), html_attrs[:class]].join(" "))
26
+
27
+ if link?
28
+ html_attrs[:href] = href
29
+ html_attrs.delete(:disabled)
30
+ else
31
+ html_attrs[:type] = type
32
+ html_attrs[:disabled] ||= false
33
+ end
34
+ end
35
+
36
+ style do
37
+ base do
38
+ [
39
+ "ariadne-inline-flex",
40
+ "ariadne-items-center",
41
+ "ariadne-justify-center",
42
+ "ariadne-gap-x-1.5",
43
+ "ariadne-rounded",
44
+ "ariadne-px-2",
45
+ "ariadne-py-1",
46
+ "ariadne-font-semibold",
47
+ "ariadne-shadow-sm",
48
+ "ariadne-text-black",
49
+ "focus-visible:ariadne-outline",
50
+ "focus-visible:ariadne-outline-2",
51
+ "focus-visible:ariadne-outline-offset-2",
52
+
53
+ "disabled:ariadne-border-transparent",
54
+ "disabled:ariadne-cursor-not-allowed",
55
+ ]
56
+ end
57
+
58
+ variants do
59
+ theme do
60
+ primary do
61
+ [
62
+ "ariadne-text-white",
63
+
64
+ "ariadne-bg-emerald-600",
65
+ "hover:ariadne-bg-emerald-700",
66
+ "active:ariadne-bg-emerald-800",
67
+
68
+ "disabled:ariadne-bg-emerald-100",
69
+ "disabled:ariadne-text-emerald-400",
70
+ "disabled:dark:ariadne-bg-emerald-900",
71
+ "disabled:dark:ariadne-text-emerald-600",
72
+ ]
73
+ end
74
+ secondary do
75
+ [
76
+ "ariadne-text-black",
77
+
78
+ "ariadne-bg-zinc-100",
79
+ "hover:ariadne-bg-zinc-300/20",
80
+ "active:ariadne-bg-zinc-200/80",
81
+
82
+ "dark:ariadne-text-slate-100",
83
+ "dark:ariadne-bg-zinc-900",
84
+ "dark:ariadne-hover:bg-zinc-800/80",
85
+ "dark:active:ariadne-bg-zinc-700/20",
86
+ ]
87
+ end
88
+ ghost do
89
+ [
90
+ "ariadne-text-black",
91
+ "dark:ariadne-text-white",
92
+ "ariadne-shadow-none",
93
+
94
+ "hover:ariadne-bg-zinc-200/20",
95
+ "active:ariadne-bg-zinc-500/10",
96
+ "active:ariadne-border-transparent",
97
+ "dark:hover:ariadne-bg-zinc-600/20",
98
+ "dark:active:ariadne-bg-zinc-500/10",
99
+ ]
100
+ end
101
+ danger do
102
+ [
103
+ "ariadne-border",
104
+ "ariadne-border-solid",
105
+ "ariadne-border-red-600",
106
+ "ariadne-bg-transparent",
107
+ "ariadne-text-red-600",
108
+ "hover:ariadne-bg-red-500",
109
+ "hover:ariadne-text-white",
110
+ "active:ariadne-text-white",
111
+ "active:ariadne-bg-red-600",
112
+ "dark:active:ariadne-bg-red-400",
113
+ ]
114
+ end
115
+ end
116
+
117
+ size do
118
+ xs do
119
+ [
120
+ "ariadne-text-xs",
121
+ ]
122
+ end
123
+ sm do
124
+ [
125
+ "ariadne-text-sm",
126
+ "ariadne-leading-5",
127
+ ]
128
+ end
129
+ base do
130
+ [
131
+ "ariadne-rounded-md",
132
+ "ariadne-px-2.5",
133
+ "ariadne-py-1.5",
134
+ "ariadne-text-base",
135
+ "ariadne-leading-7",
136
+ ]
137
+ end
138
+ lg do
139
+ [
140
+ "ariadne-rounded-md",
141
+ "ariadne-px-3",
142
+ "ariadne-py-2",
143
+ "ariadne-text-lg",
144
+ "ariadne-leading-8",
145
+ ]
146
+ end
147
+ xl do
148
+ [
149
+ "ariadne-rounded-md",
150
+ "ariadne-px-3.5",
151
+ "ariadne-py-2.5",
152
+ "ariadne-text-xl",
153
+ "ariadne-leading-10",
154
+ ]
155
+ end
156
+ end
157
+
158
+ icon_only do
159
+ yes {}
160
+ no {}
161
+ end
162
+ width do
163
+ narrow {}
164
+ full { "ariadne-w-full ariadne-justify-between" }
165
+ end
166
+ end
167
+ end
168
+
169
+ private
170
+
171
+ def button_tag
172
+ if link?
173
+ "a"
174
+ else
175
+ "button"
176
+ end
177
+ end
178
+
179
+ def link? = as == :link
180
+ def button? = as == :button
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,8 @@
1
+ <clipboard-copy class="<%= style(size:) %>" <%= html_attributes %>>
2
+ <% if content.present? %>
3
+ <%= content %>
4
+ <% else %>
5
+ <%= render Ariadne::UI::Heroicon::Component.new(icon: :"document-duplicate", variant: HeroiconsHelper::Icon::VARIANT_OUTLINE, html_attrs: { data: { "ariadne-ui-clipboard-copy-target" => "initial" }}) %>
6
+ <%= render Ariadne::UI::Heroicon::Component.new(icon: :check, variant: HeroiconsHelper::Icon::VARIANT_OUTLINE, html_attrs: { class: "text-green-600 hidden", data: { "ariadne-ui-clipboard-copy-target" => "confirmed" }}) %>
7
+ <% end %>
8
+ </clipboard-copy>