ariadne_view_components 0.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +68 -0
- data/app/assets/javascripts/ariadne_view_components.js +2 -0
- data/app/assets/javascripts/ariadne_view_components.js.map +1 -0
- data/app/assets/stylesheets/application.tailwind.css +3 -0
- data/app/components/ariadne/ariadne.ts +14 -0
- data/app/components/ariadne/base_button.rb +60 -0
- data/app/components/ariadne/base_component.rb +155 -0
- data/app/components/ariadne/button_component.html.erb +4 -0
- data/app/components/ariadne/button_component.rb +158 -0
- data/app/components/ariadne/clipboard_copy_component.html.erb +8 -0
- data/app/components/ariadne/clipboard_copy_component.rb +50 -0
- data/app/components/ariadne/clipboard_copy_component.ts +19 -0
- data/app/components/ariadne/component.rb +123 -0
- data/app/components/ariadne/content.rb +12 -0
- data/app/components/ariadne/counter_component.rb +100 -0
- data/app/components/ariadne/flash_component.html.erb +31 -0
- data/app/components/ariadne/flash_component.rb +125 -0
- data/app/components/ariadne/heading_component.rb +49 -0
- data/app/components/ariadne/heroicon_component.html.erb +7 -0
- data/app/components/ariadne/heroicon_component.rb +116 -0
- data/app/components/ariadne/image_component.rb +51 -0
- data/app/components/ariadne/text.rb +25 -0
- data/app/components/ariadne/tooltip_component.rb +105 -0
- data/app/lib/ariadne/audited/dsl.rb +32 -0
- data/app/lib/ariadne/class_name_helper.rb +22 -0
- data/app/lib/ariadne/fetch_or_fallback_helper.rb +100 -0
- data/app/lib/ariadne/icon_helper.rb +47 -0
- data/app/lib/ariadne/join_style_arguments_helper.rb +14 -0
- data/app/lib/ariadne/logger_helper.rb +23 -0
- data/app/lib/ariadne/status/dsl.rb +41 -0
- data/app/lib/ariadne/tab_nav_helper.rb +35 -0
- data/app/lib/ariadne/tabbed_component_helper.rb +39 -0
- data/app/lib/ariadne/test_selector_helper.rb +20 -0
- data/app/lib/ariadne/underline_nav_helper.rb +44 -0
- data/app/lib/ariadne/view_helper.rb +22 -0
- data/lib/ariadne/classify/utilities.rb +199 -0
- data/lib/ariadne/classify/utilities.yml +1817 -0
- data/lib/ariadne/classify/validation.rb +18 -0
- data/lib/ariadne/classify.rb +210 -0
- data/lib/ariadne/view_components/constants.rb +53 -0
- data/lib/ariadne/view_components/engine.rb +30 -0
- data/lib/ariadne/view_components/linters.rb +3 -0
- data/lib/ariadne/view_components/statuses.rb +14 -0
- data/lib/ariadne/view_components/version.rb +7 -0
- data/lib/ariadne/view_components.rb +59 -0
- data/lib/rubocop/config/default.yml +14 -0
- data/lib/rubocop/cop/ariadne/ariadne_heroicon.rb +252 -0
- data/lib/rubocop/cop/ariadne/base_cop.rb +26 -0
- data/lib/rubocop/cop/ariadne/component_name_migration.rb +35 -0
- data/lib/rubocop/cop/ariadne/no_tag_memoize.rb +43 -0
- data/lib/rubocop/cop/ariadne/system_argument_instead_of_class.rb +57 -0
- data/lib/rubocop/cop/ariadne.rb +3 -0
- data/lib/tasks/ariadne_view_components.rake +47 -0
- data/lib/tasks/coverage.rake +19 -0
- data/lib/tasks/custom_utilities.yml +310 -0
- data/lib/tasks/docs.rake +525 -0
- data/lib/tasks/helpers/ast_processor.rb +44 -0
- data/lib/tasks/helpers/ast_traverser.rb +77 -0
- data/lib/tasks/static.rake +15 -0
- data/lib/tasks/tailwind.rake +31 -0
- data/lib/tasks/utilities.rake +121 -0
- data/lib/yard/docs_helper.rb +83 -0
- data/lib/yard/renders_many_handler.rb +19 -0
- data/lib/yard/renders_one_handler.rb +19 -0
- data/static/arguments.yml +251 -0
- data/static/assets/view-components.svg +18 -0
- data/static/audited_at.json +14 -0
- data/static/classes.yml +89 -0
- data/static/constants.json +243 -0
- data/static/statuses.json +14 -0
- data/static/tailwindcss.yml +727 -0
- metadata +193 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Ariadne::FetchOrFallbackHelper
|
4
|
+
# A little helper to enable graceful fallbacks
|
5
|
+
#
|
6
|
+
# Use this helper to quietly ensure a value is
|
7
|
+
# one that you expect:
|
8
|
+
#
|
9
|
+
# allowed_values - allowed options for *value*
|
10
|
+
# given_value - input being coerced
|
11
|
+
# fallback - returned if *given_value* is not included in *allowed_values*
|
12
|
+
#
|
13
|
+
# fetch_or_raise([1,2,3], 5) => 2
|
14
|
+
# fetch_or_raise([1,2,3], 1) => 1
|
15
|
+
# fetch_or_raise([1,2,3], nil) => 2
|
16
|
+
module Ariadne
|
17
|
+
# :nodoc:
|
18
|
+
module IconHelper
|
19
|
+
include FetchOrFallbackHelper
|
20
|
+
|
21
|
+
def check_icon_presence!(icon, variant)
|
22
|
+
return true unless has_partial_icon?(icon, variant)
|
23
|
+
|
24
|
+
icon_presence!(icon, variant)
|
25
|
+
variant_presence!(icon, variant)
|
26
|
+
fetch_or_raise(HeroiconsHelper::Icon::VARIANTS, variant)
|
27
|
+
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_partial_icon?(icon, variant)
|
32
|
+
icon.present? || variant.present?
|
33
|
+
end
|
34
|
+
|
35
|
+
def icon_presence!(icon, variant)
|
36
|
+
raise(ArgumentError, "You must provide an `icon` when providing a `variant`.") if icon.blank? && variant.present?
|
37
|
+
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def variant_presence!(icon, variant)
|
42
|
+
raise(ArgumentError, "You must provide a `variant` when providing an `icon`.") if icon.present? && variant.blank?
|
43
|
+
|
44
|
+
true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
# :nodoc:
|
5
|
+
module JoinStyleArgumentsHelper
|
6
|
+
# Join two `style` arguments
|
7
|
+
#
|
8
|
+
# join_style_arguments("width: 100%", "height: 100%") =>
|
9
|
+
# "width: 100%;height: 100%"
|
10
|
+
def join_style_arguments(*args)
|
11
|
+
args.compact.join(";")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
# :nodoc:
|
5
|
+
module LoggerHelper
|
6
|
+
def logger
|
7
|
+
return Rails.logger if defined?(Rails) && Rails.logger
|
8
|
+
|
9
|
+
require "logger"
|
10
|
+
Logger.new($stderr)
|
11
|
+
end
|
12
|
+
|
13
|
+
# TODO: test
|
14
|
+
def silence_deprecations?
|
15
|
+
Rails.application.config.ariadne_view_components.silence_deprecations
|
16
|
+
end
|
17
|
+
|
18
|
+
# TODO: test
|
19
|
+
def silence_warnings?
|
20
|
+
Rails.application.config.ariadne_view_components.silence_warnings
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Ariadne
|
6
|
+
# :nodoc:
|
7
|
+
module Status
|
8
|
+
# DSL to allow components to register their status.
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
#
|
12
|
+
# class MyComponent < ViewComponent::Base
|
13
|
+
# include Ariadne::Status::Dsl
|
14
|
+
# status :experimental
|
15
|
+
# end
|
16
|
+
module Dsl
|
17
|
+
extend ActiveSupport::Concern
|
18
|
+
|
19
|
+
STATUSES = {
|
20
|
+
experimental: :experimental,
|
21
|
+
stable: :stable,
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
class UnknownStatusError < StandardError; end
|
25
|
+
|
26
|
+
included do
|
27
|
+
class_attribute :component_status, instance_writer: false, default: STATUSES[:stable]
|
28
|
+
end
|
29
|
+
|
30
|
+
class_methods do
|
31
|
+
def status(status = nil)
|
32
|
+
return component_status if status.nil?
|
33
|
+
|
34
|
+
raise UnknownStatusError, "status #{status} does not exist" if STATUSES[status].nil?
|
35
|
+
|
36
|
+
self.component_status = STATUSES[status]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Ariadne
|
6
|
+
# Helper to share tab validation logic between components.
|
7
|
+
# The component will raise an error if there are 0 or 2+ selected tabs.
|
8
|
+
module TabNavHelper
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
EXTRA_ALIGN_DEFAULT = :left
|
12
|
+
EXTRA_ALIGN_OPTIONS = [EXTRA_ALIGN_DEFAULT, :right].freeze
|
13
|
+
|
14
|
+
def tab_nav_tab_classes(classes)
|
15
|
+
class_names(
|
16
|
+
"tabnav-tab",
|
17
|
+
classes
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def tab_nav_classes(classes)
|
22
|
+
class_names(
|
23
|
+
"tabnav",
|
24
|
+
classes
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def tab_nav_body_classes(classes)
|
29
|
+
class_names(
|
30
|
+
"tabnav-tabs",
|
31
|
+
classes
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Ariadne
|
6
|
+
# Helper to share tab validation logic between components.
|
7
|
+
# The component will raise an error if there are 0 or 2+ selected tabs.
|
8
|
+
module TabbedComponentHelper
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
class MultipleSelectedTabsError < StandardError; end
|
12
|
+
|
13
|
+
def before_render
|
14
|
+
validate_single_selected_tab unless Rails.env.production?
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def aria_label_for_page_nav(label)
|
20
|
+
@attributes[:tag] == :nav ? @attributes[:"aria-label"] = label : @body_arguments[:"aria-label"] = label
|
21
|
+
end
|
22
|
+
|
23
|
+
def tab_container_wrapper(with_panel:, **attributes)
|
24
|
+
return yield unless with_panel
|
25
|
+
|
26
|
+
render(Ariadne::TabContainerComponent.new(**attributes)) do
|
27
|
+
yield if block_given?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def validate_single_selected_tab
|
32
|
+
raise MultipleSelectedTabsError, "only one tab can be selected" if selected_tabs_count > 1
|
33
|
+
end
|
34
|
+
|
35
|
+
def selected_tabs_count
|
36
|
+
@selected_tabs_count ||= tabs.count(&:selected)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
# Module to allow components to deal with the `test_selector` argument.
|
5
|
+
# It will only add the selector if env is not Production.
|
6
|
+
#
|
7
|
+
# test_selector: "foo" => data-test-selector="foo"
|
8
|
+
module TestSelectorHelper
|
9
|
+
TEST_SELECTOR_TAG = :test_selector
|
10
|
+
|
11
|
+
def add_test_selector(args)
|
12
|
+
if args.key?(TEST_SELECTOR_TAG)
|
13
|
+
args[:data] ||= {}
|
14
|
+
args[:data][TEST_SELECTOR_TAG] = args[TEST_SELECTOR_TAG]
|
15
|
+
end
|
16
|
+
|
17
|
+
args.except(TEST_SELECTOR_TAG)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Ariadne
|
6
|
+
# Helper to share tab validation logic between components.
|
7
|
+
# The component will raise an error if there are 0 or 2+ selected tabs.
|
8
|
+
module UnderlineNavHelper
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
ALIGN_DEFAULT = :left
|
12
|
+
ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
|
13
|
+
|
14
|
+
ACTIONS_TAG_DEFAULT = :div
|
15
|
+
ACTIONS_TAG_OPTIONS = [ACTIONS_TAG_DEFAULT, :span].freeze
|
16
|
+
|
17
|
+
def underline_nav_classes(classes, align)
|
18
|
+
class_names(
|
19
|
+
classes,
|
20
|
+
"UnderlineNav",
|
21
|
+
"UnderlineNav--right" => align == :right
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def underline_nav_body_classes(classes)
|
26
|
+
class_names(
|
27
|
+
"UnderlineNav-body",
|
28
|
+
classes,
|
29
|
+
"list-style-none"
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def underline_nav_action_classes(classes)
|
34
|
+
class_names("UnderlineNav-actions", classes)
|
35
|
+
end
|
36
|
+
|
37
|
+
def underline_nav_tab_classes(classes)
|
38
|
+
class_names(
|
39
|
+
"UnderlineNav-item",
|
40
|
+
classes
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
module Ariadne
|
5
|
+
# Module to allow shorthand calls for Ariadne components
|
6
|
+
module ViewHelper
|
7
|
+
class ViewHelperNotFound < StandardError; end
|
8
|
+
|
9
|
+
HELPERS = {
|
10
|
+
heroicon: "Ariadne::HeroiconComponent",
|
11
|
+
heading: "Ariadne::HeadingComponent",
|
12
|
+
time_ago: "Ariadne::TimeAgoComponent",
|
13
|
+
image: "Ariadne::ImageComponent",
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
HELPERS.each do |name, component|
|
17
|
+
define_method "ariadne_#{name}" do |*args, **kwargs, &block|
|
18
|
+
render component.constantize.new(*args, **kwargs), &block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
# :nodoc:
|
6
|
+
module Ariadne
|
7
|
+
class Classify
|
8
|
+
# Handler for AriadneCSS utility classes loaded from utilities.rake
|
9
|
+
class Utilities
|
10
|
+
# Load the utilities.yml file.
|
11
|
+
# Disabling because we want to load symbols, strings, and integers from the .yml file
|
12
|
+
UTILITIES = YAML.load(
|
13
|
+
File.read(
|
14
|
+
File.join(File.dirname(__FILE__), "./utilities.yml")
|
15
|
+
)
|
16
|
+
).freeze
|
17
|
+
BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"].freeze
|
18
|
+
|
19
|
+
# Replacements for some classnames that end up being a different argument key
|
20
|
+
REPLACEMENT_KEYS = {
|
21
|
+
"^anim" => "animation",
|
22
|
+
"^v-align" => "vertical_align",
|
23
|
+
"^d" => "display",
|
24
|
+
"^wb" => "word_break",
|
25
|
+
"^v" => "visibility",
|
26
|
+
"^width" => "w",
|
27
|
+
"^height" => "h",
|
28
|
+
"^color-bg" => "bg",
|
29
|
+
"^color-border" => "border_color",
|
30
|
+
"^color-fg" => "color",
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
SUPPORTED_KEY_CACHE = Hash.new { |h, k| h[k] = !UTILITIES[k].nil? }
|
34
|
+
BREAKPOINT_INDEX_CACHE = Hash.new { |h, k| h[k] = BREAKPOINTS.index(k) }
|
35
|
+
|
36
|
+
class << self
|
37
|
+
attr_accessor :validate_class_names
|
38
|
+
alias_method :validate_class_names?, :validate_class_names
|
39
|
+
|
40
|
+
def classname(key, val, breakpoint = "")
|
41
|
+
# For cases when `argument: false` is passed in, treat like we would nil
|
42
|
+
return nil unless val
|
43
|
+
|
44
|
+
if (valid = validate(key, val, breakpoint))
|
45
|
+
valid
|
46
|
+
else
|
47
|
+
# Get selector
|
48
|
+
UTILITIES[key][val][BREAKPOINT_INDEX_CACHE[breakpoint]]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Does the Utility class support the given key
|
53
|
+
#
|
54
|
+
# returns Boolean
|
55
|
+
def supported_key?(key)
|
56
|
+
SUPPORTED_KEY_CACHE[key]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Does the Utility class support the given key and value
|
60
|
+
#
|
61
|
+
# returns Boolean
|
62
|
+
def supported_value?(key, val)
|
63
|
+
supported_key?(key) && !UTILITIES[key][val].nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
# Does the given selector exist in the utilities file
|
67
|
+
#
|
68
|
+
# returns Boolean
|
69
|
+
def supported_selector?(selector)
|
70
|
+
# This method is too slow to run in production
|
71
|
+
return false unless validate_class_names?
|
72
|
+
|
73
|
+
find_selector(selector).present?
|
74
|
+
end
|
75
|
+
|
76
|
+
# Is the key and value responsive
|
77
|
+
#
|
78
|
+
# returns Boolean
|
79
|
+
def responsive?(key, val)
|
80
|
+
supported_value?(key, val) && UTILITIES[key][val].count > 1
|
81
|
+
end
|
82
|
+
|
83
|
+
# Get the options for the given key
|
84
|
+
#
|
85
|
+
# returns Array or nil if key not supported
|
86
|
+
def mappings(key)
|
87
|
+
return unless supported_key?(key)
|
88
|
+
|
89
|
+
UTILITIES[key].keys
|
90
|
+
end
|
91
|
+
|
92
|
+
# Extract hash from classes ie. "mr-1 mb-2 foo" => { mr: 1, mb: 2, classes: "foo" }
|
93
|
+
def classes_to_hash(classes)
|
94
|
+
# This method is too slow to run in production
|
95
|
+
return { classes: classes } unless validate_class_names?
|
96
|
+
|
97
|
+
obj = {}
|
98
|
+
classes = classes.split
|
99
|
+
# Loop through all classes supplied and reject ones we find a match for
|
100
|
+
# So when we're at the end of the loop we have classes left with any non-system classes.
|
101
|
+
classes.reject! do |classname|
|
102
|
+
key, value, index = find_selector(classname)
|
103
|
+
next false if key.nil?
|
104
|
+
|
105
|
+
# Create array if nil
|
106
|
+
obj[key] = Array.new(5, nil) if obj[key].nil?
|
107
|
+
# Place the arguments in the responsive array based on index mr: [nil, 2]
|
108
|
+
obj[key][index] = value
|
109
|
+
next true
|
110
|
+
end
|
111
|
+
|
112
|
+
# Transform responsive arrays into arrays without trailing nil, so `mr: [1, nil, nil, nil, nil]` becomes `mr: 1`
|
113
|
+
obj.transform_values! do |value|
|
114
|
+
value = value.reverse.drop_while(&:nil?).reverse
|
115
|
+
if value.count == 1
|
116
|
+
value.first
|
117
|
+
else
|
118
|
+
value
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Add back the non-system classes
|
123
|
+
obj[:classes] = classes.join(" ") if classes.any?
|
124
|
+
obj
|
125
|
+
end
|
126
|
+
|
127
|
+
def classes_to_args(classes)
|
128
|
+
hash_to_args(classes_to_hash(classes))
|
129
|
+
end
|
130
|
+
|
131
|
+
def hash_to_args(hash)
|
132
|
+
hash.map do |key, value|
|
133
|
+
val = case value
|
134
|
+
when Symbol
|
135
|
+
":#{value}"
|
136
|
+
when String
|
137
|
+
value.to_json
|
138
|
+
else
|
139
|
+
value
|
140
|
+
end
|
141
|
+
|
142
|
+
"#{key}: #{val}"
|
143
|
+
end.join(", ")
|
144
|
+
end
|
145
|
+
|
146
|
+
def validate(key, val, breakpoint)
|
147
|
+
unless supported_key?(key)
|
148
|
+
raise ArgumentError, "#{key} is not a valid Ariadne utility key" if validate_class_names?
|
149
|
+
|
150
|
+
return ""
|
151
|
+
end
|
152
|
+
|
153
|
+
unless breakpoint.empty? || responsive?(key, val)
|
154
|
+
raise ArgumentError, "#{key} does not support responsive values" if validate_class_names?
|
155
|
+
|
156
|
+
return ""
|
157
|
+
end
|
158
|
+
|
159
|
+
unless supported_value?(key, val)
|
160
|
+
raise ArgumentError, "#{val} is not a valid value for :#{key}. Use one of #{mappings(key)}" if validate_class_names?
|
161
|
+
|
162
|
+
return nil if [true, false].include?(val)
|
163
|
+
|
164
|
+
return "#{key.to_s.dasherize}-#{val.to_s.dasherize}"
|
165
|
+
end
|
166
|
+
|
167
|
+
nil
|
168
|
+
end
|
169
|
+
|
170
|
+
private def find_selector(selector)
|
171
|
+
key = infer_selector_key(selector)
|
172
|
+
value_hash = UTILITIES[key]
|
173
|
+
|
174
|
+
return nil if value_hash.blank?
|
175
|
+
|
176
|
+
# Each value hash will also contain an array of classnames for breakpoints
|
177
|
+
# Key argument `0`, classes `[ "mr-0", "mr-sm-0", "mr-md-0", "mr-lg-0", "mr-xl-0" ]`
|
178
|
+
value_hash.each do |key_argument, classnames|
|
179
|
+
# Skip each value hash until we get one with the selector
|
180
|
+
next unless classnames.include?(selector)
|
181
|
+
|
182
|
+
# Return [:mr, 0, 1]
|
183
|
+
# has index of classname, so we can match it up with responsive array `mr: [nil, 0]`
|
184
|
+
return [key, key_argument, classnames.index(selector)]
|
185
|
+
end
|
186
|
+
|
187
|
+
nil
|
188
|
+
end
|
189
|
+
|
190
|
+
private def infer_selector_key(selector)
|
191
|
+
REPLACEMENT_KEYS.each do |k, v|
|
192
|
+
return v.to_sym if selector.match?(Regexp.new(k))
|
193
|
+
end
|
194
|
+
selector.split("-").first.to_sym
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|