ariadne_view_components 0.0.33-x64-mingw32 → 0.0.35-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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