ariadne_view_components 0.0.4 → 0.0.5

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/builds/ariadne_view_components.css +1874 -0
  4. data/app/assets/javascripts/ariadne.d.ts +1 -0
  5. data/app/assets/javascripts/ariadne_view_components.js +1 -1
  6. data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
  7. data/app/assets/javascripts/clipboard-copy-component.d.ts +4 -0
  8. data/app/assets/javascripts/slideover-component.d.ts +9 -0
  9. data/app/assets/javascripts/time_ago_component.d.ts +1 -0
  10. data/app/assets/javascripts/tooltip-component.d.ts +24 -0
  11. data/app/assets/stylesheets/application.ariadne_view_components.css +5 -3
  12. data/app/assets/stylesheets/tooltip-component.css +37 -0
  13. data/app/components/ariadne/ariadne.d.ts +1 -0
  14. data/app/components/ariadne/ariadne.js +9 -0
  15. data/app/components/ariadne/ariadne.ts +3 -0
  16. data/app/components/ariadne/base_button.rb +9 -8
  17. data/app/components/ariadne/blankslate_component.rb +1 -1
  18. data/app/components/ariadne/body_component.rb +30 -0
  19. data/app/components/ariadne/button_component.rb +5 -10
  20. data/app/components/ariadne/clipboard-copy-component.d.ts +4 -0
  21. data/app/components/ariadne/clipboard-copy-component.js +18 -0
  22. data/app/components/ariadne/clipboard_copy_component.d.ts +4 -0
  23. data/app/components/ariadne/clipboard_copy_component.html.erb +2 -2
  24. data/app/components/ariadne/clipboard_copy_component.js +18 -0
  25. data/app/components/ariadne/clipboard_copy_component.rb +41 -3
  26. data/app/components/ariadne/comment_component.html.erb +25 -0
  27. data/app/components/ariadne/comment_component.rb +45 -0
  28. data/app/components/ariadne/component.rb +2 -1
  29. data/app/components/ariadne/container_component.rb +1 -1
  30. data/app/components/ariadne/flash_component.rb +1 -1
  31. data/app/components/ariadne/flex_component.rb +51 -0
  32. data/app/components/ariadne/grid_component.html.erb +12 -3
  33. data/app/components/ariadne/grid_component.rb +18 -7
  34. data/app/components/ariadne/header_component.rb +1 -1
  35. data/app/components/ariadne/heading_component.rb +2 -2
  36. data/app/components/ariadne/heroicon_component.html.erb +4 -6
  37. data/app/components/ariadne/heroicon_component.rb +18 -7
  38. data/app/components/ariadne/inline_flex_component.rb +11 -9
  39. data/app/components/ariadne/link_component.rb +13 -8
  40. data/app/components/ariadne/list_component.html.erb +5 -7
  41. data/app/components/ariadne/list_component.rb +4 -34
  42. data/app/components/ariadne/main_component.rb +32 -0
  43. data/app/components/ariadne/slideover-component.d.ts +9 -0
  44. data/app/components/ariadne/slideover-component.js +20 -0
  45. data/app/components/ariadne/slideover_component.d.ts +9 -0
  46. data/app/components/ariadne/slideover_component.html.erb +1 -4
  47. data/app/components/ariadne/slideover_component.js +19 -0
  48. data/app/components/ariadne/slideover_component.rb +19 -15
  49. data/app/components/ariadne/time_ago_component.d.ts +1 -0
  50. data/app/components/ariadne/time_ago_component.js +1 -0
  51. data/app/components/ariadne/tooltip-component.d.ts +24 -0
  52. data/app/components/ariadne/tooltip-component.js +42 -0
  53. data/app/components/ariadne/tooltip-component.ts +57 -0
  54. data/app/components/ariadne/tooltip_component.html.erb +4 -0
  55. data/app/components/ariadne/tooltip_component.rb +34 -31
  56. data/app/lib/ariadne/form_builder.rb +14 -14
  57. data/lib/ariadne/classify.rb +4 -98
  58. data/lib/ariadne/view_components/version.rb +1 -1
  59. data/lib/ariadne/view_components.rb +31 -29
  60. data/lib/rubocop/cop/ariadne/ariadne_heroicon.rb +2 -2
  61. data/lib/tasks/docs.rake +4 -0
  62. data/static/arguments.yml +89 -13
  63. data/static/audited_at.json +4 -0
  64. data/static/classes.yml +40 -8
  65. data/static/constants.json +83 -101
  66. data/static/statuses.json +4 -0
  67. metadata +48 -6
@@ -24,82 +24,85 @@ module Ariadne
24
24
  # - When there is no visible text on the trigger element and the tooltip content is appropriate as a label for the element, set `type: :label`.
25
25
  # This type is usually only appropriate for an icon-only control.
26
26
  class TooltipComponent < Ariadne::Component
27
- DIRECTION_DEFAULT = :s
28
- DIRECTION_OPTIONS = [DIRECTION_DEFAULT, :n, :e, :w, :ne, :nw, :se, :sw].freeze
27
+ DEFAULT_TAG = :tooltip
28
+ DEFAULT_PLACEMENT = :top
29
+ VALID_PLACEMENTS = [DEFAULT_PLACEMENT, :right, :bottom, :left].freeze
30
+
31
+ DEFAULT_CLASSES = "invisible absolute bg-slate-900 text-white font-semibold max-w-xs py-1 px-2 rounded z-max"
32
+
33
+ DATA_CONTROLLER = "tooltip-component"
34
+ DATA_ACTION = "mouseover->tooltip-component#show mouseout->tooltip-component#hide"
29
35
 
30
36
  TYPE_DEFAULT = :description
31
37
  TYPE_OPTIONS = [:label, TYPE_DEFAULT].freeze
38
+
39
+ # DEFAULT_DATA_ATTRIBUTES = {
40
+ # "data-controller": DATA_CONTROLLER,
41
+ # "data-action": "mouseover->tooltip-component#show mouseout->tooltip-component#hide",
42
+ # "data-tooltip-component-placement": DEFAULT_PLACEMENT,
43
+ # }
44
+
32
45
  # @example As a description for an icon-only button
33
46
  # @description
34
47
  # If the tooltip content provides supplementary description, set `type: :description` to establish an `aria-describedby` relationship.
35
48
  # The trigger element should also have a _concise_ accessible label via `aria-label`.
36
49
  # @code
37
50
  # <%= render(Ariadne::HeroiconComponent.new(icon: :moon, variant: HeroiconsHelper::Icon::VARIANT_OUTLINE, attributes: { id: "bold-button-0" })) %>
38
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "bold-button-0" }, type: :description, text: "Add bold text", direction: :ne)) %>
51
+ # <%= render(Ariadne::TooltipComponent.new(for_id: "bold-button-0", type: :description, text: "Add bold text", direction: :top)) %>
39
52
  # @example As a label for an icon-only button
40
53
  # @description
41
54
  # If the tooltip labels the icon-only button, set `type: :label`. This tooltip content becomes the accessible name for the button.
42
55
  # @code
43
- # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "like-button"})) { "👍" } %>
44
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "like-button" }, type: :label, text: "Like", direction: :n)) %>
56
+ # <%= render(Ariadne::ButtonComponent.new(attributes: { id: "like-button" })) { "👍" } %>
57
+ # <%= render(Ariadne::TooltipComponent.new(for_id: "like-button", type: :label, text: "Like", direction: :top)) %>
45
58
  #
46
59
  # @example As a description for a button with visible label
47
60
  # @description
48
61
  # If the button already has visible label text, the tooltip content is likely supplementary so set `type: :description`.
49
62
  # @code
50
63
  # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "save-button"}, scheme: :success)) { "Save" } %>
51
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "save-button"}, type: :description, text: "This will immediately impact all organization members", direction: :ne)) %>
64
+ # <%= render(Ariadne::TooltipComponent.new(for_id: "save-button", type: :description, text: "This will immediately impact all organization members", direction: :right)) %>
52
65
  # @example With direction
53
66
  # @description
54
67
  # Set direction of tooltip with `direction`. The tooltip is responsive and will automatically adjust direction to avoid cutting off.
55
68
  # @code
56
69
  # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "North", m: 2})) { "North" } %>
57
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "North"}, type: :description, text: "This is a North-facing tooltip, and is responsive.", direction: :n)) %>
70
+ # <%= render(Ariadne::TooltipComponent.new(for_id: "North", type: :description, text: "This is a North-facing tooltip, and is responsive.", direction: :top)) %>
58
71
  # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "South", m: 2})) { "South" } %>
59
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "South"}, type: :description, text: "This is a South-facing tooltip and is responsive.", direction: :s)) %>
72
+ # <%= render(Ariadne::TooltipComponent.new(for_id: "South", type: :description, text: "This is a South-facing tooltip and is responsive.", direction: :bottom)) %>
60
73
  # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "East", m: 2})) { "East" } %>
61
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "East"}, type: :description, text: "This is a East-facing tooltip and is responsive.", direction: :e)) %>
74
+ # <%= render(Ariadne::TooltipComponent.new(for_id: "East", type: :description, text: "This is a East-facing tooltip and is responsive.", direction: :right)) %>
62
75
  # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "West", m: 2})) { "West" } %>
63
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "West"}, type: :description, text: "This is a West-facing tooltip and is responsive.", direction: :w)) %>
64
- # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "Northeast", m: 2})) { "Northeast" } %>
65
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "Northeast"}, type: :description, text: "This is a Northeast-facing tooltip and is responsive.", direction: :ne)) %>
66
- # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "Southeast", m: 2})) { "Southeast" } %>
67
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "Southeast"}, type: :description, text: "This is a Southeast-facing tooltip and is responsive.", direction: :se)) %>
68
- # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "Northwest", m: 2})) { "Northwest" } %>
69
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "Northwest"}, type: :description, text: "This is a Northwest-facing tooltip and is responsive.", direction: :nw)) %>
70
- # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "Southwest", m: 2})) { "Southwest" } %>
71
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "Southwest"}, type: :description, text: "This is a Southwest-facing tooltip and is responsive.", direction: :sw)) %>
76
+ # <%= render(Ariadne::TooltipComponent.new(for_id: "West""", type: :description, text: "This is a West-facing tooltip and is responsive.", direction: :left)) %>
72
77
  # @example With relative parent
73
78
  # @description
74
79
  # When the tooltip and trigger element have a parent container with `relative: position`, it should not affect width of the tooltip.
75
80
  # @code
76
81
  # <span style="position: relative;">
77
82
  # <%= render(Ariadne::ButtonComponent.new(attributes: {id: "test-button"}, scheme: :info)) { "Test" } %>
78
- # <%= render(Ariadne::TooltipComponent.new(attributes: { for: "test-button" }, type: :description, text: "This tooltip should take up the full width", direction: :ne)) %>
83
+ # <%= render(Ariadne::TooltipComponent.new(for_id: "test-button", type: :description, text: "This tooltip should take up the full width", direction: :bottom)) %>
79
84
  # </span>
80
85
  # @param tag [Symbol, String] The rendered tag name
81
- # @param type [Symbol] <%= one_of(Ariadne::TooltipComponent::TYPE_OPTIONS) %>
86
+ # @param for_id [String] The ID of the element that the tooltip should be attached to.
82
87
  # @param text [String] The text content of the tooltip. This should be brief and no longer than a sentence.
83
- # @param direction [Symbol] <%= one_of(Ariadne::TooltipComponent::DIRECTION_OPTIONS) %>
88
+ # @param type [Symbol] <%= one_of(Ariadne::TooltipComponent::TYPE_OPTIONS) %>
89
+ # @param direction [Symbol] <%= one_of(Ariadne::TooltipComponent::VALID_PLACEMENTS) %>
84
90
  # @param classes [String] <%= link_to_classes_docs %>
85
91
  # @param attributes [Hash] <%= link_to_attributes_docs %>
86
- def initialize(tag: :"tool-tip", type: TYPE_DEFAULT, text:, direction: DIRECTION_DEFAULT, classes: "", attributes: {})
92
+ def initialize(tag: DEFAULT_TAG, for_id:, text:, type: TYPE_DEFAULT, direction: DEFAULT_PLACEMENT, classes: "", attributes: {})
87
93
  raise TypeError, "tooltip text must be a string" unless text.is_a?(String)
88
94
 
89
- @tag = check_incoming_tag(:"tool-tip", tag)
95
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
90
96
 
91
97
  @text = text
92
- @classes = classes
98
+ @classes = class_names(DEFAULT_CLASSES, classes)
93
99
 
94
100
  @attributes = attributes
95
- @attributes[:hidden] = true
96
- @attributes[:visible] ||= false
97
- @attributes[:"data-direction"] = fetch_or_raise(DIRECTION_OPTIONS, direction)
98
- @attributes[:"data-type"] = fetch_or_raise(TYPE_OPTIONS, type)
99
- end
101
+ @attributes[:for] = for_id
100
102
 
101
- def call
102
- render(Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes)) { @text }
103
+ @attributes[:"data-tooltip-component-placement"] = fetch_or_raise(VALID_PLACEMENTS, direction)
104
+ @attributes[:"data-type"] = fetch_or_raise(TYPE_OPTIONS, type)
105
+ @attributes[:"data-tooltip-component-target"] = "tooltip"
103
106
  end
104
107
  end
105
108
  end
@@ -5,7 +5,7 @@ module Ariadne
5
5
  class FormBuilder < ActionView::Helpers::FormBuilder
6
6
  include ClassNameHelper
7
7
 
8
- DEFAULT_SECTION_CLASSES = "divide-y divide-gray-200 pt-8 space-y-6 sm:pt-10 sm:space-y-5"
8
+ DEFAULT_SECTION_CLASSES = "pt-8 space-y-6 sm:pt-10 sm:space-y-5"
9
9
  def section(classes: "", attributes: {}, &block)
10
10
  actual_classes = class_names(DEFAULT_SECTION_CLASSES, classes)
11
11
  options = { class: actual_classes, **attributes }
@@ -13,10 +13,10 @@ module Ariadne
13
13
  end
14
14
 
15
15
  DEFAULT_SECTION_HEADING_CLASSES = "text-lg leading-6 font-medium text-gray-900"
16
- def heading(classes: "", attributes: {}, &block)
16
+ def heading(tag: :h3, classes: "", attributes: {}, &block)
17
17
  actual_classes = class_names(DEFAULT_SECTION_HEADING_CLASSES, classes)
18
18
  options = { class: actual_classes, **attributes }
19
- @template.content_tag(:h3, **options, &block)
19
+ @template.content_tag(tag, **options, &block)
20
20
  end
21
21
 
22
22
  DEFAULT_SECTION_SUBHEADING_CLASSES = "mt-1 max-w-2xl text-sm text-gray-500"
@@ -26,45 +26,45 @@ module Ariadne
26
26
  @template.content_tag(:p, **options, &block)
27
27
  end
28
28
 
29
- DEFAULT_LABEL_CLASSES = "block text-sm font-medium text-gray-700"
30
- def label(method, text = nil, options = {}, &block)
31
- options[:class] = class_names(DEFAULT_LABEL_CLASSES, options[:class])
32
- super(method, **options)
29
+ DEFAULT_LABEL_CLASSES = "block text-sm font-medium text-gray-700 pl-2"
30
+ def label(object_name, content, ptions = {}, &block)
31
+ options[:class] = class_names(DEFAULT_LABEL_CLASSES, options.delete(:classes))
32
+ super(object_name, content, options, &block)
33
33
  end
34
34
 
35
35
  DEFAULT_TEXT_CLASSES = "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md"
36
36
  def text_field(method, options = {})
37
- options[:class] = class_names(DEFAULT_TEXT_CLASSES, options[:class])
37
+ options[:class] = class_names(DEFAULT_TEXT_CLASSES, options.delete(:classes))
38
38
  super(method, **options)
39
39
  end
40
40
 
41
41
  DEFAULT_CHECKBOX_CLASSES = "focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
42
42
  def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
43
- options[:class] = class_names(DEFAULT_TEXT_CLASSES, options[:class])
44
- super(method, **options)
43
+ options[:class] = class_names(DEFAULT_CHECKBOX_CLASSES, options.delete(:classes))
44
+ super(method, options, checked_value, unchecked_value)
45
45
  end
46
46
 
47
47
  DEFAULT_RADIO_CLASSES = "focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
48
48
  def radio_button(method, tag_value, options = {})
49
- options[:class] = class_names(DEFAULT_RADIO_CLASSES, options[:class])
49
+ options[:class] = class_names(DEFAULT_RADIO_CLASSES, options.delete(:classes))
50
50
  super(method, tag_value, **options)
51
51
  end
52
52
 
53
53
  DEFAULT_TEXTAREA_CLASSES = "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border border-gray-300 rounded-md"
54
54
  def text_area(method, options = {})
55
- options[:class] = class_names(DEFAULT_TEXTAREA_CLASSES, options[:class])
55
+ options[:class] = class_names(DEFAULT_TEXTAREA_CLASSES, options.delete(:classes))
56
56
  super(method, **options)
57
57
  end
58
58
 
59
59
  DEFAULT_EMAIL_CLASSES = "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md"
60
60
  def email_field(method, options = {})
61
- options[:class] = class_names(DEFAULT_EMAIL_CLASSES, options[:class])
61
+ options[:class] = class_names(DEFAULT_EMAIL_CLASSES, options.delete(:classes))
62
62
  super(method, **options)
63
63
  end
64
64
 
65
65
  DEFAULT_PASSWORD_CLASSES = "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
66
66
  def password_field(method, options = {})
67
- options[:class] = class_names(DEFAULT_PASSWORD_CLASSES, options[:class])
67
+ options[:class] = class_names(DEFAULT_PASSWORD_CLASSES, options.delete(:classes))
68
68
  super(method, **options)
69
69
  end
70
70
  end
@@ -3,6 +3,8 @@
3
3
  require_relative "classify/utilities"
4
4
  require_relative "classify/validation"
5
5
 
6
+ require "tailwind_merge"
7
+
6
8
  module Ariadne
7
9
  # :nodoc:
8
10
  class Classify
@@ -110,104 +112,8 @@ module Ariadne
110
112
  private def validated_class_names(classes)
111
113
  return if classes.blank?
112
114
 
113
- corrected_classes = correct_classes(classes)
114
-
115
- if raise_on_invalid_options? && !ENV["ARIADNE_WARNINGS_DISABLED"]
116
- invalid_class_names =
117
- corrected_classes.each_with_object([]) do |class_name, memo|
118
- memo << class_name if Ariadne::Classify::Validation.invalid?(class_name)
119
- end
120
-
121
- # TODO: implement this
122
- if invalid_class_names.any?
123
- # raise ArgumentError, <<~MSG
124
- # Use Tailwind CSS class names instead of your own #{"name".pluralize(invalid_class_names.length)} #{invalid_class_names.to_sentence}.
125
- # Set ARIADNE_WARNINGS_DISABLED=1 to disable this warning.
126
- # MSG
127
- end
128
- end
129
-
130
- corrected_classes.join(" ")
131
- end
132
-
133
- # TODO: automate this, ugh. peek at utilities.yml
134
- BG_PREFIX = /^bg-/.freeze
135
- BG_PSEUDO_PREFIX = /^\S+:bg-/.freeze
136
- BORDER_PREFIX = /^border-/.freeze
137
- BORDER_PSEUDO_PREFIX = /^\S+:border-/.freeze
138
- TEXT_ASPECT_PREFIX = /^text-\S+-/.freeze
139
- TEXT_ASPECT_PSEUDO_PREFIX = /^\S+:text-\S+-/.freeze
140
- TEXT_PREFIX = /^text-/.freeze
141
- TEXT_PSEUDO_PREFIX = /^\S+:text-/.freeze
142
-
143
- BORDER_STATE_PREFIX = /^border-state-/.freeze
144
- BORDER_SIDE_PREFIX = /^border-.(?:-)?/.freeze
145
-
146
- # TODO: TEST!
147
- private def correct_classes(classes)
148
- matched_bg = ""
149
- matched_bg_pseudo = {}
150
- matched_border = ""
151
- matched_border_pseudo = {}
152
- matched_text_aspect = {}
153
- matched_text_aspect_pseudo = {}
154
- matched_text = ""
155
- matched_text_pseudo = {}
156
-
157
- classes.split(" ").reverse.each_with_object([]) do |c, memo|
158
- next if c.blank?
159
-
160
- class_name = c.strip
161
-
162
- if class_name.match(BG_PREFIX)
163
- next if matched_bg.present?
164
-
165
- memo << matched_bg = class_name
166
- elsif class_name.match(BG_PSEUDO_PREFIX)
167
- next if matched_bg_pseudo.keys.any? { |m| m.start_with?(class_name.split(":").first) }
168
-
169
- matched_bg_pseudo[class_name] = true
170
- memo << class_name
171
-
172
- elsif class_name.match(BORDER_PREFIX)
173
- next if matched_border.present?
174
-
175
- if class_name.match(BORDER_STATE_PREFIX) || class_name.match(BORDER_SIDE_PREFIX)
176
- memo << class_name
177
- next
178
- end
179
-
180
- memo << matched_border = class_name
181
- elsif class_name.match(BORDER_PSEUDO_PREFIX)
182
- next if matched_border_pseudo.keys.any? { |m| m.start_with?(class_name.split(":").first) }
183
-
184
- matched_border_pseudo[class_name] = true
185
- memo << class_name
186
-
187
- elsif class_name.match(TEXT_ASPECT_PREFIX)
188
- next if matched_text_aspect.keys.any? { |m| m.start_with?(class_name.split(":").first) }
189
-
190
- matched_text_aspect[class_name] = true
191
- memo << class_name
192
- elsif class_name.match(TEXT_ASPECT_PSEUDO_PREFIX)
193
- next if matched_text_aspect_pseudo.keys.any? { |m| m.start_with?(class_name.split(":").first) }
194
-
195
- matched_text_aspect_pseudo[class_name] = true
196
- memo << class_name
197
-
198
- elsif class_name.match(TEXT_PREFIX)
199
- next if matched_text.present?
200
-
201
- memo << matched_text = class_name
202
- elsif class_name.match(TEXT_PSEUDO_PREFIX)
203
- next if matched_text_pseudo.keys.any? { |m| m.start_with?(class_name.split(":").first) }
204
-
205
- matched_text_pseudo[class_name] = true
206
- memo << class_name
207
- else
208
- memo << class_name
209
- end
210
- end.uniq.reverse
115
+ # TODO: obviously instantiate this
116
+ TailwindMerge::Merger.new.merge(classes)
211
117
  end
212
118
 
213
119
  private def raise_on_invalid_options?
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ariadne
4
4
  module ViewComponents
5
- VERSION = "0.0.4"
5
+ VERSION = "0.0.5"
6
6
  end
7
7
  end
@@ -15,45 +15,47 @@ module Ariadne
15
15
  audited_at: "audited_at.json",
16
16
  }.freeze
17
17
 
18
- # generate_statuses returns a hash mapping component name to
19
- # the component's status sorted alphabetically by the component name.
20
- def self.generate_statuses
21
- Ariadne::Component.descendants.sort_by(&:name).each_with_object({}) do |component, mem|
22
- mem[component.to_s] = component.status.to_s
18
+ class << self
19
+ # generate_statuses returns a hash mapping component name to
20
+ # the component's status sorted alphabetically by the component name.
21
+ def generate_statuses
22
+ Ariadne::Component.descendants.sort_by(&:name).each_with_object({}) do |component, mem|
23
+ mem[component.to_s] = component.status.to_s
24
+ end
23
25
  end
24
- end
25
26
 
26
- # generate_audited_at returns a hash mapping component name to
27
- # the day the component has passed an accessibility audit.
28
- def self.generate_audited_at
29
- Ariadne::Component.descendants.sort_by(&:name).each_with_object({}) do |component, mem|
30
- mem[component.to_s] = component.audited_at.to_s
27
+ # generate_audited_at returns a hash mapping component name to
28
+ # the day the component has passed an accessibility audit.
29
+ def generate_audited_at
30
+ Ariadne::Component.descendants.sort_by(&:name).each_with_object({}) do |component, mem|
31
+ mem[component.to_s] = component.audited_at.to_s
32
+ end
31
33
  end
32
- end
33
34
 
34
- # generate_constants returns a hash mapping component name to
35
- # all of its constants.
36
- def self.generate_constants
37
- Ariadne::Component.descendants.sort_by(&:name).each_with_object({}) do |component, mem|
38
- mem[component.to_s] = component.constants(false).sort.each_with_object({}) do |constant, h|
39
- h[constant] = component.const_get(constant)
35
+ # generate_constants returns a hash mapping component name to
36
+ # all of its constants.
37
+ def generate_constants
38
+ Ariadne::Component.descendants.sort_by(&:name).each_with_object({}) do |component, mem|
39
+ mem[component.to_s] = component.constants(false).sort.each_with_object({}) do |constant, h|
40
+ h[constant] = component.const_get(constant)
41
+ end
40
42
  end
41
43
  end
42
- end
43
44
 
44
- # dump generates the requested stat hash and outputs it to a file.
45
- def self.dump(stats)
46
- require "json"
45
+ # dump generates the requested stat hash and outputs it to a file.
46
+ def dump(stats)
47
+ require "json"
47
48
 
48
- File.open(File.join(DEFAULT_STATIC_PATH, FILE_NAMES[stats]), "w") do |f|
49
- f.write(JSON.pretty_generate(send("generate_#{stats}")))
50
- f.write($INPUT_RECORD_SEPARATOR)
49
+ File.open(File.join(DEFAULT_STATIC_PATH, FILE_NAMES[stats]), "w") do |f|
50
+ f.write(JSON.pretty_generate(send("generate_#{stats}")))
51
+ f.write($INPUT_RECORD_SEPARATOR)
52
+ end
51
53
  end
52
- end
53
54
 
54
- # read returns a JSON string matching the output of the corresponding stat.
55
- def self.read(stats)
56
- File.read(File.join(DEFAULT_STATIC_PATH, FILE_NAMES[stats]))
55
+ # read returns a JSON string matching the output of the corresponding stat.
56
+ def read(stats)
57
+ File.read(File.join(DEFAULT_STATIC_PATH, FILE_NAMES[stats]))
58
+ end
57
59
  end
58
60
  end
59
61
  end
@@ -113,7 +113,7 @@ module RuboCop
113
113
  if size.between?(10, 16)
114
114
  ""
115
115
  elsif size.between?(22, 26)
116
- ":m"
116
+ :md
117
117
  else
118
118
  size
119
119
  end
@@ -209,7 +209,7 @@ module RuboCop
209
209
  # No arguments if they map to the default size
210
210
  return if size_attributes.blank? || size_attributes.values.all?(&:blank?)
211
211
  # Return mapped argument to `size`
212
- return "size: :m" if size_attributes.values.any?(":m")
212
+ return "size: :md" if size_attributes.values.any?(:md)
213
213
 
214
214
  size_attributes.map do |key, value|
215
215
  "#{key}: #{value}"
data/lib/tasks/docs.rake CHANGED
@@ -47,6 +47,9 @@ namespace :docs do
47
47
  # Rails controller for rendering arbitrary ERB
48
48
  view_context = ApplicationController.new.tap { |c| c.request = ActionDispatch::TestRequest.create }.view_context
49
49
  components = [
50
+ Ariadne::FlexComponent,
51
+ Ariadne::CommentComponent,
52
+ Ariadne::BodyComponent,
50
53
  Ariadne::BlankslateComponent,
51
54
  Ariadne::BaseButton,
52
55
  Ariadne::ButtonComponent,
@@ -63,6 +66,7 @@ namespace :docs do
63
66
  Ariadne::InlineFlexComponent,
64
67
  Ariadne::LinkComponent,
65
68
  Ariadne::ListComponent,
69
+ Ariadne::MainComponent,
66
70
  Ariadne::PillComponent,
67
71
  Ariadne::SlideoverComponent,
68
72
  Ariadne::Text,
data/static/arguments.yml CHANGED
@@ -12,8 +12,8 @@
12
12
  description: One of `:button`, `:reset`, or `:submit`.
13
13
  - name: size
14
14
  type: Symbol
15
- default: "`:m`"
16
- description: One of `:l`, `:m`, `:s`, `:xl`, or `:xs`.
15
+ default: "`:md`"
16
+ description: One of `:lg`, `:md`, `:sm`, `:xl`, or `:xs`.
17
17
  - name: classes
18
18
  type: String
19
19
  default: '`""`'
@@ -37,6 +37,17 @@
37
37
  type: Hash
38
38
  default: "`{}`"
39
39
  description: "[Classes and attributes](/classes-attributes)"
40
+ - component: Body
41
+ source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/body_component.rb
42
+ parameters:
43
+ - name: classes
44
+ type: String
45
+ default: '`""`'
46
+ description: "[Classes and attributes](/classes-attributes)"
47
+ - name: attributes
48
+ type: Hash
49
+ default: "`{}`"
50
+ description: "[Classes and attributes](/classes-attributes)"
40
51
  - component: Button
41
52
  source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/button_component.rb
42
53
  parameters:
@@ -55,7 +66,7 @@
55
66
  - name: size
56
67
  type: Symbol
57
68
  default: "`BaseButton::DEFAULT_SIZE`"
58
- description: One of `:l`, `:m`, `:s`, `:xl`, or `:xs`.
69
+ description: One of `:lg`, `:md`, `:sm`, `:xl`, or `:xs`.
59
70
  - name: type
60
71
  type: Symbol
61
72
  default: "`:button`"
@@ -83,6 +94,10 @@
83
94
  type: String
84
95
  default: '`""`'
85
96
  description: Text to copy into the users clipboard when they click the component.
97
+ - name: for_id
98
+ type: String
99
+ default: "`nil`"
100
+ description: If `value` is not provided, the element with this id will be copied.
86
101
  - name: aria_label
87
102
  type: String
88
103
  default: '`""`'
@@ -92,6 +107,21 @@
92
107
  type: Hash
93
108
  default: "`{}`"
94
109
  description: "[Classes and attributes](/classes-attributes)"
110
+ - component: Comment
111
+ source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/comment_component.rb
112
+ parameters:
113
+ - name: action
114
+ type: String
115
+ default: N/A
116
+ description: The action to take when the form is submitted.
117
+ - name: classes
118
+ type: String
119
+ default: '`""`'
120
+ description: "[Classes and attributes](/classes-attributes)"
121
+ - name: attributes
122
+ type: Hash
123
+ default: "`{}`"
124
+ description: "[Classes and attributes](/classes-attributes)"
95
125
  - component: Container
96
126
  source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/container_component.rb
97
127
  parameters:
@@ -167,6 +197,25 @@
167
197
  type: Hash
168
198
  default: "`{}`"
169
199
  description: "[Classes and attributes](/classes-attributes)"
200
+ - component: Flex
201
+ source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/flex_component.rb
202
+ parameters:
203
+ - name: tag
204
+ type: Symbol, String
205
+ default: "`:div`"
206
+ description: The rendered tag name.
207
+ - name: type
208
+ type: Symbol
209
+ default: N/A
210
+ description: One of `:column`, `:column_reverse`, `:row`, or `:row_reverse`.
211
+ - name: classes
212
+ type: String
213
+ default: '`""`'
214
+ description: "[Classes and attributes](/classes-attributes)"
215
+ - name: attributes
216
+ type: Hash
217
+ default: "`{}`"
218
+ description: "[Classes and attributes](/classes-attributes)"
170
219
  - component: Footer
171
220
  source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/footer_component.rb
172
221
  parameters:
@@ -236,12 +285,20 @@
236
285
  description: One of `outline` and `solid`.
237
286
  - name: size
238
287
  type: Symbol
239
- default: "`:s`"
240
- description: One of `:s` (`16`) and `:m` (`24`).
288
+ default: "`:sm`"
289
+ description: One of `:sm` (`16`), `:md` (`24`), or `:lg` (`128`).
241
290
  - name: attributes
242
291
  type: Hash
243
292
  default: "`{}`"
244
293
  description: "[Classes and attributes](/classes-attributes)"
294
+ - name: text_classes
295
+ type: String
296
+ default: '`""`'
297
+ description: "[Classes and attributes](/classes-attributes)"
298
+ - name: text_attributes
299
+ type: Hash
300
+ default: "`{}`"
301
+ description: "[Classes and attributes](/classes-attributes)"
245
302
  - component: Image
246
303
  source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/image_component.rb
247
304
  parameters:
@@ -295,6 +352,10 @@
295
352
  type: String
296
353
  default: N/A
297
354
  description: URL to be used for the link.
355
+ - name: actionable
356
+ type: Boolean
357
+ default: "`false`"
358
+ description: If true, adds additional classes to the link to make it more aware.
298
359
  - name: classes
299
360
  type: String
300
361
  default: '`""`'
@@ -314,6 +375,17 @@
314
375
  type: Hash
315
376
  default: "`{}`"
316
377
  description: "[Classes and attributes](/classes-attributes)"
378
+ - component: Main
379
+ source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/main_component.rb
380
+ parameters:
381
+ - name: classes
382
+ type: String
383
+ default: '`""`'
384
+ description: "[Classes and attributes](/classes-attributes)"
385
+ - name: attributes
386
+ type: Hash
387
+ default: "`{}`"
388
+ description: "[Classes and attributes](/classes-attributes)"
317
389
  - component: Pill
318
390
  source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/pill_component.rb
319
391
  parameters:
@@ -343,7 +415,7 @@
343
415
  - name: direction
344
416
  type: Symbol
345
417
  default: N/A
346
- description: One of `:x` and `:y`.
418
+ description: One of `:xl` and `:yd`.
347
419
  - name: form_id
348
420
  type: String
349
421
  default: "`nil`"
@@ -423,21 +495,25 @@
423
495
  parameters:
424
496
  - name: tag
425
497
  type: Symbol, String
426
- default: '`:"tool-tip"`'
498
+ default: "`:tooltip`"
427
499
  description: The rendered tag name
428
- - name: type
429
- type: Symbol
430
- default: "`:description`"
431
- description: One of `:description` and `:label`.
500
+ - name: for_id
501
+ type: String
502
+ default: N/A
503
+ description: The ID of the element that the tooltip should be attached to.
432
504
  - name: text
433
505
  type: String
434
506
  default: N/A
435
507
  description: The text content of the tooltip. This should be brief and no longer
436
508
  than a sentence.
509
+ - name: type
510
+ type: Symbol
511
+ default: "`:description`"
512
+ description: One of `:description` and `:label`.
437
513
  - name: direction
438
514
  type: Symbol
439
- default: "`:s`"
440
- description: One of `:e`, `:n`, `:ne`, `:nw`, `:s`, `:se`, `:sw`, or `:w`.
515
+ default: "`:top`"
516
+ description: One of `:bottom`, `:left`, `:right`, or `:top`.
441
517
  - name: classes
442
518
  type: String
443
519
  default: '`""`'
@@ -2,12 +2,15 @@
2
2
  "Ariadne::BaseButton": "",
3
3
  "Ariadne::BaseComponent": "",
4
4
  "Ariadne::BlankslateComponent": "",
5
+ "Ariadne::BodyComponent": "",
5
6
  "Ariadne::ButtonComponent": "",
6
7
  "Ariadne::ClipboardCopyComponent": "",
8
+ "Ariadne::CommentComponent": "",
7
9
  "Ariadne::ContainerComponent": "",
8
10
  "Ariadne::Content": "",
9
11
  "Ariadne::CounterComponent": "",
10
12
  "Ariadne::FlashComponent": "",
13
+ "Ariadne::FlexComponent": "",
11
14
  "Ariadne::FooterComponent": "",
12
15
  "Ariadne::GridComponent": "",
13
16
  "Ariadne::GridComponent::Item": "",
@@ -19,6 +22,7 @@
19
22
  "Ariadne::LinkComponent": "",
20
23
  "Ariadne::ListComponent": "",
21
24
  "Ariadne::ListComponent::Item": "",
25
+ "Ariadne::MainComponent": "",
22
26
  "Ariadne::PillComponent": "",
23
27
  "Ariadne::SlideoverComponent": "",
24
28
  "Ariadne::Text": "",