ariadne_view_components 0.0.33-aarch64-linux → 0.0.35-aarch64-linux

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -5
  3. data/README.md +2 -2
  4. data/app/components/ariadne/avatar_component.rb +1 -1
  5. data/app/components/ariadne/avatar_stack_component.rb +7 -7
  6. data/app/components/ariadne/base_button.rb +2 -2
  7. data/app/components/ariadne/base_component.rb +2 -2
  8. data/app/components/ariadne/blankslate_component.rb +9 -9
  9. data/app/components/ariadne/body_component.rb +1 -1
  10. data/app/components/ariadne/button_component.rb +8 -6
  11. data/app/components/ariadne/clipboard_copy_component.rb +1 -1
  12. data/app/components/ariadne/comment_component/comment_component.html.erb +6 -6
  13. data/app/components/ariadne/comment_component.rb +5 -5
  14. data/app/components/ariadne/component.rb +0 -1
  15. data/app/components/ariadne/container_component.rb +1 -1
  16. data/app/components/ariadne/counter_component.rb +1 -1
  17. data/app/components/ariadne/details_component.rb +10 -9
  18. data/app/components/ariadne/dropdown/menu_component.rb +3 -3
  19. data/app/components/ariadne/dropdown_component/dropdown_component.html.erb +2 -2
  20. data/app/components/ariadne/dropdown_component.rb +52 -52
  21. data/app/components/ariadne/flash_component.rb +5 -5
  22. data/app/components/ariadne/flex_component/flex_component.html.erb +5 -0
  23. data/app/components/ariadne/flex_component.rb +10 -3
  24. data/app/components/ariadne/footer_component.rb +2 -2
  25. data/app/components/ariadne/grid_component.rb +4 -8
  26. data/app/components/ariadne/header_component.rb +7 -7
  27. data/app/components/ariadne/heading_component.rb +1 -1
  28. data/app/components/ariadne/heroicon_component.rb +2 -2
  29. data/app/components/ariadne/inline_flex_component.rb +7 -7
  30. data/app/components/ariadne/link_component.rb +3 -3
  31. data/app/components/ariadne/list_component.rb +10 -4
  32. data/app/components/ariadne/narrow_container_component.rb +1 -1
  33. data/app/components/ariadne/panel_bar_component.rb +3 -3
  34. data/app/components/ariadne/pill_component.rb +1 -1
  35. data/app/components/ariadne/rich_text_area_component/rich-text-area-component.ts +4 -4
  36. data/app/components/ariadne/rich_text_area_component.rb +1 -1
  37. data/app/components/ariadne/slideover_component.rb +3 -3
  38. data/app/components/ariadne/tab_component.rb +1 -1
  39. data/app/components/ariadne/tab_container_component/tab-container-component.ts +1 -1
  40. data/app/components/ariadne/tab_container_component.rb +7 -7
  41. data/app/components/ariadne/tab_nav_component.rb +5 -5
  42. data/app/components/ariadne/table_nav_component.rb +42 -42
  43. data/app/components/ariadne/time_ago_component.rb +1 -1
  44. data/app/components/ariadne/timeline_component.rb +1 -1
  45. data/app/components/ariadne/tooltip_component/tooltip-component.ts +5 -5
  46. data/app/components/ariadne/tooltip_component.rb +1 -1
  47. data/app/lib/ariadne/action_view_extensions/form_helper.rb +1 -1
  48. data/app/lib/ariadne/class_name_helper.rb +1 -1
  49. data/app/lib/ariadne/form_builder.rb +15 -12
  50. data/lib/ariadne/view_components/linters/argument_mappers/conversion_error.rb +10 -0
  51. data/lib/ariadne/view_components/linters/autocorrectable.rb +32 -0
  52. data/lib/ariadne/view_components/linters/base_linter.rb +202 -0
  53. data/lib/ariadne/view_components/linters/tag_tree_helpers.rb +76 -0
  54. data/lib/ariadne/view_components/version.rb +2 -1
  55. data/lib/tasks/build.rake +6 -0
  56. data/lib/tasks/coverage.rake +4 -1
  57. data/lib/tasks/docs.rake +5 -1
  58. data/lib/tasks/test.rake +19 -0
  59. data/static/classes.yml +3 -1
  60. metadata +8 -16
  61. data/app/assets/javascripts/ariadne-form-with.d.ts +0 -20
  62. data/app/assets/javascripts/ariadne-form.d.ts +0 -22
  63. data/app/assets/javascripts/ariadne.d.ts +0 -2
  64. data/app/assets/javascripts/ariadne_view_components.js +0 -8
  65. data/app/assets/javascripts/ariadne_view_components.js.map +0 -1
  66. data/app/assets/javascripts/clipboard-copy-component.d.ts +0 -4
  67. data/app/assets/javascripts/comment-component.d.ts +0 -12
  68. data/app/assets/javascripts/rich-text-area-component.d.ts +0 -6
  69. data/app/assets/javascripts/slideover-component.d.ts +0 -9
  70. data/app/assets/javascripts/tab-container-component.d.ts +0 -1
  71. data/app/assets/javascripts/tab-nav-component.d.ts +0 -9
  72. data/app/assets/javascripts/time-ago-component.d.ts +0 -1
  73. data/app/assets/javascripts/time_ago_component.d.ts +0 -1
  74. data/app/assets/javascripts/tooltip-component.d.ts +0 -24
@@ -19,7 +19,7 @@ module Ariadne
19
19
  # @param classes [String] <%= link_to_classes_docs %>
20
20
  # @param attributes [Hash] <%= link_to_attributes_docs %>
21
21
  renders_many :tabs, lambda { |id: "", selected: false, classes: "", attributes: {}|
22
- actual_classes = class_names(selected ? DEFAULT_SELECTED_CLASSES : DEFAULT_UNSELECTED_CLASSES, classes)
22
+ actual_classes = merge_class_names(selected ? DEFAULT_SELECTED_CLASSES : DEFAULT_UNSELECTED_CLASSES, classes)
23
23
 
24
24
  Ariadne::TabComponent.new(
25
25
  id: id,
@@ -35,12 +35,12 @@ module Ariadne
35
35
  #
36
36
  # <%= render(Ariadne::TabContainerComponent.new(sr_label: "Comments")) do |tab_container| %>
37
37
  # <%= render(Ariadne::TabComponent.new(id: "pub-comment")) do |tab| %>
38
- # <% tab.text { "Tab 1" } %>
39
- # <% tab.panel { "Panel 1" } %>
38
+ # <% tab.with_text { "Tab 1" } %>
39
+ # <% tab.with_panel { "Panel 1" } %>
40
40
  # <% end %>
41
41
  # <%= render(Ariadne::TabComponent.new(id: "pub-comment")) do |tab| %>
42
- # <% tab.text { "Tab 2" } %>
43
- # <% tab.panel { "Panel 2" } %>
42
+ # <% tab.with_text { "Tab 2" } %>
43
+ # <% tab.with_panel { "Panel 2" } %>
44
44
  # <% end %>
45
45
  # <% end %>
46
46
  #
@@ -51,7 +51,7 @@ module Ariadne
51
51
  # @param attributes [Hash] <%= link_to_attributes_docs %>
52
52
  def initialize(sr_label:, classes: "", attributes: {})
53
53
  @tag = DEFAULT_TAG
54
- @classes = class_names(
54
+ @classes = merge_class_names(
55
55
  DEFAULT_CLASSES,
56
56
  classes,
57
57
  )
@@ -62,7 +62,7 @@ module Ariadne
62
62
  end
63
63
 
64
64
  def render?
65
- tabs.present?
65
+ tabs?
66
66
  end
67
67
  end
68
68
  end
@@ -34,7 +34,7 @@ module Ariadne
34
34
  attributes[:"data-tab-nav-component-target"] = "tab"
35
35
  attributes[:"data-action"] = "click->tab-nav-component#toggle"
36
36
 
37
- actual_classes = class_names(selected ? SELECTED_CLASSES : UNSELECTED_CLASSES, classes)
37
+ actual_classes = merge_class_names(selected ? SELECTED_CLASSES : UNSELECTED_CLASSES, classes)
38
38
  Ariadne::TabComponent.new(
39
39
  selected: selected,
40
40
 
@@ -48,9 +48,9 @@ module Ariadne
48
48
  # `<nav>` is a landmark and should be reserved for main navigation links. See <%= link_to_accessibility %>.
49
49
  # @code
50
50
  # <%= render(Ariadne::TabNavComponent.new(label: "Nav")) do |c| %>
51
- # <% c.tab(selected: true, href: "#") { "Tab 1" } %>
52
- # <% c.tab(href: "#") { "Tab 2" } %>
53
- # <% c.tab(href: "#") { "Tab 3" } %>
51
+ # <% c.with_tab(selected: true, href: "#") { "Tab 1" } %>
52
+ # <% c.with_tab(href: "#") { "Tab 2" } %>
53
+ # <% c.with_tab(href: "#") { "Tab 3" } %>
54
54
  # <% end %>
55
55
  #
56
56
  # @param label [String] Sets an `aria-label` that helps assistive technology users understand the purpose of the links, and distinguish it from similar elements.
@@ -59,7 +59,7 @@ module Ariadne
59
59
  # @param attributes [Hash] <%= link_to_attributes_docs %>
60
60
  def initialize(label:, tag: DEFAULT_TAG, classes: "", attributes: {})
61
61
  @tag = check_incoming_tag(DEFAULT_TAG, tag)
62
- @classes = class_names(
62
+ @classes = merge_class_names(
63
63
  DEFAULT_CLASSES,
64
64
  classes,
65
65
  )
@@ -16,48 +16,48 @@ module Ariadne
16
16
  # @example Default
17
17
  #
18
18
  # <%= render(Ariadne::TableNavComponent.new) do |table| %>
19
- # <%= table.header_row do |header_row| %>
20
- # <% header_row.selection_cell do %>
19
+ # <%= table.with_header_row do |header_row| %>
20
+ # <% header_row.with_selection_cell do %>
21
21
  # Status
22
22
  # <% end %>
23
- # <% header_row.main_cell do %>
23
+ # <% header_row.with_main_cell do %>
24
24
  # State
25
25
  # <% end %>
26
- # <% header_row.action_cell do %>
26
+ # <% header_row.with_action_cell do %>
27
27
  # Labels
28
28
  # <% end %>
29
29
  # <% end %>
30
- # <%= table.row do |row| %>
31
- # <% row.selection_cell do %>
32
- # G
30
+ # <%= table.with_row do |row| %>
31
+ # <% row.with_selection_cell do %>
32
+ # "G"
33
33
  # <% end %>
34
- # <% row.main_cell do %>
34
+ # <% row.with_main_cell do %>
35
35
  # "California"
36
36
  # <% end %>
37
- # <% row.metadata_cell do %>
38
- # Labels
37
+ # <% row.with_metadata_cell do %>
38
+ # "Labels"
39
39
  # <% end %>
40
40
  # <% end %>
41
- # <%= table.row do |row| %>
42
- # <% row.selection_cell do %>
43
- # V
41
+ # <%= table.with_row do |row| %>
42
+ # <% row.with_selection_cell do %>
43
+ # "V"
44
44
  # <% end %>
45
- # <% row.main_cell do %>
45
+ # <% row.with_main_cell do %>
46
46
  # "New York"
47
47
  # <% end %>
48
- # <% row.metadata_cell do %>
49
- # Labels
48
+ # <% row.with_metadata_cell do %>
49
+ # "Labels"
50
50
  # <% end %>
51
51
  # <% end %>
52
- # <%= table.row do |row| %>
53
- # <% row.cell do %>
54
- # D
52
+ # <%= table.with_row do |row| %>
53
+ # <% row.with_cell do %>
54
+ # "D"
55
55
  # <% end %>
56
- # <% row.selection_cell do %>
56
+ # <% row.with_selection_cell do %>
57
57
  # "Texas"
58
58
  # <% end %>
59
- # <% row.metadata_cell do %>
60
- # Labels
59
+ # <% row.with_metadata_cell do %>
60
+ # "Labels"
61
61
  # <% end %>
62
62
  # <% end %>
63
63
  # <% end %>
@@ -66,7 +66,7 @@ module Ariadne
66
66
  # @param attributes [Hash] <%= link_to_attributes_docs %>
67
67
  def initialize(classes: "", attributes: {})
68
68
  @tag = DEFAULT_TAG
69
- @classes = class_names(
69
+ @classes = merge_class_names(
70
70
  DEFAULT_CLASSES,
71
71
  classes,
72
72
  )
@@ -91,7 +91,7 @@ module Ariadne
91
91
 
92
92
  BASE_SELECTION_CLASSES = ""
93
93
  renders_one :selection_cell, lambda { |classes: "", attributes: {}|
94
- actual_classes = class_names(BASE_SELECTION_CLASSES, classes)
94
+ actual_classes = merge_class_names(BASE_SELECTION_CLASSES, classes)
95
95
  if header?
96
96
  Ariadne::TableNavComponent::BaseCellItem::HeaderCellItem.new(classes: actual_classes, attributes: attributes)
97
97
  else
@@ -101,7 +101,7 @@ module Ariadne
101
101
 
102
102
  BASE_MAIN_CLASSES = "ariadne-pr-5"
103
103
  renders_one :main_cell, lambda { |classes: "", attributes: {}|
104
- actual_classes = class_names(BASE_MAIN_CLASSES, classes)
104
+ actual_classes = merge_class_names(BASE_MAIN_CLASSES, classes)
105
105
  if header?
106
106
  Ariadne::TableNavComponent::BaseCellItem::HeaderCellItem.new(classes: actual_classes, attributes: attributes)
107
107
  else
@@ -113,7 +113,7 @@ module Ariadne
113
113
 
114
114
  def initialize(classes: "", attributes: {})
115
115
  @tag = DEFAULT_TAG
116
- @classes = class_names(BASE_ROW_CLASSES, classes)
116
+ @classes = merge_class_names(BASE_ROW_CLASSES, classes)
117
117
 
118
118
  @attributes = attributes
119
119
  end
@@ -136,7 +136,7 @@ module Ariadne
136
136
  DEFAULT_ROW_CLASSES = "ariadne-bg-white"
137
137
  DEFAULT_METADATA_CLASSES = ""
138
138
  renders_many :metadata_cells, lambda { |classes: "", attributes: {}|
139
- actual_classes = class_names(DEFAULT_METADATA_CLASSES, classes)
139
+ actual_classes = merge_class_names(DEFAULT_METADATA_CLASSES, classes)
140
140
  Ariadne::TableNavComponent::BaseCellItem::CellItem.new(classes: actual_classes, attributes: attributes)
141
141
  }
142
142
 
@@ -145,7 +145,7 @@ module Ariadne
145
145
  def initialize(classes: "", attributes: {})
146
146
  @header = false
147
147
 
148
- actual_classes = class_names(DEFAULT_ROW_CLASSES, classes)
148
+ actual_classes = merge_class_names(DEFAULT_ROW_CLASSES, classes)
149
149
 
150
150
  super(classes: actual_classes, attributes: attributes)
151
151
  end
@@ -163,7 +163,7 @@ module Ariadne
163
163
  def initialize(classes: "", attributes: {})
164
164
  @header = true
165
165
 
166
- actual_classes = class_names(
166
+ actual_classes = merge_class_names(
167
167
  DEFAULT_HEADER_ROW_CLASSES,
168
168
  classes,
169
169
  )
@@ -181,7 +181,7 @@ module Ariadne
181
181
  attr_writer :first, :last
182
182
 
183
183
  def initialize(classes: "", attributes: {})
184
- @classes = class_names(
184
+ @classes = merge_class_names(
185
185
  DEFAULT_CELL_CLASSES,
186
186
  classes,
187
187
  )
@@ -212,7 +212,7 @@ module Ariadne
212
212
  # TODO: add one_of check for width
213
213
  def initialize(classes: "", attributes: {})
214
214
  @tag = DEFAULT_TAG
215
- actual_classes = class_names(DEFAULT_HEADER_CELL_CLASSES, classes)
215
+ actual_classes = merge_class_names(DEFAULT_HEADER_CELL_CLASSES, classes)
216
216
  attributes["scope"] = "col"
217
217
  super(classes: actual_classes, attributes: attributes)
218
218
  end
@@ -228,7 +228,7 @@ module Ariadne
228
228
  # TODO: add one_of check for width
229
229
  def initialize(classes: "", attributes: {})
230
230
  @tag = DEFAULT_TAG
231
- actual_classes = class_names(DEFAULT_CELL_CLASSES, classes)
231
+ actual_classes = merge_class_names(DEFAULT_CELL_CLASSES, classes)
232
232
  super(classes: actual_classes, attributes: attributes)
233
233
  end
234
234
  end
@@ -241,7 +241,7 @@ module Ariadne
241
241
 
242
242
  DEFAULT_RESULT_CLASSES = "ariadne-text-sm ariadne-text-gray-700"
243
243
  renders_one :records_info, lambda { |classes: "", attributes: {}|
244
- actual_classes = class_names(DEFAULT_RESULT_CLASSES, classes)
244
+ actual_classes = merge_class_names(DEFAULT_RESULT_CLASSES, classes)
245
245
  Ariadne::BaseComponent.new(tag: :p, classes: actual_classes, attributes: attributes)
246
246
  }
247
247
 
@@ -250,7 +250,7 @@ module Ariadne
250
250
  attr_reader :classes, :attributes
251
251
 
252
252
  def initialize(classes: "", attributes: {})
253
- @classes = class_names(
253
+ @classes = merge_class_names(
254
254
  DEFAULT_FOOTER_CLASSES,
255
255
  classes,
256
256
  )
@@ -271,13 +271,13 @@ module Ariadne
271
271
  DEFAULT_PREV_PAGE_CLASSES = "ariadne-relative ariadne-inline-flex ariadne-items-center ariadne-rounded-l-md ariadne-border ariadne-border-gray-300 ariadne-bg-white ariadne-px-2 ariadne-py-2 ariadne-text-sm ariadne-font-medium ariadne-text-gray-500 hover:ariadne-bg-gray-50 focus:ariadne-z-20"
272
272
  renders_one :prev_page, lambda { |disabled: false, href:, classes: "", attributes: {}|
273
273
  if disabled
274
- actual_classes = class_names(DEFAULT_PREV_PAGE_CLASSES, "ariadne-bg-gray-50", classes)
274
+ actual_classes = merge_class_names(DEFAULT_PREV_PAGE_CLASSES, "ariadne-bg-gray-50", classes)
275
275
 
276
276
  render(Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes)) do
277
277
  render(Ariadne::HeroiconComponent.new(icon: "chevron-left", size: :sm, variant: :mini, text_attributes: { "aria-hidden": true }, text_classes: "ariadne-sr-only"))
278
278
  end
279
279
  else
280
- actual_classes = class_names(DEFAULT_PREV_PAGE_CLASSES, "hover:ariadne-bg-gray-50", classes)
280
+ actual_classes = merge_class_names(DEFAULT_PREV_PAGE_CLASSES, "hover:ariadne-bg-gray-50", classes)
281
281
  attributes[:"aria-label"] = "previous"
282
282
 
283
283
  render(Ariadne::LinkComponent.new(href: href, classes: actual_classes, attributes: attributes)) do
@@ -292,13 +292,13 @@ module Ariadne
292
292
  renders_many :items, lambda { |link:, classes: "", attributes: {}|
293
293
  page, href = link
294
294
  if page.is_a?(Integer)
295
- actual_classes = class_names(DEFAULT_PAGE_CLASSES, classes)
295
+ actual_classes = merge_class_names(DEFAULT_PAGE_CLASSES, classes)
296
296
  render(Ariadne::LinkComponent.new(href: href, classes: actual_classes, attributes: attributes)) { page.to_s }
297
297
  elsif page.is_a?(String)
298
- actual_classes = class_names(DEFAULT_CURRENT_PAGE_CLASSES, classes)
298
+ actual_classes = merge_class_names(DEFAULT_CURRENT_PAGE_CLASSES, classes)
299
299
  render(Ariadne::LinkComponent.new(href: href, classes: actual_classes, attributes: attributes)) { page.to_s }
300
300
  elsif page == :gap
301
- actual_classes = class_names(DEFAULT_GAP_CLASSES, classes)
301
+ actual_classes = merge_class_names(DEFAULT_GAP_CLASSES, classes)
302
302
  render(Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes)) { h(href.to_s) }
303
303
  end
304
304
  }
@@ -306,13 +306,13 @@ module Ariadne
306
306
  DEFAULT_NEXT_PAGE_CLASSES = "ariadne-relative ariadne-inline-flex ariadne-items-center ariadne-rounded-r-md ariadne-border ariadne-border-gray-300 ariadne-bg-white ariadne-px-2 ariadne-py-2 ariadne-text-sm ariadne-font-medium ariadne-text-gray-500 hover:ariadne-bg-gray-50 focus:ariadne-z-20"
307
307
  renders_one :next_page, lambda { |disabled: false, href:, classes: "", attributes: {}|
308
308
  if disabled
309
- actual_classes = class_names(DEFAULT_NEXT_PAGE_CLASSES, "ariadne-bg-gray-50", classes)
309
+ actual_classes = merge_class_names(DEFAULT_NEXT_PAGE_CLASSES, "ariadne-bg-gray-50", classes)
310
310
 
311
311
  render(Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes)) do
312
312
  render(Ariadne::HeroiconComponent.new(icon: "chevron-right", size: :sm, variant: :mini, text_attributes: { "aria-hidden": true }, text_classes: "ariadne-sr-only"))
313
313
  end
314
314
  else
315
- actual_classes = class_names(DEFAULT_NEXT_PAGE_CLASSES, "hover:ariadne-bg-gray-50", classes)
315
+ actual_classes = merge_class_names(DEFAULT_NEXT_PAGE_CLASSES, "hover:ariadne-bg-gray-50", classes)
316
316
  attributes[:"aria-label"] = "next"
317
317
 
318
318
  render(Ariadne::LinkComponent.new(href: href, classes: actual_classes, attributes: attributes)) do
@@ -325,7 +325,7 @@ module Ariadne
325
325
 
326
326
  DEFAULT_PAGINATOR_CLASSES = "ariadne-flex ariadne-items-center ariadne-justify-between ariadne-m-10"
327
327
  def initialize(classes: "", attributes: {})
328
- @classes = class_names(
328
+ @classes = merge_class_names(
329
329
  DEFAULT_PAGINATOR_CLASSES,
330
330
  classes,
331
331
  )
@@ -19,7 +19,7 @@ module Ariadne
19
19
  # @param attributes [Hash] <%= link_to_attributes_docs %>
20
20
  def initialize(tag: DEFAULT_TAG, time:, micro: false, classes: "", attributes: {})
21
21
  @tag = check_incoming_tag(DEFAULT_TAG, tag)
22
- @classes = class_names(
22
+ @classes = merge_class_names(
23
23
  DEFAULT_CLASSES,
24
24
  classes,
25
25
  )
@@ -23,7 +23,7 @@ module Ariadne
23
23
  # @param attributes [Hash] <%= link_to_attributes_docs %>
24
24
  def initialize(tag: DEFAULT_TAG, classes: "", attributes: {})
25
25
  @tag = check_incoming_tag(DEFAULT_TAG, tag)
26
- @classes = class_names(
26
+ @classes = merge_class_names(
27
27
  DEFAULT_CLASSES,
28
28
  classes,
29
29
  )
@@ -9,7 +9,7 @@ export default class TooltipComponent extends Controller {
9
9
 
10
10
  static values = {
11
11
  placement: {type: String, default: 'top'},
12
- offset: {type: Array, default: [0, 8]}
12
+ offset: {type: Array, default: [0, 8]},
13
13
  }
14
14
  declare readonly placementValue: Placement
15
15
  declare readonly offsetValue: Array<number>
@@ -24,10 +24,10 @@ export default class TooltipComponent extends Controller {
24
24
  {
25
25
  name: 'offset',
26
26
  options: {
27
- offset: this.offsetValue
28
- }
29
- }
30
- ]
27
+ offset: this.offsetValue,
28
+ },
29
+ },
30
+ ],
31
31
  })
32
32
  }
33
33
 
@@ -95,7 +95,7 @@ module Ariadne
95
95
  @tag = check_incoming_tag(DEFAULT_TAG, tag)
96
96
 
97
97
  @text = text
98
- @classes = class_names(DEFAULT_CLASSES, classes)
98
+ @classes = merge_class_names(DEFAULT_CLASSES, classes)
99
99
 
100
100
  @attributes = attributes
101
101
  @attributes[:for] = for_id
@@ -8,7 +8,7 @@ module Ariadne
8
8
 
9
9
  DEFAULT_FORM_CLASSES = "ariadne-space-y-8 sm:ariadne-space-y-5"
10
10
  def ariadne_form_with(model: nil, scope: nil, url: nil, format: nil, classes: "", attributes: {}, **options, &block)
11
- options[:class] = class_names(DEFAULT_FORM_CLASSES, options[:class])
11
+ options[:class] = merge_class_names(DEFAULT_FORM_CLASSES, options[:class])
12
12
  options[:builder] ||= Ariadne::FormBuilder
13
13
  options[:html] = attributes
14
14
 
@@ -4,7 +4,7 @@
4
4
  module Ariadne
5
5
  # :nodoc:
6
6
  module ClassNameHelper
7
- def class_names(*args)
7
+ def merge_class_names(*args)
8
8
  [].tap do |classes|
9
9
  args.each do |class_name|
10
10
  next if class_name.blank?
@@ -2,69 +2,72 @@
2
2
 
3
3
  module Ariadne
4
4
  # :nodoc:
5
+ # Many of the form methods simply call out to the corresponding ActionView::Helpers::FormBuilder methods,
6
+ # documented at https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html, with
7
+ # default Tailwind classes applied.
5
8
  class FormBuilder < ActionView::Helpers::FormBuilder
6
9
  include ClassNameHelper
7
10
 
8
11
  DEFAULT_SECTION_CLASSES = "ariadne-space-y-6 ariadne-px-4"
9
12
  def section(classes: "", attributes: {}, &block)
10
- actual_classes = class_names(DEFAULT_SECTION_CLASSES, classes)
13
+ actual_classes = merge_class_names(DEFAULT_SECTION_CLASSES, classes)
11
14
  options = { class: actual_classes, **attributes }
12
15
  @template.content_tag(:div, **options, &block)
13
16
  end
14
17
 
15
18
  DEFAULT_SECTION_HEADING_CLASSES = "ariadne-text-lg ariadne-leading-6 ariadne-py-4 ariadne-font-medium ariadne-text-gray-900"
16
19
  def heading(tag: :h3, classes: "", attributes: {}, &block)
17
- actual_classes = class_names(DEFAULT_SECTION_HEADING_CLASSES, classes)
20
+ actual_classes = merge_class_names(DEFAULT_SECTION_HEADING_CLASSES, classes)
18
21
  options = { class: actual_classes, **attributes }
19
22
  @template.content_tag(tag, **options, &block)
20
23
  end
21
24
 
22
25
  DEFAULT_SECTION_SUBHEADING_CLASSES = "ariadne-mt-1 ariadne-max-w-2xl ariadne-text-sm ariadne-text-gray-500"
23
26
  def subheading(classes: "", attributes: {}, &block)
24
- actual_classes = class_names(DEFAULT_SECTION_SUBHEADING_CLASSES, classes)
27
+ actual_classes = merge_class_names(DEFAULT_SECTION_SUBHEADING_CLASSES, classes)
25
28
  options = { class: actual_classes, **attributes }
26
29
  @template.content_tag(:p, **options, &block)
27
30
  end
28
31
 
29
32
  DEFAULT_LABEL_CLASSES = "ariadne-block ariadne-text-sm ariadne-font-medium ariadne-text-gray-700 ariadne-pl-2"
30
- def label(object_name, content, options = {}, &block)
31
- options[:class] = class_names(DEFAULT_LABEL_CLASSES, options.delete(:classes))
32
- super(object_name, content, options, &block)
33
+ def label(method, text = nil, options = {}, &block)
34
+ options[:class] = merge_class_names(DEFAULT_LABEL_CLASSES, options.delete(:classes))
35
+ super(method, text, options, &block)
33
36
  end
34
37
 
35
38
  DEFAULT_TEXT_CLASSES = "ariadne-shadow-sm focus:ariadne-ring-slate-500 focus:ariadne-border-slate-500 ariadne-block ariadne-w-full sm:ariadne-text-sm ariadne-border-gray-300 ariadne-rounded-md"
36
39
  def text_field(method, options = {})
37
- options[:class] = class_names(DEFAULT_TEXT_CLASSES, options.delete(:classes))
40
+ options[:class] = merge_class_names(DEFAULT_TEXT_CLASSES, options.delete(:classes))
38
41
  super(method, **options)
39
42
  end
40
43
 
41
44
  DEFAULT_CHECKBOX_CLASSES = "focus:ariadne-ring-slate-500 ariadne-h-4 ariadne-w-4 ariadne-text-slate-600 ariadne-border-slate-300 ariadne-rounded"
42
45
  def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
43
- options[:class] = class_names(DEFAULT_CHECKBOX_CLASSES, options.delete(:classes))
46
+ options[:class] = merge_class_names(DEFAULT_CHECKBOX_CLASSES, options.delete(:classes))
44
47
  super(method, options, checked_value, unchecked_value)
45
48
  end
46
49
 
47
50
  DEFAULT_RADIO_CLASSES = "focus:ariadne-ring-slate-500 ariadne-h-4 ariadne-w-4 ariadne-text-slate-600 ariadne-border-gray-300 ariadne-rounded"
48
51
  def radio_button(method, tag_value, options = {})
49
- options[:class] = class_names(DEFAULT_RADIO_CLASSES, options.delete(:classes))
52
+ options[:class] = merge_class_names(DEFAULT_RADIO_CLASSES, options.delete(:classes))
50
53
  super(method, tag_value, **options)
51
54
  end
52
55
 
53
56
  DEFAULT_TEXTAREA_CLASSES = "ariadne-shadow-sm focus:ariadne-ring-slate-500 focus:ariadne-border-slate-500 ariadne-block ariadne-w-full sm:ariadne-text-sm ariadne-border ariadne-border-gray-300 ariadne-rounded-md"
54
57
  def text_area(method, options = {})
55
- options[:class] = class_names(DEFAULT_TEXTAREA_CLASSES, options.delete(:classes))
58
+ options[:class] = merge_class_names(DEFAULT_TEXTAREA_CLASSES, options.delete(:classes))
56
59
  super(method, **options)
57
60
  end
58
61
 
59
62
  DEFAULT_EMAIL_CLASSES = "ariadne-shadow-sm focus:ariadne-ring-slate-500 focus:ariadne-border-slate-500 ariadne-block ariadne-w-full sm:ariadne-text-sm ariadne-border-gray-300 ariadne-rounded-md"
60
63
  def email_field(method, options = {})
61
- options[:class] = class_names(DEFAULT_EMAIL_CLASSES, options.delete(:classes))
64
+ options[:class] = merge_class_names(DEFAULT_EMAIL_CLASSES, options.delete(:classes))
62
65
  super(method, **options)
63
66
  end
64
67
 
65
68
  DEFAULT_PASSWORD_CLASSES = "ariadne-appearance-none ariadne-block ariadne-w-full ariadne-px-3 ariadne-py-2 ariadne-border ariadne-border-gray-300 ariadne-rounded-md ariadne-shadow-sm ariadne-placeholder-gray-400 focus:ariadne-outline-none focus:ariadne-ring-slate-500 focus:ariadne-border-slate-500 sm:ariadne-text-sm"
66
69
  def password_field(method, options = {})
67
- options[:class] = class_names(DEFAULT_PASSWORD_CLASSES, options.delete(:classes))
70
+ options[:class] = merge_class_names(DEFAULT_PASSWORD_CLASSES, options.delete(:classes))
68
71
  super(method, **options)
69
72
  end
70
73
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ERBLint
4
+ module Linters
5
+ module ArgumentMappers
6
+ # Error when converting arguments.
7
+ class ConversionError < StandardError; end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "argument_mappers/conversion_error"
4
+
5
+ module ERBLint
6
+ module Linters
7
+ # Provides the autocorrection functionality for the linter. Once included, you should define the following constants:
8
+ # * `ARGUMENT_MAPPER` - required - The class responsible for transforming classes and attributes into arguments for the component.
9
+ # * `COMPONENT` - required - The component name for the linter. It will be used to generate the correction.
10
+ module Autocorrectable
11
+ def map_arguments(tag, _tag_tree)
12
+ self.class::ARGUMENT_MAPPER.new(tag).to_s
13
+ rescue ArgumentMappers::ConversionError
14
+ nil
15
+ end
16
+
17
+ def correction(args)
18
+ return nil if args.nil?
19
+
20
+ correction = "<%= render #{self.class::COMPONENT}.new"
21
+ correction += "(#{args})" if args.present?
22
+ "#{correction} do %>"
23
+ end
24
+
25
+ def message(args, processed_source)
26
+ return self.class::MESSAGE if args.nil?
27
+
28
+ "#{self.class::MESSAGE}\nTry using:\n\n#{correction(args)}\n\nYou can also run erblint in autocorrect mode:\n\nbundle exec erblint -a #{processed_source.filename}\n"
29
+ end
30
+ end
31
+ end
32
+ end