ariadne_view_components 0.0.59 → 0.0.64

Sign up to get free protection for your applications and to get access to all the features.
Files changed (264) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -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.map +1 -1
  7. data/app/assets/stylesheets/ariadne_view_components.css +1 -7
  8. data/app/components/ariadne/base_component.rb +79 -27
  9. data/app/components/ariadne/behaviors/tooltipable.rb +120 -0
  10. data/app/components/ariadne/conditional_wrapper.rb +21 -0
  11. data/app/components/ariadne/form/base_component.rb +74 -0
  12. data/app/components/ariadne/form/base_input_component.rb +60 -0
  13. data/app/components/ariadne/form/caption/component.html.erb +10 -0
  14. data/app/components/ariadne/form/caption/component.rb +29 -0
  15. data/app/components/ariadne/form/form_control/component.html.erb +19 -0
  16. data/app/components/ariadne/form/form_control/component.rb +27 -0
  17. data/app/components/ariadne/form/form_reference/component.html.erb +1 -0
  18. data/app/components/ariadne/form/form_reference/component.rb +18 -0
  19. data/app/components/ariadne/form/group/component.html.erb +5 -0
  20. data/app/components/ariadne/form/group/component.rb +27 -0
  21. data/app/components/ariadne/form/hidden_field/component.html.erb +1 -0
  22. data/app/components/ariadne/form/hidden_field/component.rb +15 -0
  23. data/app/components/ariadne/form/separator/component.html.erb +1 -0
  24. data/app/components/ariadne/form/separator/component.rb +8 -0
  25. data/app/components/ariadne/form/spacing_wrapper/component.html.erb +3 -0
  26. data/app/components/ariadne/form/spacing_wrapper/component.rb +8 -0
  27. data/app/components/ariadne/form/text_field/component.html.erb +25 -0
  28. data/app/components/ariadne/form/text_field/component.rb +132 -0
  29. data/app/components/ariadne/form/validation_message/component.html.erb +5 -0
  30. data/app/components/ariadne/form/validation_message/component.rb +14 -0
  31. data/app/components/ariadne/layout/narrow/component.html.erb +10 -0
  32. data/app/components/ariadne/layout/narrow/component.rb +24 -0
  33. data/app/components/ariadne/layout/nav_bar/component.css +0 -0
  34. data/app/components/ariadne/layout/nav_bar/component.html.erb +123 -0
  35. data/app/components/ariadne/layout/nav_bar/component.rb +77 -0
  36. data/app/components/ariadne/ui/button/component.html.erb +5 -0
  37. data/app/components/ariadne/ui/button/component.rb +184 -0
  38. data/app/components/ariadne/ui/clipboard_copy/component.html.erb +8 -0
  39. data/app/components/ariadne/ui/clipboard_copy/component.rb +102 -0
  40. data/app/components/ariadne/ui/clipboard_copy/component.ts +54 -0
  41. data/app/components/ariadne/ui/combobox/component.html.erb +32 -0
  42. data/app/components/ariadne/ui/combobox/component.rb +83 -0
  43. data/app/components/ariadne/ui/combobox/component.ts +119 -0
  44. data/app/components/ariadne/ui/combobox/menu_item/component.html.erb +9 -0
  45. data/app/components/ariadne/ui/combobox/menu_item/component.rb +53 -0
  46. data/app/components/ariadne/ui/combobox/option/component.html.erb +11 -0
  47. data/app/components/ariadne/ui/combobox/option/component.rb +45 -0
  48. data/app/components/ariadne/ui/heroicon/component.html.erb +3 -0
  49. data/app/components/ariadne/ui/heroicon/component.rb +141 -0
  50. data/app/components/ariadne/ui/image/component.rb +69 -0
  51. data/app/components/ariadne/ui/link/component.html.erb +3 -0
  52. data/app/components/ariadne/ui/link/component.rb +56 -0
  53. data/app/components/ariadne/ui/typography/component.html.erb +3 -0
  54. data/app/components/ariadne/ui/typography/component.rb +41 -0
  55. data/app/lib/ariadne/attributes_helper.rb +119 -0
  56. data/app/lib/ariadne/fetch_or_fallback_helper.rb +1 -1
  57. data/app/lib/ariadne/form.rb +16 -0
  58. data/app/lib/ariadne/view_helper.rb +2 -5
  59. data/app/lib/view_components_contrib/html_attrs.rb +64 -0
  60. data/app/lib/view_components_contrib/style_variants.rb +14 -0
  61. data/lib/ariadne/forms/acts_as_component.rb +125 -0
  62. data/lib/ariadne/forms/base.html.erb +8 -0
  63. data/lib/ariadne/forms/base.rb +132 -0
  64. data/lib/ariadne/forms/buffer_rewriter.rb +51 -0
  65. data/lib/ariadne/forms/builder.rb +88 -0
  66. data/lib/ariadne/forms/dsl/button_input.rb +33 -0
  67. data/lib/ariadne/forms/dsl/form_object.rb +26 -0
  68. data/lib/ariadne/forms/dsl/input.rb +322 -0
  69. data/lib/ariadne/forms/dsl/input_group.rb +34 -0
  70. data/lib/ariadne/forms/dsl/input_methods.rb +157 -0
  71. data/lib/ariadne/forms/dsl/submit_button_input.rb +36 -0
  72. data/lib/ariadne/forms/dsl/text_field_input.rb +73 -0
  73. data/lib/ariadne/forms/utils.rb +34 -0
  74. data/lib/ariadne/generate.rb +11 -0
  75. data/lib/ariadne/view_components/engine.rb +24 -7
  76. data/lib/ariadne/view_components/version.rb +1 -1
  77. data/lib/ariadne/view_components.rb +1 -1
  78. data/lib/ariadne/yard/backend.rb +24 -0
  79. data/lib/ariadne/yard/component_manifest.rb +148 -0
  80. data/lib/ariadne/yard/component_ref.rb +49 -0
  81. data/lib/ariadne/yard/docs_helper.rb +98 -0
  82. data/lib/ariadne/yard/info_arch_docs_helper.rb +31 -0
  83. data/lib/ariadne/yard/lookbook_docs_helper.rb +32 -0
  84. data/lib/ariadne/yard/lookbook_pages_backend.rb +235 -0
  85. data/lib/ariadne/yard/registry.rb +136 -0
  86. data/lib/ariadne/yard/renders_many_handler.rb +23 -0
  87. data/lib/ariadne/yard/renders_one_handler.rb +23 -0
  88. data/lib/ariadne/yard.rb +19 -0
  89. data/static/arguments.yml +141 -48
  90. data/static/audited_at.json +0 -9
  91. data/static/classes.yml +210 -209
  92. data/static/constants.json +2 -209
  93. data/static/statuses.json +0 -9
  94. metadata +125 -210
  95. data/app/assets/builds/ariadne_view_components.css +0 -2202
  96. data/app/assets/javascripts/components/ariadne/accumulator_controller/accumulator_controller.d.ts +0 -22
  97. data/app/assets/javascripts/components/ariadne/ariadne-form.d.ts +0 -22
  98. data/app/assets/javascripts/components/ariadne/ariadne.d.ts +0 -2
  99. data/app/assets/javascripts/components/ariadne/clipboard_copy_component/clipboard-copy-component.d.ts +0 -4
  100. data/app/assets/javascripts/components/ariadne/dropdown/menu_component.d.ts +0 -1
  101. data/app/assets/javascripts/components/ariadne/events_controller/events_controller.d.ts +0 -4
  102. data/app/assets/javascripts/components/ariadne/options_controller/options_controller.d.ts +0 -39
  103. data/app/assets/javascripts/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +0 -42
  104. data/app/assets/javascripts/components/ariadne/slideover_component/slideover-component.d.ts +0 -9
  105. data/app/assets/javascripts/components/ariadne/string_match_controller/string_match_controller.d.ts +0 -27
  106. data/app/assets/javascripts/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +0 -48
  107. data/app/assets/javascripts/components/ariadne/tab_container_component/tab-container-component.d.ts +0 -1
  108. data/app/assets/javascripts/components/ariadne/tab_nav_component/tab-nav-component.d.ts +0 -9
  109. data/app/assets/javascripts/components/ariadne/time_ago_component/time-ago-component.d.ts +0 -1
  110. data/app/assets/javascripts/components/ariadne/toggleable_controller/toggleable_controller.d.ts +0 -34
  111. data/app/assets/javascripts/components/ariadne/tooltip_component/tooltip-component.d.ts +0 -24
  112. data/app/assets/stylesheets/dropdown.css +0 -46
  113. data/app/assets/stylesheets/prosemirror.css +0 -323
  114. data/app/assets/stylesheets/tooltip-component.css +0 -37
  115. data/app/components/ariadne/accumulator_controller/accumulator_controller.d.ts +0 -22
  116. data/app/components/ariadne/accumulator_controller/accumulator_controller.js +0 -39
  117. data/app/components/ariadne/accumulator_controller/accumulator_controller.ts +0 -48
  118. data/app/components/ariadne/action_card_component.html.erb +0 -13
  119. data/app/components/ariadne/action_card_component.rb +0 -88
  120. data/app/components/ariadne/ariadne-form.d.ts +0 -22
  121. data/app/components/ariadne/ariadne-form.js +0 -85
  122. data/app/components/ariadne/ariadne.d.ts +0 -2
  123. data/app/components/ariadne/ariadne.js +0 -24
  124. data/app/components/ariadne/ariadne.ts +0 -29
  125. data/app/components/ariadne/avatar_component.rb +0 -81
  126. data/app/components/ariadne/avatar_stack_component/avatar_stack_component.html.erb +0 -12
  127. data/app/components/ariadne/avatar_stack_component.rb +0 -75
  128. data/app/components/ariadne/base_button.rb +0 -70
  129. data/app/components/ariadne/blankslate_component/blankslate_component.html.erb +0 -26
  130. data/app/components/ariadne/blankslate_component.rb +0 -148
  131. data/app/components/ariadne/body_component.rb +0 -30
  132. data/app/components/ariadne/bottom_tab_component.html.erb +0 -4
  133. data/app/components/ariadne/bottom_tab_component.rb +0 -44
  134. data/app/components/ariadne/bottom_tab_nav_component.html.erb +0 -5
  135. data/app/components/ariadne/bottom_tab_nav_component.rb +0 -33
  136. data/app/components/ariadne/breadcrumbs_component.html.erb +0 -13
  137. data/app/components/ariadne/breadcrumbs_component.rb +0 -31
  138. data/app/components/ariadne/button_component/button_component.html.erb +0 -4
  139. data/app/components/ariadne/button_component.rb +0 -165
  140. data/app/components/ariadne/checkbox_component.html.erb +0 -5
  141. data/app/components/ariadne/checkbox_component.rb +0 -43
  142. data/app/components/ariadne/clipboard_copy_component/clipboard-copy-component.d.ts +0 -4
  143. data/app/components/ariadne/clipboard_copy_component/clipboard-copy-component.js +0 -18
  144. data/app/components/ariadne/clipboard_copy_component/clipboard-copy-component.ts +0 -19
  145. data/app/components/ariadne/clipboard_copy_component/clipboard_copy_component.html.erb +0 -9
  146. data/app/components/ariadne/clipboard_copy_component.rb +0 -90
  147. data/app/components/ariadne/close_button_component.html.erb +0 -4
  148. data/app/components/ariadne/close_button_component.rb +0 -33
  149. data/app/components/ariadne/combobox_component.html.erb +0 -14
  150. data/app/components/ariadne/combobox_component.rb +0 -76
  151. data/app/components/ariadne/component.rb +0 -127
  152. data/app/components/ariadne/container_component/container_component.html.erb +0 -3
  153. data/app/components/ariadne/container_component.rb +0 -25
  154. data/app/components/ariadne/content.rb +0 -12
  155. data/app/components/ariadne/counter_component.rb +0 -100
  156. data/app/components/ariadne/details_component/details_component.html.erb +0 -4
  157. data/app/components/ariadne/details_component.rb +0 -81
  158. data/app/components/ariadne/dropdown/menu_component.d.ts +0 -1
  159. data/app/components/ariadne/dropdown/menu_component.html.erb +0 -20
  160. data/app/components/ariadne/dropdown/menu_component.js +0 -1
  161. data/app/components/ariadne/dropdown/menu_component.rb +0 -101
  162. data/app/components/ariadne/dropdown/menu_component.ts +0 -1
  163. data/app/components/ariadne/dropdown_component/dropdown_component.html.erb +0 -8
  164. data/app/components/ariadne/dropdown_component.rb +0 -172
  165. data/app/components/ariadne/events_controller/events_controller.d.ts +0 -4
  166. data/app/components/ariadne/events_controller/events_controller.js +0 -6
  167. data/app/components/ariadne/events_controller/events_controller.ts +0 -7
  168. data/app/components/ariadne/flash_component/flash_component.html.erb +0 -31
  169. data/app/components/ariadne/flash_component.rb +0 -128
  170. data/app/components/ariadne/flex_component/flex_component.html.erb +0 -5
  171. data/app/components/ariadne/flex_component.rb +0 -56
  172. data/app/components/ariadne/footer_component/footer_component.html.erb +0 -7
  173. data/app/components/ariadne/footer_component.rb +0 -23
  174. data/app/components/ariadne/grid_component/grid_component.html.erb +0 -26
  175. data/app/components/ariadne/grid_component.rb +0 -67
  176. data/app/components/ariadne/header_component/header_component.html.erb +0 -29
  177. data/app/components/ariadne/header_component.rb +0 -111
  178. data/app/components/ariadne/heading_component.rb +0 -49
  179. data/app/components/ariadne/heroicon_component/heroicon_component.html.erb +0 -4
  180. data/app/components/ariadne/heroicon_component.rb +0 -166
  181. data/app/components/ariadne/image_component.rb +0 -53
  182. data/app/components/ariadne/inline_flex_component/inline_flex_component.html.erb +0 -6
  183. data/app/components/ariadne/inline_flex_component.rb +0 -72
  184. data/app/components/ariadne/layout_component.html.erb +0 -21
  185. data/app/components/ariadne/layout_component.rb +0 -69
  186. data/app/components/ariadne/link_component.rb +0 -65
  187. data/app/components/ariadne/list_component/list_component.html.erb +0 -3
  188. data/app/components/ariadne/list_component.rb +0 -70
  189. data/app/components/ariadne/modal_component.html.erb +0 -11
  190. data/app/components/ariadne/modal_component.rb +0 -88
  191. data/app/components/ariadne/narrow_container_component/narrow_container_component.html.erb +0 -3
  192. data/app/components/ariadne/narrow_container_component.rb +0 -30
  193. data/app/components/ariadne/options_controller/options_controller.d.ts +0 -39
  194. data/app/components/ariadne/options_controller/options_controller.js +0 -89
  195. data/app/components/ariadne/options_controller/options_controller.ts +0 -122
  196. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +0 -42
  197. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.js +0 -237
  198. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.ts +0 -278
  199. data/app/components/ariadne/panel_bar_component/panel_bar_component.html.erb +0 -20
  200. data/app/components/ariadne/panel_bar_component.rb +0 -80
  201. data/app/components/ariadne/pill_component/pill_component.html.erb +0 -3
  202. data/app/components/ariadne/pill_component.rb +0 -44
  203. data/app/components/ariadne/popover_component.html.erb +0 -10
  204. data/app/components/ariadne/popover_component.rb +0 -81
  205. data/app/components/ariadne/progress_bar_component.html.erb +0 -5
  206. data/app/components/ariadne/progress_bar_component.rb +0 -63
  207. data/app/components/ariadne/relative_time_component.html.erb +0 -3
  208. data/app/components/ariadne/relative_time_component.rb +0 -61
  209. data/app/components/ariadne/show_more_button_component.html.erb +0 -11
  210. data/app/components/ariadne/show_more_button_component.rb +0 -47
  211. data/app/components/ariadne/slideover_component/slideover-component.d.ts +0 -9
  212. data/app/components/ariadne/slideover_component/slideover-component.js +0 -11
  213. data/app/components/ariadne/slideover_component/slideover-component.ts +0 -17
  214. data/app/components/ariadne/slideover_component/slideover_component.html.erb +0 -9
  215. data/app/components/ariadne/slideover_component.rb +0 -66
  216. data/app/components/ariadne/spinner_component.html.erb +0 -16
  217. data/app/components/ariadne/spinner_component.rb +0 -45
  218. data/app/components/ariadne/string_match_controller/string_match_controller.d.ts +0 -27
  219. data/app/components/ariadne/string_match_controller/string_match_controller.js +0 -51
  220. data/app/components/ariadne/string_match_controller/string_match_controller.ts +0 -65
  221. data/app/components/ariadne/subheader_component.html.erb +0 -11
  222. data/app/components/ariadne/subheader_component.rb +0 -65
  223. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +0 -48
  224. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.js +0 -207
  225. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.ts +0 -256
  226. data/app/components/ariadne/tab_component/tab_component.html.erb +0 -3
  227. data/app/components/ariadne/tab_component.rb +0 -98
  228. data/app/components/ariadne/tab_container_component/tab-container-component.d.ts +0 -1
  229. data/app/components/ariadne/tab_container_component/tab-container-component.js +0 -23
  230. data/app/components/ariadne/tab_container_component/tab-container-component.ts +0 -24
  231. data/app/components/ariadne/tab_container_component.erb +0 -10
  232. data/app/components/ariadne/tab_container_component.rb +0 -68
  233. data/app/components/ariadne/tab_nav_component/tab-nav-component.d.ts +0 -9
  234. data/app/components/ariadne/tab_nav_component/tab-nav-component.js +0 -33
  235. data/app/components/ariadne/tab_nav_component/tab-nav-component.ts +0 -34
  236. data/app/components/ariadne/tab_nav_component/tab_nav_component.html.erb +0 -7
  237. data/app/components/ariadne/tab_nav_component.rb +0 -72
  238. data/app/components/ariadne/table_nav_component/table_nav_component.html.erb +0 -52
  239. data/app/components/ariadne/table_nav_component.rb +0 -338
  240. data/app/components/ariadne/text.rb +0 -25
  241. data/app/components/ariadne/time_ago_component/time-ago-component.d.ts +0 -1
  242. data/app/components/ariadne/time_ago_component/time-ago-component.js +0 -1
  243. data/app/components/ariadne/time_ago_component/time-ago-component.ts +0 -1
  244. data/app/components/ariadne/time_ago_component.rb +0 -56
  245. data/app/components/ariadne/timeline_component/timeline_component.html.erb +0 -19
  246. data/app/components/ariadne/timeline_component.rb +0 -34
  247. data/app/components/ariadne/toggle_component/toggle_component.html.erb +0 -15
  248. data/app/components/ariadne/toggle_component.rb +0 -95
  249. data/app/components/ariadne/toggleable_controller/toggleable_controller.d.ts +0 -34
  250. data/app/components/ariadne/toggleable_controller/toggleable_controller.js +0 -54
  251. data/app/components/ariadne/toggleable_controller/toggleable_controller.ts +0 -77
  252. data/app/components/ariadne/tooltip_component/tooltip-component.d.ts +0 -24
  253. data/app/components/ariadne/tooltip_component/tooltip-component.js +0 -43
  254. data/app/components/ariadne/tooltip_component/tooltip-component.ts +0 -57
  255. data/app/components/ariadne/tooltip_component/tooltip_component.html.erb +0 -4
  256. data/app/components/ariadne/tooltip_component.rb +0 -108
  257. data/app/lib/ariadne/action_view_extensions/form_helper.rb +0 -30
  258. data/app/lib/ariadne/audited/dsl.rb +0 -32
  259. data/app/lib/ariadne/form_builder.rb +0 -80
  260. data/app/lib/ariadne/status/dsl.rb +0 -41
  261. data/config/importmap.rb +0 -3
  262. data/exe/tailwindcss +0 -21
  263. data/lib/rubocop/cop/ariadne/base_cop.rb +0 -26
  264. data/tailwind.config.js +0 -70
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ariadne
4
- # A component to render a subheader with optional description below it and optional action
5
- # components on the right side
6
- class SubheaderComponent < Ariadne::Component
7
- DEFAULT_TAGS = {
8
- wrapper: :div,
9
- actions: :div,
10
- header: :h2,
11
- description: :span,
12
- }
13
-
14
- DEFAULT_CLASSES = {
15
- wrapper: "ariadne-border-b-2 ariadne-border-solid ariadne-border-black ariadne-border-opacity-20",
16
- header: "",
17
- actions: "",
18
- description: "ariadne-text-black/50",
19
- }
20
-
21
- DEFAULT_ATTRIBUTES = {
22
- wrapper: {},
23
- header: {},
24
- description: {},
25
- actions: {},
26
- }
27
-
28
- renders_one :header, lambda { |tag: DEFAULT_TAGS[:header], classes: "", attributes: {}|
29
- Ariadne::HeadingComponent.new(
30
- tag: check_incoming_tag(DEFAULT_TAGS[:header], tag),
31
- classes: merge_class_names(DEFAULT_CLASSES[:header], classes),
32
- attributes: DEFAULT_ATTRIBUTES[:header].merge({ id: @header_id }).merge(attributes),
33
- )
34
- }
35
-
36
- renders_one :description, lambda { |tag: DEFAULT_TAGS[:description], classes: "", attributes: {}|
37
- Ariadne::BaseComponent.new(
38
- tag: check_incoming_tag(DEFAULT_TAGS[:description], tag),
39
- classes: merge_class_names(DEFAULT_CLASSES[:description], classes),
40
- attributes: DEFAULT_ATTRIBUTES[:description]
41
- .merge({ "aria-describedby": @header_id })
42
- .merge(attributes),
43
- )
44
- }
45
-
46
- renders_many :actions
47
-
48
- # @example Default
49
- #
50
- # <%= render(Ariadne::SubheaderComponent.new) { "Example" } %>
51
- #
52
- # @param tag [Symbol, String] The rendered tag name.
53
- # @param classes [String] <%= link_to_classes_docs %>
54
- # @param attributes [Hash] <%= link_to_attributes_docs %>
55
- def initialize(tag: DEFAULT_TAGS[:wrapper], classes: "", id: "subheader-#{SecureRandom.uuid}", attributes: {})
56
- @tag = check_incoming_tag(DEFAULT_TAGS[:wrapper], tag)
57
- @header_id = id
58
- @attributes = DEFAULT_ATTRIBUTES[:wrapper].merge(attributes)
59
- @classes = merge_class_names(
60
- DEFAULT_CLASSES[:wrapper],
61
- classes,
62
- )
63
- end
64
- end
65
- end
@@ -1,48 +0,0 @@
1
- import OutletManagerController from '../outlet_manager_controller/outlet_manager_controller';
2
- export type TStimulusDispatchEvent<TDetails> = {
3
- target?: Element | undefined;
4
- detail?: TDetails | undefined;
5
- prefix?: string | undefined;
6
- bubbles?: boolean | undefined;
7
- cancelable?: boolean | undefined;
8
- preventDefault: () => void;
9
- };
10
- export type TBooleanValueDetail = {
11
- value: boolean;
12
- };
13
- export interface TSyncAttrDetail extends TBooleanValueDetail {
14
- attr: string;
15
- }
16
- export default class SyncedBooleanAttributesController<T> extends OutletManagerController<T> {
17
- #private;
18
- static values: {
19
- syncedAttrs: ArrayConstructor;
20
- antiAttrs: ArrayConstructor;
21
- protectAttrs: BooleanConstructor;
22
- outletEvents: ArrayConstructor;
23
- };
24
- readonly syncedAttrsValue: string[];
25
- readonly hasSyncedAttrsValue: boolean;
26
- readonly antiAttrsValue: string[];
27
- readonly hasAntiAttrsValue: boolean;
28
- readonly protectAttrsValue: boolean;
29
- static removeOnFalseAttrs: {
30
- [k: string]: boolean;
31
- };
32
- syncedAttrsLookup: {
33
- [k: string]: boolean;
34
- } | null;
35
- antiAttrsLookup: {
36
- [k: string]: boolean;
37
- } | null;
38
- getValueForElement(element: Element): boolean | null;
39
- getElementsToSync(): Array<Element> | null | undefined;
40
- connect(): void;
41
- updateAttributesForElement(element: Element, value: boolean): void;
42
- getSyncedAttrsForElement(element: Element): string[] | null;
43
- getAntiAttrsForElement(element: Element): string[] | null;
44
- getParsedAttributeForElement<T>(element: Element, attribute: string): T | null;
45
- syncElementAttributes(): void;
46
- validateAttrChange(dispatchEvent: TStimulusDispatchEvent<TSyncAttrDetail>): void;
47
- doesElementHaveOnAttrs(element: Element): boolean;
48
- }
@@ -1,207 +0,0 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var _SyncedBooleanAttributesController_instances, _SyncedBooleanAttributesController_isSyncedAttr, _SyncedBooleanAttributesController_isAntiAttr, _SyncedBooleanAttributesController_isAttr, _SyncedBooleanAttributesController_setAttrs, _SyncedBooleanAttributesController_getLookupForStringArray;
7
- import OutletManagerController from '../outlet_manager_controller/outlet_manager_controller';
8
- /*
9
- This class isn't used directly by itself because it has no functionality. What it does is establishes
10
- "synced attrs" and "anti-attrs" so that other controllers can extend this one and not worry about
11
- implementing the logic themselves (and thus have duplicate logic all over our controllers)
12
-
13
- To implement this, extend your controller with "SyncedBooleanAttributesController" then spread its
14
- values into your controllers then implement:
15
-
16
- export default class MyNewController extends SyncedBooleanAttributesController {
17
- static values = {
18
- ...SyncedBooleanAttributesController.values,
19
- myString: String,
20
- }
21
- }
22
-
23
- Also, consider the functions defined here ABOVE the connection() function. Those functions will
24
- give you control over how your controller can interact with other SyncedBooleanAttributeControllers.
25
- Not every controller needs them but you should consider them (description can be found in the functions)
26
-
27
- And don't forget that when you want to change an attr on an element, you should not do it manually.
28
- Instead run:
29
- this.updateAttributesForElement(element, value)
30
- This will let you take advantage of the ecosystem created by this base controller without any additional work
31
- */
32
- class SyncedBooleanAttributesController extends OutletManagerController {
33
- constructor() {
34
- super(...arguments);
35
- _SyncedBooleanAttributesController_instances.add(this);
36
- this.syncedAttrsLookup = null;
37
- this.antiAttrsLookup = null;
38
- }
39
- getValueForElement(element) {
40
- // This function allows the base controller to access a given element's
41
- // current status so the attributes can be set or compared. For example,
42
- // you will want to make sure the attributes are added initially and are
43
- // in sync with the controller's state. To ensure this, you can use the
44
- // default connect() function or add "this.syncElementAttributes()" to your
45
- // custom connect function. It'll look through your targets and get values for
46
- // each then set the appropriate attrs and anti-attrs
47
- return null;
48
- }
49
- getElementsToSync() {
50
- // These are the elements your controller wants to keep in sync with the attrs
51
- // Sometimes these are this.element, sometimes they're specific targets.
52
- // Return them here so the base controller can automate some behaviors for you
53
- return [];
54
- }
55
- connect() {
56
- // This function will sync attrs and anti-attrs when the controller connects.
57
- // The logic is abstracted to a function so you can override this connect
58
- // function in favor of your own without having to duplicate the sync logic
59
- this.syncElementAttributes();
60
- }
61
- updateAttributesForElement(element, value) {
62
- // This is how you should update any synced or anti-synced attrs on your elements
63
- // Do not do it manually unless you are very sure of what you're doing
64
- const syncedAttrs = this.getSyncedAttrsForElement(element);
65
- if (syncedAttrs === null || syncedAttrs === void 0 ? void 0 : syncedAttrs.length) {
66
- __classPrivateFieldGet(this, _SyncedBooleanAttributesController_instances, "m", _SyncedBooleanAttributesController_setAttrs).call(this, element, syncedAttrs, value);
67
- }
68
- const antiAttrs = this.getAntiAttrsForElement(element);
69
- if (antiAttrs === null || antiAttrs === void 0 ? void 0 : antiAttrs.length) {
70
- __classPrivateFieldGet(this, _SyncedBooleanAttributesController_instances, "m", _SyncedBooleanAttributesController_setAttrs).call(this, element, antiAttrs, !value);
71
- }
72
- }
73
- getSyncedAttrsForElement(element) {
74
- const parsedAttrs = this.getParsedAttributeForElement(element, 'data-options-synced-attrs-value');
75
- if (parsedAttrs) {
76
- return parsedAttrs;
77
- }
78
- if (this.hasSyncedAttrsValue) {
79
- return this.syncedAttrsValue;
80
- }
81
- return null;
82
- }
83
- getAntiAttrsForElement(element) {
84
- const parsedAttrs = this.getParsedAttributeForElement(element, 'data-options-anti-attrs-value');
85
- if (parsedAttrs) {
86
- return parsedAttrs;
87
- }
88
- if (this.hasAntiAttrsValue) {
89
- return this.antiAttrsValue;
90
- }
91
- return null;
92
- }
93
- getParsedAttributeForElement(element, attribute) {
94
- const attr = element.getAttribute(attribute);
95
- try {
96
- if (attr === null) {
97
- throw new Error('Bad attr');
98
- }
99
- return JSON.parse(attr);
100
- }
101
- catch (err) {
102
- return null;
103
- }
104
- }
105
- syncElementAttributes() {
106
- var _a;
107
- this.syncOutlets();
108
- // Essentially just a "sync attrs and anti-attrs on mount" function
109
- const elements = this.getElementsToSync();
110
- if (elements === null || elements === void 0 ? void 0 : elements.length) {
111
- for (const index in elements) {
112
- const element = elements[index];
113
- const value = (_a = this.getValueForElement(element)) !== null && _a !== void 0 ? _a : false;
114
- this.updateAttributesForElement(element, value);
115
- }
116
- }
117
- }
118
- validateAttrChange(dispatchEvent) {
119
- // If you protect your attrs, then this function will deny other controllers you specify from making changes to them.
120
- // For example, if you want an item to disappear when it's selected, then your Options controller likely has an "aria-hidden"
121
- // synced attr. If you use another attr to filter the list and then remove that filter, normally that would unhide your selected
122
- // element. But if you have Options protect its attrs, the filter behavior won't be allowed to change it at any time and thus
123
- // the element will remain hidden
124
- const { target, detail } = dispatchEvent;
125
- if (target && detail) {
126
- const currentValue = this.getValueForElement(target);
127
- if (currentValue !== null && this.protectAttrsValue && __classPrivateFieldGet(this, _SyncedBooleanAttributesController_instances, "m", _SyncedBooleanAttributesController_isAttr).call(this, detail.attr)) {
128
- dispatchEvent.preventDefault();
129
- }
130
- }
131
- }
132
- doesElementHaveOnAttrs(element) {
133
- if (this.hasSyncedAttrsValue) {
134
- for (let i = 0; i < this.syncedAttrsValue.length; i++) {
135
- const attrName = this.syncedAttrsValue[i];
136
- if (element.getAttribute(attrName) === 'true') {
137
- return true;
138
- }
139
- }
140
- }
141
- if (this.hasAntiAttrsValue) {
142
- for (let i = 0; i < this.antiAttrsValue.length; i++) {
143
- const attrName = this.antiAttrsValue[i];
144
- const attrValue = element.getAttribute(attrName);
145
- if (attrValue === 'false' || (SyncedBooleanAttributesController.removeOnFalseAttrs[attrName] && !attrValue)) {
146
- return true;
147
- }
148
- }
149
- }
150
- return false;
151
- }
152
- }
153
- _SyncedBooleanAttributesController_instances = new WeakSet(), _SyncedBooleanAttributesController_isSyncedAttr = function _SyncedBooleanAttributesController_isSyncedAttr(attr) {
154
- var _a;
155
- // Helper function to determine if the attr is synced
156
- if (this.syncedAttrsLookup === null) {
157
- this.syncedAttrsLookup = __classPrivateFieldGet(this, _SyncedBooleanAttributesController_instances, "m", _SyncedBooleanAttributesController_getLookupForStringArray).call(this, this.syncedAttrsValue);
158
- }
159
- return (_a = this.syncedAttrsLookup[attr]) !== null && _a !== void 0 ? _a : false;
160
- }, _SyncedBooleanAttributesController_isAntiAttr = function _SyncedBooleanAttributesController_isAntiAttr(attr) {
161
- var _a;
162
- // Helper function to determine if the attr is anti-synced
163
- if (this.antiAttrsLookup === null) {
164
- this.antiAttrsLookup = __classPrivateFieldGet(this, _SyncedBooleanAttributesController_instances, "m", _SyncedBooleanAttributesController_getLookupForStringArray).call(this, this.antiAttrsValue);
165
- }
166
- return (_a = this.antiAttrsLookup[attr]) !== null && _a !== void 0 ? _a : false;
167
- }, _SyncedBooleanAttributesController_isAttr = function _SyncedBooleanAttributesController_isAttr(attr) {
168
- // Helper function to determine if an attr is known to a controller
169
- return __classPrivateFieldGet(this, _SyncedBooleanAttributesController_instances, "m", _SyncedBooleanAttributesController_isAntiAttr).call(this, attr) || __classPrivateFieldGet(this, _SyncedBooleanAttributesController_instances, "m", _SyncedBooleanAttributesController_isSyncedAttr).call(this, attr);
170
- }, _SyncedBooleanAttributesController_setAttrs = function _SyncedBooleanAttributesController_setAttrs(element, attrs, value) {
171
- // Attempts to change the attr for an element. However, it'll dispatch an event
172
- // first so other controllers get the opportunity to deny it
173
- const attrState = JSON.stringify(value);
174
- for (const index in attrs) {
175
- const attr = attrs[index];
176
- const dispatchEvent = this.dispatch('attrChange', {
177
- target: element,
178
- detail: { attr, value },
179
- });
180
- if (!dispatchEvent.defaultPrevented) {
181
- if (attrState === 'false' && SyncedBooleanAttributesController.removeOnFalseAttrs[attr]) {
182
- element.removeAttribute(attr);
183
- }
184
- else {
185
- element.setAttribute(attr, attrState);
186
- }
187
- }
188
- }
189
- }, _SyncedBooleanAttributesController_getLookupForStringArray = function _SyncedBooleanAttributesController_getLookupForStringArray(arr) {
190
- // Helper function to return an array of strings into an object for easy lookup
191
- // While the arrays contained here are small, looking up attrs will happen often
192
- // so I think it's worth the small sacrifice to memory
193
- if (!(arr === null || arr === void 0 ? void 0 : arr.length)) {
194
- return {};
195
- }
196
- return arr.reduce((acc, cur) => {
197
- acc[cur] = true;
198
- return acc;
199
- }, {});
200
- };
201
- SyncedBooleanAttributesController.values = Object.assign(Object.assign({}, OutletManagerController.values), { syncedAttrs: Array, antiAttrs: Array, protectAttrs: Boolean });
202
- // Some attributes are only false in HTML if they don't exist
203
- // If included here, the property will be deleted on "false"
204
- SyncedBooleanAttributesController.removeOnFalseAttrs = {
205
- checked: true,
206
- };
207
- export default SyncedBooleanAttributesController;
@@ -1,256 +0,0 @@
1
- import OutletManagerController from '../outlet_manager_controller/outlet_manager_controller'
2
-
3
- export type TStimulusDispatchEvent<TDetails> = {
4
- target?: Element | undefined
5
- detail?: TDetails | undefined
6
- prefix?: string | undefined
7
- bubbles?: boolean | undefined
8
- cancelable?: boolean | undefined
9
- preventDefault: () => void
10
- }
11
-
12
- export type TBooleanValueDetail = {
13
- value: boolean
14
- }
15
-
16
- export interface TSyncAttrDetail extends TBooleanValueDetail {
17
- attr: string
18
- }
19
-
20
- /*
21
- This class isn't used directly by itself because it has no functionality. What it does is establishes
22
- "synced attrs" and "anti-attrs" so that other controllers can extend this one and not worry about
23
- implementing the logic themselves (and thus have duplicate logic all over our controllers)
24
-
25
- To implement this, extend your controller with "SyncedBooleanAttributesController" then spread its
26
- values into your controllers then implement:
27
-
28
- export default class MyNewController extends SyncedBooleanAttributesController {
29
- static values = {
30
- ...SyncedBooleanAttributesController.values,
31
- myString: String,
32
- }
33
- }
34
-
35
- Also, consider the functions defined here ABOVE the connection() function. Those functions will
36
- give you control over how your controller can interact with other SyncedBooleanAttributeControllers.
37
- Not every controller needs them but you should consider them (description can be found in the functions)
38
-
39
- And don't forget that when you want to change an attr on an element, you should not do it manually.
40
- Instead run:
41
- this.updateAttributesForElement(element, value)
42
- This will let you take advantage of the ecosystem created by this base controller without any additional work
43
- */
44
-
45
- export default class SyncedBooleanAttributesController<T> extends OutletManagerController<T> {
46
- static values = {
47
- ...OutletManagerController.values,
48
- syncedAttrs: Array, // Set option target attrs to true/false in agreement with the option's selected state
49
- antiAttrs: Array, // Set option target attrs to true/false opposite of the option's selected state
50
- protectAttrs: Boolean, // If the controller should block other SyncedBooleanAttributesController from changing its defined attrs
51
- }
52
-
53
- declare readonly syncedAttrsValue: string[]
54
- declare readonly hasSyncedAttrsValue: boolean
55
- declare readonly antiAttrsValue: string[]
56
- declare readonly hasAntiAttrsValue: boolean
57
- declare readonly protectAttrsValue: boolean
58
-
59
- // Some attributes are only false in HTML if they don't exist
60
- // If included here, the property will be deleted on "false"
61
- static removeOnFalseAttrs: {[k: string]: boolean} = {
62
- checked: true,
63
- }
64
-
65
- syncedAttrsLookup: {[k: string]: boolean} | null = null
66
- antiAttrsLookup: {[k: string]: boolean} | null = null
67
-
68
- getValueForElement(element: Element): boolean | null {
69
- // This function allows the base controller to access a given element's
70
- // current status so the attributes can be set or compared. For example,
71
- // you will want to make sure the attributes are added initially and are
72
- // in sync with the controller's state. To ensure this, you can use the
73
- // default connect() function or add "this.syncElementAttributes()" to your
74
- // custom connect function. It'll look through your targets and get values for
75
- // each then set the appropriate attrs and anti-attrs
76
- return null
77
- }
78
-
79
- getElementsToSync(): Array<Element> | null | undefined {
80
- // These are the elements your controller wants to keep in sync with the attrs
81
- // Sometimes these are this.element, sometimes they're specific targets.
82
- // Return them here so the base controller can automate some behaviors for you
83
- return []
84
- }
85
-
86
- connect(): void {
87
- // This function will sync attrs and anti-attrs when the controller connects.
88
- // The logic is abstracted to a function so you can override this connect
89
- // function in favor of your own without having to duplicate the sync logic
90
- this.syncElementAttributes()
91
- }
92
-
93
- updateAttributesForElement(element: Element, value: boolean) {
94
- // This is how you should update any synced or anti-synced attrs on your elements
95
- // Do not do it manually unless you are very sure of what you're doing
96
- const syncedAttrs = this.getSyncedAttrsForElement(element)
97
- if (syncedAttrs?.length) {
98
- this.#setAttrs(element, syncedAttrs, value)
99
- }
100
-
101
- const antiAttrs = this.getAntiAttrsForElement(element)
102
- if (antiAttrs?.length) {
103
- this.#setAttrs(element, antiAttrs, !value)
104
- }
105
- }
106
-
107
- getSyncedAttrsForElement(element: Element) {
108
- const parsedAttrs = this.getParsedAttributeForElement<Array<string>>(element, 'data-options-synced-attrs-value')
109
- if (parsedAttrs) {
110
- return parsedAttrs
111
- }
112
-
113
- if (this.hasSyncedAttrsValue) {
114
- return this.syncedAttrsValue
115
- }
116
-
117
- return null
118
- }
119
-
120
- getAntiAttrsForElement(element: Element) {
121
- const parsedAttrs = this.getParsedAttributeForElement<Array<string>>(element, 'data-options-anti-attrs-value')
122
- if (parsedAttrs) {
123
- return parsedAttrs
124
- }
125
-
126
- if (this.hasAntiAttrsValue) {
127
- return this.antiAttrsValue
128
- }
129
-
130
- return null
131
- }
132
-
133
- getParsedAttributeForElement<T>(element: Element, attribute: string) {
134
- const attr = element.getAttribute(attribute)
135
- try {
136
- if (attr === null) {
137
- throw new Error('Bad attr')
138
- }
139
-
140
- return JSON.parse(attr) as T
141
- } catch (err) {
142
- return null
143
- }
144
- }
145
-
146
- syncElementAttributes() {
147
- this.syncOutlets()
148
- // Essentially just a "sync attrs and anti-attrs on mount" function
149
- const elements = this.getElementsToSync()
150
-
151
- if (elements?.length) {
152
- for (const index in elements) {
153
- const element = elements[index]
154
- const value = this.getValueForElement(element) ?? false
155
- this.updateAttributesForElement(element, value)
156
- }
157
- }
158
- }
159
-
160
- validateAttrChange(dispatchEvent: TStimulusDispatchEvent<TSyncAttrDetail>) {
161
- // If you protect your attrs, then this function will deny other controllers you specify from making changes to them.
162
- // For example, if you want an item to disappear when it's selected, then your Options controller likely has an "aria-hidden"
163
- // synced attr. If you use another attr to filter the list and then remove that filter, normally that would unhide your selected
164
- // element. But if you have Options protect its attrs, the filter behavior won't be allowed to change it at any time and thus
165
- // the element will remain hidden
166
- const {target, detail} = dispatchEvent
167
- if (target && detail) {
168
- const currentValue = this.getValueForElement(target)
169
- if (currentValue !== null && this.protectAttrsValue && this.#isAttr(detail.attr)) {
170
- dispatchEvent.preventDefault()
171
- }
172
- }
173
- }
174
-
175
- doesElementHaveOnAttrs(element: Element) {
176
- if (this.hasSyncedAttrsValue) {
177
- for (let i = 0; i < this.syncedAttrsValue.length; i++) {
178
- const attrName = this.syncedAttrsValue[i]
179
- if (element.getAttribute(attrName) === 'true') {
180
- return true
181
- }
182
- }
183
- }
184
-
185
- if (this.hasAntiAttrsValue) {
186
- for (let i = 0; i < this.antiAttrsValue.length; i++) {
187
- const attrName = this.antiAttrsValue[i]
188
- const attrValue = element.getAttribute(attrName)
189
- if (attrValue === 'false' || (SyncedBooleanAttributesController.removeOnFalseAttrs[attrName] && !attrValue)) {
190
- return true
191
- }
192
- }
193
- }
194
-
195
- return false
196
- }
197
-
198
- #isSyncedAttr(attr: string) {
199
- // Helper function to determine if the attr is synced
200
- if (this.syncedAttrsLookup === null) {
201
- this.syncedAttrsLookup = this.#getLookupForStringArray(this.syncedAttrsValue)
202
- }
203
-
204
- return this.syncedAttrsLookup[attr] ?? false
205
- }
206
-
207
- #isAntiAttr(attr: string) {
208
- // Helper function to determine if the attr is anti-synced
209
- if (this.antiAttrsLookup === null) {
210
- this.antiAttrsLookup = this.#getLookupForStringArray(this.antiAttrsValue)
211
- }
212
-
213
- return this.antiAttrsLookup[attr] ?? false
214
- }
215
-
216
- #isAttr(attr: string) {
217
- // Helper function to determine if an attr is known to a controller
218
- return this.#isAntiAttr(attr) || this.#isSyncedAttr(attr)
219
- }
220
-
221
- #setAttrs(element: Element, attrs: string[], value: boolean) {
222
- // Attempts to change the attr for an element. However, it'll dispatch an event
223
- // first so other controllers get the opportunity to deny it
224
- const attrState = JSON.stringify(value)
225
- for (const index in attrs) {
226
- const attr = attrs[index]
227
-
228
- const dispatchEvent = this.dispatch('attrChange', {
229
- target: element,
230
- detail: {attr, value},
231
- } as TStimulusDispatchEvent<TSyncAttrDetail>)
232
-
233
- if (!dispatchEvent.defaultPrevented) {
234
- if (attrState === 'false' && SyncedBooleanAttributesController.removeOnFalseAttrs[attr]) {
235
- element.removeAttribute(attr)
236
- } else {
237
- element.setAttribute(attr, attrState)
238
- }
239
- }
240
- }
241
- }
242
-
243
- #getLookupForStringArray(arr?: Array<string>) {
244
- // Helper function to return an array of strings into an object for easy lookup
245
- // While the arrays contained here are small, looking up attrs will happen often
246
- // so I think it's worth the small sacrifice to memory
247
- if (!arr?.length) {
248
- return {}
249
- }
250
-
251
- return arr.reduce((acc, cur) => {
252
- acc[cur] = true
253
- return acc
254
- }, {} as {[k: string]: boolean})
255
- }
256
- }
@@ -1,3 +0,0 @@
1
- <%= render(Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes)) do %>
2
- <%= text || content %>
3
- <% end %>
@@ -1,98 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ariadne
4
- # This component is part of navigation components such as `Ariadne::TabContainerComponent`.
5
- # and `Ariadne::TabNavComponent` and should not be used by itself.
6
- #
7
- # @accessibility
8
- # `TabComponent` renders the selected anchor tab with `aria-current="page"` by default.
9
- # When the selected tab does not correspond to the current page, such as in a nested inner tab, make sure to use aria-current="true"
10
- class TabComponent < Ariadne::Component
11
- DEFAULT_ARIA_CURRENT_FOR_ANCHOR = :page
12
- ARIA_CURRENT_OPTIONS_FOR_ANCHOR = [true, DEFAULT_ARIA_CURRENT_FOR_ANCHOR].freeze
13
-
14
- # Panel controlled by the Tab. This will not render anything in the tab itself.
15
- # It will provide a accessor for the Tab's parent to call and render the panel
16
- # content in the appropriate place.
17
- #
18
- # @param classes [String] <%= link_to_classes_docs %>
19
- # @param attributes [Hash] <%= link_to_attributes_docs %>
20
- renders_one :panel, lambda { |classes: "", attributes: {}|
21
- attributes[:id] = @panel_id
22
- tag = :div
23
- attributes[:role] ||= :tabpanel
24
- attributes[:hidden] = true unless @selected
25
-
26
- label_present = aria("label", attributes) || aria("labelledby", attributes)
27
- unless label_present
28
- if @id.present?
29
- attributes[:"aria-labelledby"] = @id
30
- else
31
- raise ArgumentError, "Panels must be labelled. Either set a unique `id` on the tab, or set an `aria-label` directly on the panel"
32
- end
33
- end
34
-
35
- Ariadne::BaseComponent.new(tag: tag, classes: classes, attributes: attributes)
36
- }
37
-
38
- # The tab's text.
39
- #
40
- # @param kwargs [Hash] The same arguments as <%= link_to_component(Ariadne::Text) %>.
41
- renders_one :text, Ariadne::Text
42
- # TODO: test what hapenns with really long inbox names
43
-
44
- attr_reader :selected, :id, :classes, :attributes
45
-
46
- DEFAULT_CLASSES = "ariadne-border-transparent ariadne-text-gray-500 hover:ariadne-text-gray-700 hover:ariadne-border-gray-300 ariadne-whitespace-nowrap ariadne-py-4 ariadne-px-1 ariadne-border-b-2 ariadne-font-medium ariadne-text-sm"
47
-
48
- # @example Default
49
- #
50
- # <%= render(Ariadne::TabComponent.new(id: "pub-comment")) do |tab| %>
51
- # <% tab.text { "Public comment" } %>
52
- # <% tab.panel { "Public comment panel" } %>
53
- # <% end %>
54
- # @param id [String] The unique ID of the tab.
55
- # @param selected [Boolean] Whether the tab is selected or not.
56
- # @param with_panel [Boolean] Whether the Tab has an associated panel.
57
- # @param href [String] The link to navigate to when the tab is clicked.
58
- # @param classes [String] <%= link_to_classes_docs %>
59
- # @param attributes [Hash] <%= link_to_attributes_docs %>
60
- def initialize(id: nil, selected: false, with_panel: false, href: nil, classes: "", attributes: {})
61
- @id = id
62
-
63
- @href = href
64
- @selected = selected
65
-
66
- @classes = merge_class_names(
67
- DEFAULT_CLASSES,
68
- classes,
69
- )
70
-
71
- @attributes = attributes
72
- @attributes[:id] ||= @id
73
-
74
- if with_panel # TODO: test
75
- if @id.blank?
76
- raise ArgumentError, "Tabs with panels must have a unique `id`"
77
- end
78
-
79
- @tag = :button
80
- @attributes[:type] = :button
81
- @attributes[:role] = :tab
82
- @panel_id = "panel-#{@id}"
83
- @attributes[:"aria-controls"] = @panel_id
84
- else
85
- @tag = :a
86
- end
87
-
88
- return unless @selected
89
-
90
- if @tag == :a
91
- aria_current = aria("current", attributes) || DEFAULT_ARIA_CURRENT_FOR_ANCHOR
92
- @attributes[:"aria-current"] = fetch_or_raise(ARIA_CURRENT_OPTIONS_FOR_ANCHOR, aria_current)
93
- else
94
- @attributes[:"aria-selected"] = true
95
- end
96
- end
97
- end
98
- end
@@ -1 +0,0 @@
1
- import '@github/tab-container-element';