class Primer::Classify::Utilities
Handler for PrimerCSS utility classes loaded from utilities.rake
Constants
- BREAKPOINTS
rubocop:enable Security/YAMLLoad
- REPLACEMENT_KEYS
Replacements for some classnames that end up being a different argument key
- UTILITIES
Load the utilities.yml file. Disabling because we want to load symbols, strings, and integers from the .yml file rubocop:disable Security/YAMLLoad
Public Class Methods
classes_to_args(classes)
click to toggle source
# File lib/primer/classify/utilities.rb, line 117 def classes_to_args(classes) hash_to_args(classes_to_hash(classes)) end
classes_to_hash(classes)
click to toggle source
Extract hash from classes ie. “mr-1 mb-2 foo” => { mr: 1, mb: 2, classes: “foo” }
# File lib/primer/classify/utilities.rb, line 83 def classes_to_hash(classes) # This method is too slow to run in production return { classes: classes } if ENV["RAILS_ENV"] == "production" obj = {} classes = classes.split # Loop through all classes supplied and reject ones we find a match for # So when we're at the end of the loop we have classes left with any non-system classes. classes.reject! do |classname| key, value, index = find_selector(classname) next false if key.nil? # Create array if nil obj[key] = Array.new(5, nil) if obj[key].nil? # Place the arguments in the responsive array based on index mr: [nil, 2] obj[key][index] = value next true end # Transform responsive arrays into arrays without trailing nil, so `mr: [1, nil, nil, nil, nil]` becomes `mr: 1` obj.transform_values! do |value| value = value.reverse.drop_while(&:nil?).reverse if value.count == 1 value.first else value end end # Add back the non-system classes obj[:classes] = classes.join(" ") if classes.any? obj end
classname(key, val, breakpoint = "")
click to toggle source
# File lib/primer/classify/utilities.rb, line 33 def classname(key, val, breakpoint = "") if (valid = validate(key, val, breakpoint)) valid else # Get selector UTILITIES[key][val][BREAKPOINTS.index(breakpoint)] end end
hash_to_args(hash)
click to toggle source
# File lib/primer/classify/utilities.rb, line 121 def hash_to_args(hash) hash.map do |key, value| val = case value when Symbol ":#{value}" when String value.to_json else value end "#{key}: #{val}" end.join(", ") end
mappings(key)
click to toggle source
Get the options for the given key
returns Array or nil if key not supported
# File lib/primer/classify/utilities.rb, line 76 def mappings(key) return unless supported_key?(key) UTILITIES[key].keys end
responsive?(key, val)
click to toggle source
Is the key and value responsive
returns Boolean
# File lib/primer/classify/utilities.rb, line 69 def responsive?(key, val) supported_value?(key, val) && UTILITIES[key][val].count > 1 end
supported_key?(key)
click to toggle source
Does the Utilitiy class support the given key
returns Boolean
# File lib/primer/classify/utilities.rb, line 45 def supported_key?(key) UTILITIES[key].present? end
supported_selector?(selector)
click to toggle source
Does the given selector exist in the utilities file
returns Boolean
# File lib/primer/classify/utilities.rb, line 59 def supported_selector?(selector) # This method is too slow to run in production return false if ENV["RAILS_ENV"] == "production" find_selector(selector).present? end
supported_value?(key, val)
click to toggle source
Does the Utilitiy class support the given key and value
returns Boolean
# File lib/primer/classify/utilities.rb, line 52 def supported_value?(key, val) supported_key?(key) && UTILITIES[key][val].present? end
Private Class Methods
find_selector(selector)
click to toggle source
# File lib/primer/classify/utilities.rb, line 138 def find_selector(selector) key = infer_selector_key(selector) value_hash = UTILITIES[key] return nil if value_hash.blank? # Each value hash will also contain an array of classnames for breakpoints # Key argument `0`, classes `[ "mr-0", "mr-sm-0", "mr-md-0", "mr-lg-0", "mr-xl-0" ]` value_hash.each do |key_argument, classnames| # Skip each value hash until we get one with the selector next unless classnames.include?(selector) # Return [:mr, 0, 1] # has index of classname, so we can match it up with responsvie array `mr: [nil, 0]` return [key, key_argument, classnames.index(selector)] end nil end
infer_selector_key(selector)
click to toggle source
# File lib/primer/classify/utilities.rb, line 158 def infer_selector_key(selector) REPLACEMENT_KEYS.each do |k, v| return v.to_sym if selector.match?(Regexp.new(k)) end selector.split("-").first.to_sym end
validate(key, val, breakpoint)
click to toggle source
# File lib/primer/classify/utilities.rb, line 166 def validate(key, val, breakpoint) unless supported_key?(key) raise ArgumentError, "#{key} is not a valid Primer utility key" unless ENV["RAILS_ENV"] == "production" return "" end unless breakpoint.empty? || responsive?(key, val) raise ArgumentError, "#{key} does not support responsive values" unless ENV["RAILS_ENV"] == "production" return "" end unless supported_value?(key, val) raise ArgumentError, "#{val} is not a valid value for :#{key}. Use one of #{mappings(key)}" unless ENV["RAILS_ENV"] == "production" return "#{key.to_s.dasherize}-#{val.to_s.dasherize}" end nil end