ariadne_view_components 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/assets/builds/ariadne_view_components.css +1874 -0
- data/app/assets/javascripts/ariadne.d.ts +1 -0
- data/app/assets/javascripts/ariadne_view_components.js +1 -1
- data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
- data/app/assets/javascripts/clipboard-copy-component.d.ts +4 -0
- data/app/assets/javascripts/slideover-component.d.ts +9 -0
- data/app/assets/javascripts/time_ago_component.d.ts +1 -0
- data/app/assets/javascripts/tooltip-component.d.ts +24 -0
- data/app/assets/stylesheets/application.ariadne_view_components.css +5 -3
- data/app/assets/stylesheets/tooltip-component.css +37 -0
- data/app/components/ariadne/ariadne.d.ts +1 -0
- data/app/components/ariadne/ariadne.js +9 -0
- data/app/components/ariadne/ariadne.ts +3 -0
- data/app/components/ariadne/base_button.rb +9 -8
- data/app/components/ariadne/blankslate_component.rb +1 -1
- data/app/components/ariadne/body_component.rb +30 -0
- data/app/components/ariadne/button_component.rb +5 -10
- data/app/components/ariadne/clipboard-copy-component.d.ts +4 -0
- data/app/components/ariadne/clipboard-copy-component.js +18 -0
- data/app/components/ariadne/clipboard_copy_component.d.ts +4 -0
- data/app/components/ariadne/clipboard_copy_component.html.erb +2 -2
- data/app/components/ariadne/clipboard_copy_component.js +18 -0
- data/app/components/ariadne/clipboard_copy_component.rb +41 -3
- data/app/components/ariadne/comment_component.html.erb +25 -0
- data/app/components/ariadne/comment_component.rb +45 -0
- data/app/components/ariadne/component.rb +2 -1
- data/app/components/ariadne/container_component.rb +1 -1
- data/app/components/ariadne/flash_component.rb +1 -1
- data/app/components/ariadne/flex_component.rb +51 -0
- data/app/components/ariadne/grid_component.html.erb +12 -3
- data/app/components/ariadne/grid_component.rb +18 -7
- data/app/components/ariadne/header_component.rb +1 -1
- data/app/components/ariadne/heading_component.rb +2 -2
- data/app/components/ariadne/heroicon_component.html.erb +4 -6
- data/app/components/ariadne/heroicon_component.rb +18 -7
- data/app/components/ariadne/inline_flex_component.rb +11 -9
- data/app/components/ariadne/link_component.rb +13 -8
- data/app/components/ariadne/list_component.html.erb +5 -7
- data/app/components/ariadne/list_component.rb +4 -34
- data/app/components/ariadne/main_component.rb +32 -0
- data/app/components/ariadne/slideover-component.d.ts +9 -0
- data/app/components/ariadne/slideover-component.js +20 -0
- data/app/components/ariadne/slideover_component.d.ts +9 -0
- data/app/components/ariadne/slideover_component.html.erb +1 -4
- data/app/components/ariadne/slideover_component.js +19 -0
- data/app/components/ariadne/slideover_component.rb +19 -15
- data/app/components/ariadne/time_ago_component.d.ts +1 -0
- data/app/components/ariadne/time_ago_component.js +1 -0
- data/app/components/ariadne/tooltip-component.d.ts +24 -0
- data/app/components/ariadne/tooltip-component.js +42 -0
- data/app/components/ariadne/tooltip-component.ts +57 -0
- data/app/components/ariadne/tooltip_component.html.erb +4 -0
- data/app/components/ariadne/tooltip_component.rb +34 -31
- data/app/lib/ariadne/form_builder.rb +14 -14
- data/lib/ariadne/classify.rb +4 -98
- data/lib/ariadne/view_components/version.rb +1 -1
- data/lib/ariadne/view_components.rb +31 -29
- data/lib/rubocop/cop/ariadne/ariadne_heroicon.rb +2 -2
- data/lib/tasks/docs.rake +4 -0
- data/static/arguments.yml +89 -13
- data/static/audited_at.json +4 -0
- data/static/classes.yml +40 -8
- data/static/constants.json +83 -101
- data/static/statuses.json +4 -0
- 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
|
-
|
28
|
-
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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
|
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
|
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:
|
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(
|
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[:
|
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
|
-
|
102
|
-
|
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 = "
|
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(
|
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(
|
31
|
-
options[:class] = class_names(DEFAULT_LABEL_CLASSES, options
|
32
|
-
super(
|
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
|
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(
|
44
|
-
super(method,
|
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
|
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
|
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
|
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
|
67
|
+
options[:class] = class_names(DEFAULT_PASSWORD_CLASSES, options.delete(:classes))
|
68
68
|
super(method, **options)
|
69
69
|
end
|
70
70
|
end
|
data/lib/ariadne/classify.rb
CHANGED
@@ -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
|
-
|
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?
|
@@ -15,45 +15,47 @@ module Ariadne
|
|
15
15
|
audited_at: "audited_at.json",
|
16
16
|
}.freeze
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
45
|
+
# dump generates the requested stat hash and outputs it to a file.
|
46
|
+
def dump(stats)
|
47
|
+
require "json"
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
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: :
|
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: "`:
|
16
|
-
description: One of `:
|
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 `:
|
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: "`:
|
240
|
-
description: One of `:
|
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 `:
|
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:
|
498
|
+
default: "`:tooltip`"
|
427
499
|
description: The rendered tag name
|
428
|
-
- name:
|
429
|
-
type:
|
430
|
-
default:
|
431
|
-
description:
|
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: "`:
|
440
|
-
description: One of `:
|
515
|
+
default: "`:top`"
|
516
|
+
description: One of `:bottom`, `:left`, `:right`, or `:top`.
|
441
517
|
- name: classes
|
442
518
|
type: String
|
443
519
|
default: '`""`'
|
data/static/audited_at.json
CHANGED
@@ -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": "",
|