primer_view_components 0.0.48 → 0.0.52
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 +4 -4
- data/CHANGELOG.md +155 -0
- data/app/components/primer/base_component.rb +2 -2
- data/app/components/primer/beta/avatar.rb +1 -1
- data/app/components/primer/{avatar_stack_component.html.erb → beta/avatar_stack.html.erb} +0 -0
- data/app/components/primer/beta/avatar_stack.rb +92 -0
- data/app/components/primer/beta/truncate.html.erb +5 -0
- data/app/components/primer/beta/truncate.rb +110 -0
- data/app/components/primer/border_box_component.rb +27 -1
- data/app/components/primer/clipboard_copy.html.erb +2 -2
- data/app/components/primer/clipboard_copy.rb +1 -1
- data/app/components/primer/dropdown.rb +7 -7
- data/app/components/primer/icon_button.rb +1 -1
- data/app/components/primer/image_crop.html.erb +4 -4
- data/app/components/primer/label_component.rb +13 -12
- data/app/components/primer/navigation/tab_component.rb +16 -2
- data/app/components/primer/progress_bar_component.rb +0 -3
- data/app/components/primer/tab_nav_component.rb +4 -3
- data/app/components/primer/truncate.rb +1 -1
- data/app/components/primer/underline_nav_component.rb +3 -2
- data/app/lib/primer/fetch_or_fallback_helper.rb +2 -0
- data/app/lib/primer/octicon/cache.rb +1 -1
- data/app/lib/primer/tabbed_component_helper.rb +1 -1
- data/app/lib/primer/view_helper.rb +1 -0
- data/lib/primer/classify.rb +4 -16
- data/lib/primer/classify/cache.rb +0 -5
- data/lib/primer/classify/flex.rb +1 -1
- data/lib/primer/classify/functional_colors.rb +1 -1
- data/lib/primer/classify/utilities.rb +51 -13
- data/lib/primer/classify/utilities.yml +16 -0
- data/lib/primer/classify/validation.rb +18 -0
- data/lib/primer/view_components.rb +34 -6
- data/lib/primer/view_components/constants.rb +55 -0
- data/lib/primer/view_components/linters/argument_mappers/base.rb +100 -0
- data/lib/primer/view_components/linters/argument_mappers/button.rb +33 -46
- data/lib/primer/view_components/linters/argument_mappers/clipboard_copy.rb +19 -0
- data/lib/primer/view_components/linters/argument_mappers/helpers/erb_block.rb +67 -0
- data/lib/primer/view_components/linters/argument_mappers/label.rb +49 -0
- data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +6 -5
- data/lib/primer/view_components/linters/autocorrectable.rb +30 -0
- data/lib/primer/view_components/linters/button_component_migration_counter.rb +9 -23
- data/lib/primer/view_components/linters/clipboard_copy_component_migration_counter.rb +21 -0
- data/lib/primer/view_components/linters/close_button_component_migration_counter.rb +16 -0
- data/lib/primer/view_components/linters/helpers.rb +47 -42
- data/lib/primer/view_components/linters/label_component_migration_counter.rb +25 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/config/default.yml +5 -0
- data/lib/rubocop/cop/primer.rb +1 -2
- data/lib/rubocop/cop/primer/deprecated_arguments.rb +173 -0
- data/lib/rubocop/cop/primer/no_tag_memoize.rb +1 -0
- data/lib/rubocop/cop/primer/primer_octicon.rb +178 -0
- data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +12 -16
- data/lib/tasks/constants.rake +12 -0
- data/lib/tasks/coverage.rake +4 -0
- data/lib/tasks/docs.rake +27 -25
- data/lib/tasks/utilities.rake +9 -13
- data/lib/yard/docs_helper.rb +15 -5
- data/static/arguments.yml +980 -0
- data/static/assets/view-components.svg +18 -0
- data/static/classes.yml +182 -0
- data/static/constants.json +640 -0
- data/static/statuses.json +4 -2
- metadata +29 -10
- data/app/components/primer/avatar_stack_component.rb +0 -90
@@ -0,0 +1,178 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
require "primer/classify/utilities"
|
5
|
+
require "primer/classify/validation"
|
6
|
+
|
7
|
+
# :nocov:
|
8
|
+
module RuboCop
|
9
|
+
module Cop
|
10
|
+
module Primer
|
11
|
+
# This cop ensures that components use System Arguments instead of CSS classes.
|
12
|
+
#
|
13
|
+
# bad
|
14
|
+
# octicon(:icon)
|
15
|
+
# octicon("icon")
|
16
|
+
# octicon("icon-with-daashes")
|
17
|
+
# octicon(@ivar)
|
18
|
+
# octicon(condition > "icon" : "other-icon")
|
19
|
+
#
|
20
|
+
# good
|
21
|
+
# primer_octicon(:icon)
|
22
|
+
# primer_octicon(:"icon-with-daashes")
|
23
|
+
# primer_octicon(@ivar)
|
24
|
+
# primer_octicon(condition > "icon" : "other-icon")
|
25
|
+
class PrimerOcticon < RuboCop::Cop::Cop
|
26
|
+
INVALID_MESSAGE = <<~STR
|
27
|
+
Replace the octicon helper with primer_octicon. See https://primer.style/view-components/components/octicon for details.
|
28
|
+
STR
|
29
|
+
|
30
|
+
SIZE_ATTRIBUTES = %w[height width size].freeze
|
31
|
+
STRING_ATTRIBUTES = %w[aria- data-].freeze
|
32
|
+
VALID_ATTRIBUTES = [*SIZE_ATTRIBUTES, *STRING_ATTRIBUTES, "class"].freeze
|
33
|
+
|
34
|
+
STRING_ATTRIBUTE_REGEX = Regexp.union(STRING_ATTRIBUTES).freeze
|
35
|
+
ATTRIBUTE_REGEX = Regexp.union(VALID_ATTRIBUTES).freeze
|
36
|
+
INVALID_ATTRIBUTE = -1
|
37
|
+
|
38
|
+
def on_send(node)
|
39
|
+
return unless node.method_name == :octicon
|
40
|
+
return unless node.arguments?
|
41
|
+
|
42
|
+
kwargs = kwargs(node)
|
43
|
+
|
44
|
+
return unless kwargs.type == :hash
|
45
|
+
|
46
|
+
attributes = kwargs.keys.map(&:value)
|
47
|
+
|
48
|
+
# Don't convert unknown attributes
|
49
|
+
return unless attributes.all? { |attribute| attribute.match?(ATTRIBUTE_REGEX) }
|
50
|
+
# Can't convert size
|
51
|
+
return if octicon_size_attributes(kwargs) == INVALID_ATTRIBUTE
|
52
|
+
|
53
|
+
# find class pair
|
54
|
+
classes = classes(kwargs)
|
55
|
+
|
56
|
+
return if classes == INVALID_ATTRIBUTE
|
57
|
+
|
58
|
+
# check if classes are convertible
|
59
|
+
if classes.present?
|
60
|
+
system_arguments = ::Primer::Classify::Utilities.classes_to_hash(classes)
|
61
|
+
invalid_classes = (system_arguments[:classes]&.split(" ") || []).select { |class_name| ::Primer::Classify::Validation.invalid?(class_name) }
|
62
|
+
|
63
|
+
# Uses system argument that can't be converted
|
64
|
+
return if invalid_classes.present?
|
65
|
+
end
|
66
|
+
|
67
|
+
add_offense(node, message: INVALID_MESSAGE)
|
68
|
+
end
|
69
|
+
|
70
|
+
def autocorrect(node)
|
71
|
+
lambda do |corrector|
|
72
|
+
kwargs = kwargs(node)
|
73
|
+
|
74
|
+
# Converting arguments for the component
|
75
|
+
classes = classes(kwargs)
|
76
|
+
size_attributes = transform_sizes(kwargs)
|
77
|
+
args = arguments_as_string(node, size_attributes, classes)
|
78
|
+
|
79
|
+
corrector.replace(node.loc.expression, "primer_octicon(#{args})")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def transform_sizes(kwargs)
|
86
|
+
attributes = octicon_size_attributes(kwargs)
|
87
|
+
|
88
|
+
attributes.transform_values do |size|
|
89
|
+
if size.between?(10, 16)
|
90
|
+
""
|
91
|
+
elsif size.between?(22, 26)
|
92
|
+
":medium"
|
93
|
+
else
|
94
|
+
size
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def octicon_size_attributes(kwargs)
|
100
|
+
kwargs.pairs.each_with_object({}) do |pair, h|
|
101
|
+
next unless SIZE_ATTRIBUTES.include?(pair.key.value.to_s)
|
102
|
+
|
103
|
+
# We only support string or int values.
|
104
|
+
case pair.value.type
|
105
|
+
when :int
|
106
|
+
h[pair.key.value] = pair.value.source.to_i
|
107
|
+
when :str
|
108
|
+
h[pair.key.value] = pair.value.value.to_i
|
109
|
+
else
|
110
|
+
return INVALID_ATTRIBUTE
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def classes(kwargs)
|
116
|
+
# find class pair
|
117
|
+
class_arg = kwargs.pairs.find { |kwarg| kwarg.key.value == :class }
|
118
|
+
|
119
|
+
return if class_arg.blank?
|
120
|
+
return INVALID_ATTRIBUTE unless class_arg.value.type == :str
|
121
|
+
|
122
|
+
class_arg.value.value
|
123
|
+
end
|
124
|
+
|
125
|
+
def arguments_as_string(node, size_attributes, classes)
|
126
|
+
args = icon(node.arguments.first)
|
127
|
+
size_args = size_attributes_to_string(size_attributes)
|
128
|
+
string_args = string_args_to_string(node)
|
129
|
+
|
130
|
+
args = "#{args}, #{size_attributes_to_string(size_attributes)}" if size_args.present?
|
131
|
+
args = "#{args}, #{::Primer::Classify::Utilities.classes_to_args(classes)}" if classes.present?
|
132
|
+
args = "#{args}, #{string_args}" if string_args.present?
|
133
|
+
|
134
|
+
args
|
135
|
+
end
|
136
|
+
|
137
|
+
def size_attributes_to_string(size_attributes)
|
138
|
+
# No arguments if they map to the default size
|
139
|
+
return if size_attributes.blank? || size_attributes.values.all?(&:blank?)
|
140
|
+
# Return mapped argument to `size`
|
141
|
+
return "size: :medium" if size_attributes.values.any?(":medium")
|
142
|
+
|
143
|
+
size_attributes.map do |key, value|
|
144
|
+
"#{key}: #{value}"
|
145
|
+
end.join(", ")
|
146
|
+
end
|
147
|
+
|
148
|
+
def string_args_to_string(node)
|
149
|
+
kwargs = kwargs(node)
|
150
|
+
|
151
|
+
args = kwargs.pairs.each_with_object([]) do |pair, acc|
|
152
|
+
next unless pair.key.value.to_s.match?(STRING_ATTRIBUTE_REGEX)
|
153
|
+
|
154
|
+
key = pair.key.value.to_s == "data-test-selector" ? "test_selector" : "\"#{pair.key.value}\""
|
155
|
+
acc << "#{key}: #{pair.value.source}"
|
156
|
+
end
|
157
|
+
|
158
|
+
args.join(",")
|
159
|
+
end
|
160
|
+
|
161
|
+
def kwargs(node)
|
162
|
+
return node.arguments.last if node.arguments.size > 1
|
163
|
+
|
164
|
+
OpenStruct.new(keys: [], pairs: [], type: :hash)
|
165
|
+
end
|
166
|
+
|
167
|
+
def icon(node)
|
168
|
+
return node.source unless node.type == :str
|
169
|
+
return ":#{node.value}" unless node.value.include?("-")
|
170
|
+
|
171
|
+
# If the icon contains `-` we need to cast the string as a symbole
|
172
|
+
# E.g: `arrow-down` becomes `:"arrow-down"`
|
173
|
+
":#{node.source}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -3,7 +3,9 @@
|
|
3
3
|
require "rubocop"
|
4
4
|
require "primer/classify/utilities"
|
5
5
|
require "primer/view_components/statuses"
|
6
|
+
require_relative "../../../../app/lib/primer/view_helper"
|
6
7
|
|
8
|
+
# :nocov:
|
7
9
|
module RuboCop
|
8
10
|
module Cop
|
9
11
|
module Primer
|
@@ -20,8 +22,7 @@ module RuboCop
|
|
20
22
|
STR
|
21
23
|
|
22
24
|
def on_send(node)
|
23
|
-
return unless node
|
24
|
-
return unless ::Primer::ViewComponents::STATUSES.key?(node.receiver.const_name)
|
25
|
+
return unless valid_node?(node)
|
25
26
|
return unless node.arguments?
|
26
27
|
|
27
28
|
# we are looking for hash arguments and they are always last
|
@@ -48,26 +49,21 @@ module RuboCop
|
|
48
49
|
|
49
50
|
def autocorrect(node)
|
50
51
|
lambda do |corrector|
|
51
|
-
|
52
|
-
corrector.replace(node.loc.expression,
|
52
|
+
args = ::Primer::Classify::Utilities.classes_to_args(node.value.value)
|
53
|
+
corrector.replace(node.loc.expression, args)
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
57
|
private
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
when String
|
64
|
-
value.to_json
|
65
|
-
else
|
66
|
-
value
|
67
|
-
end
|
59
|
+
# We only verify SystemArguments if it's a `.new` call on a component or
|
60
|
+
# a ViewHleper call.
|
61
|
+
def valid_node?(node)
|
62
|
+
view_helpers.include?(node.method_name) || (node.method_name == :new && ::Primer::ViewComponents::STATUSES.key?(node.receiver.const_name))
|
63
|
+
end
|
68
64
|
|
69
|
-
|
70
|
-
|
65
|
+
def view_helpers
|
66
|
+
::Primer::ViewHelper::HELPERS.keys.map { |key| "primer_#{key}".to_sym }
|
71
67
|
end
|
72
68
|
end
|
73
69
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :constants do
|
4
|
+
task :dump do
|
5
|
+
require File.expand_path("./../../demo/config/environment.rb", __dir__)
|
6
|
+
require "primer/view_components"
|
7
|
+
# Loads all components for `.descendants` to work properly
|
8
|
+
Dir["./app/components/primer/**/*.rb"].sort.each { |file| require file }
|
9
|
+
|
10
|
+
Primer::ViewComponents.dump_constants
|
11
|
+
end
|
12
|
+
end
|
data/lib/tasks/coverage.rake
CHANGED
@@ -9,6 +9,10 @@ namespace :coverage do
|
|
9
9
|
|
10
10
|
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], "rails" do
|
11
11
|
formatter SimpleCov::Formatter::Console
|
12
|
+
|
13
|
+
add_group "Ignored Code" do |src_file|
|
14
|
+
File.readlines(src_file.filename).grep(/:nocov:/).any?
|
15
|
+
end
|
12
16
|
end
|
13
17
|
end
|
14
18
|
end
|
data/lib/tasks/docs.rake
CHANGED
@@ -35,7 +35,7 @@ namespace :docs do
|
|
35
35
|
Primer::Beta::AutoComplete,
|
36
36
|
Primer::Beta::AutoComplete::Item,
|
37
37
|
Primer::Beta::Avatar,
|
38
|
-
Primer::
|
38
|
+
Primer::Beta::AvatarStack,
|
39
39
|
Primer::BaseButton,
|
40
40
|
Primer::BlankslateComponent,
|
41
41
|
Primer::BorderBoxComponent,
|
@@ -74,6 +74,7 @@ namespace :docs do
|
|
74
74
|
Primer::TimelineItemComponent,
|
75
75
|
Primer::Tooltip,
|
76
76
|
Primer::Truncate,
|
77
|
+
Primer::Beta::Truncate,
|
77
78
|
Primer::UnderlineNavComponent
|
78
79
|
]
|
79
80
|
|
@@ -110,6 +111,7 @@ namespace :docs do
|
|
110
111
|
File.open(path, "w") do |f|
|
111
112
|
f.puts("---")
|
112
113
|
f.puts("title: #{data[:title]}")
|
114
|
+
f.puts("componentId: #{data[:component_id]}")
|
113
115
|
f.puts("status: #{data[:status]}")
|
114
116
|
f.puts("source: #{data[:source]}")
|
115
117
|
f.puts("storybook: #{data[:storybook]}")
|
@@ -227,28 +229,17 @@ namespace :docs do
|
|
227
229
|
f.puts("## Examples")
|
228
230
|
|
229
231
|
initialize_method.tags(:example).each do |tag|
|
230
|
-
name = tag
|
231
|
-
description = nil
|
232
|
-
code = nil
|
233
|
-
|
234
|
-
if tag.text.include?("@description")
|
235
|
-
splitted = tag.text.split(/@description|@code/)
|
236
|
-
description = splitted.second.gsub(/^[ \t]{2}/, "").strip
|
237
|
-
code = splitted.last.gsub(/^[ \t]{2}/, "").strip
|
238
|
-
else
|
239
|
-
code = tag.text
|
240
|
-
end
|
241
|
-
|
232
|
+
name, description, code = parse_example_tag(tag)
|
242
233
|
f.puts
|
243
234
|
f.puts("### #{name}")
|
244
235
|
if description
|
245
236
|
f.puts
|
246
|
-
f.puts(description)
|
237
|
+
f.puts(view_context.render(inline: description.squish))
|
247
238
|
end
|
248
239
|
f.puts
|
249
240
|
html = view_context.render(inline: code)
|
250
241
|
html.scan(/class="([^"]*)"/) do |classnames|
|
251
|
-
classes_found_in_examples.concat(classnames[0].split
|
242
|
+
classes_found_in_examples.concat(classnames[0].split.reject { |c| c.starts_with?("octicon", "js", "my-") }.map { ".#{_1}" })
|
252
243
|
end
|
253
244
|
f.puts("<Example src=\"#{html.tr('"', "\'").delete("\n")}\" />")
|
254
245
|
f.puts
|
@@ -330,13 +321,14 @@ namespace :docs do
|
|
330
321
|
f.puts(" class #{short_name}Preview < ViewComponent::Preview")
|
331
322
|
|
332
323
|
yard_example_tags.each_with_index do |tag, index|
|
333
|
-
|
324
|
+
name, _, code = parse_example_tag(tag)
|
325
|
+
method_name = name.split("|").first.downcase.parameterize.underscore
|
334
326
|
f.puts(" def #{method_name}; end")
|
335
327
|
f.puts unless index == yard_example_tags.size - 1
|
336
328
|
path = Pathname.new("demo/test/components/previews/primer/docs/#{short_name.underscore}_preview/#{method_name}.html.erb")
|
337
329
|
path.dirname.mkdir unless path.dirname.exist?
|
338
330
|
File.open(path, "w") do |view_file|
|
339
|
-
view_file.puts(
|
331
|
+
view_file.puts(code.to_s)
|
340
332
|
end
|
341
333
|
end
|
342
334
|
|
@@ -374,8 +366,24 @@ namespace :docs do
|
|
374
366
|
registry
|
375
367
|
end
|
376
368
|
|
369
|
+
def parse_example_tag(tag)
|
370
|
+
name = tag.name
|
371
|
+
description = nil
|
372
|
+
code = nil
|
373
|
+
|
374
|
+
if tag.text.include?("@description")
|
375
|
+
splitted = tag.text.split(/@description|@code/)
|
376
|
+
description = splitted.second.gsub(/^[ \t]{2}/, "").strip
|
377
|
+
code = splitted.last.gsub(/^[ \t]{2}/, "").strip
|
378
|
+
else
|
379
|
+
code = tag.text
|
380
|
+
end
|
381
|
+
|
382
|
+
[name, description, code]
|
383
|
+
end
|
384
|
+
|
377
385
|
def pretty_default_value(tag, component)
|
378
|
-
params = tag.object.parameters.find { |param| [tag.name.to_s, tag.name
|
386
|
+
params = tag.object.parameters.find { |param| [tag.name.to_s, "#{tag.name}:"].include?(param[0]) }
|
379
387
|
default = tag.defaults&.first || params&.second
|
380
388
|
|
381
389
|
return "N/A" unless default
|
@@ -388,13 +396,6 @@ namespace :docs do
|
|
388
396
|
pretty_value(constant_value)
|
389
397
|
end
|
390
398
|
|
391
|
-
def status_module_and_short_name(component)
|
392
|
-
name_with_status = component.name.gsub(/Primer::|Component/, "")
|
393
|
-
|
394
|
-
m = name_with_status.match(/(?<status>Beta|Alpha|Deprecated)?(::)?(?<name>.*)/)
|
395
|
-
[m[:status]&.downcase, m[:name].gsub("::", "")]
|
396
|
-
end
|
397
|
-
|
398
399
|
def docs_metadata(component)
|
399
400
|
(status_module, short_name) = status_module_and_short_name(component)
|
400
401
|
status_path = status_module.nil? ? "" : "#{status_module}/"
|
@@ -402,6 +403,7 @@ namespace :docs do
|
|
402
403
|
|
403
404
|
{
|
404
405
|
title: short_name,
|
406
|
+
component_id: short_name.underscore,
|
405
407
|
status: status.capitalize,
|
406
408
|
source: source_url(component),
|
407
409
|
storybook: storybook_url(component),
|
data/lib/tasks/utilities.rake
CHANGED
@@ -5,30 +5,26 @@ namespace :utilities do
|
|
5
5
|
require "yaml"
|
6
6
|
require "json"
|
7
7
|
require File.expand_path("./../../demo/config/environment.rb", __dir__)
|
8
|
+
require "primer/classify/utilities"
|
8
9
|
|
9
10
|
# Keys that are looked for to be included in the utilities.yml file
|
11
|
+
# rubocop:disable Lint/ConstantDefinitionInBlock
|
10
12
|
SUPPORTED_KEYS = %i[
|
11
13
|
anim
|
12
14
|
d
|
13
15
|
float
|
16
|
+
height
|
14
17
|
hide
|
15
18
|
m mt mr mb ml mx my
|
16
19
|
p pt pr pb pl px py
|
17
20
|
position
|
18
21
|
wb
|
22
|
+
width
|
19
23
|
v
|
20
24
|
].freeze
|
21
25
|
|
22
|
-
# Replacements for some classnames that end up being a different argument key
|
23
|
-
REPLACEMENT_KEYS = {
|
24
|
-
"^anim" => "animation",
|
25
|
-
"^v-align" => "vertical_align",
|
26
|
-
"^d" => "display",
|
27
|
-
"^wb" => "word_break",
|
28
|
-
"^v" => "visibility"
|
29
|
-
}.freeze
|
30
|
-
|
31
26
|
BREAKPOINTS = [nil, "sm", "md", "lg", "xl"].freeze
|
27
|
+
# rubocop:enable Lint/ConstantDefinitionInBlock
|
32
28
|
|
33
29
|
css_data =
|
34
30
|
JSON.parse(
|
@@ -44,7 +40,7 @@ namespace :utilities do
|
|
44
40
|
css_data.each do |selector|
|
45
41
|
selector.sub!(/^./, "")
|
46
42
|
# Next if selector has ancestors or sibling selectors
|
47
|
-
next if selector.match?(/[:><~\[
|
43
|
+
next if selector.match?(/[:><~\[.]/)
|
48
44
|
next unless SUPPORTED_KEYS.any? { |key| selector.start_with?("#{key}-") }
|
49
45
|
|
50
46
|
# Dupe so we still have the selector at the end of slicing it up
|
@@ -52,11 +48,11 @@ namespace :utilities do
|
|
52
48
|
key = ""
|
53
49
|
|
54
50
|
# Look for a replacement key
|
55
|
-
REPLACEMENT_KEYS.each do |k, v|
|
51
|
+
Primer::Classify::Utilities::REPLACEMENT_KEYS.each do |k, v|
|
56
52
|
next unless classname.match?(Regexp.new(k))
|
57
53
|
|
58
54
|
key = v
|
59
|
-
classname.sub!(Regexp.new(k
|
55
|
+
classname.sub!(Regexp.new("#{k}-"), "")
|
60
56
|
end
|
61
57
|
|
62
58
|
# If we didn't find a replacement, grab the first text before hyphen
|
@@ -72,7 +68,7 @@ namespace :utilities do
|
|
72
68
|
end
|
73
69
|
|
74
70
|
# Change the rest from hypens to underscores
|
75
|
-
classname.sub!(
|
71
|
+
classname.sub!(/-/, "_")
|
76
72
|
|
77
73
|
# convert padding/margin negative values ie n7 to -7
|
78
74
|
classname.sub!(/^n/, "-") if classname.match?(/^n[0-9]/)
|