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