primer_view_components 0.1.8 → 0.1.9

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -0
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/assets/styles/primer_view_components.css +1 -1
  6. data/app/assets/styles/primer_view_components.css.map +1 -1
  7. data/app/components/primer/alpha/action_list/item.rb +1 -3
  8. data/app/components/primer/alpha/action_menu.rb +1 -1
  9. data/app/components/primer/alpha/modal_dialog.js +6 -0
  10. data/app/components/primer/alpha/modal_dialog.ts +6 -0
  11. data/app/components/primer/alpha/overlay/header.html.erb +5 -3
  12. data/app/components/primer/alpha/overlay/header.rb +4 -1
  13. data/app/components/primer/alpha/overlay.css +1 -1
  14. data/app/components/primer/alpha/overlay.css.json +1 -1
  15. data/app/components/primer/alpha/overlay.css.map +1 -1
  16. data/app/components/primer/alpha/overlay.pcss +1 -1
  17. data/app/components/primer/alpha/overlay.rb +1 -0
  18. data/app/components/primer/alpha/toggle_switch.css +1 -1
  19. data/app/components/primer/alpha/toggle_switch.css.json +11 -11
  20. data/app/components/primer/alpha/toggle_switch.css.map +1 -1
  21. data/app/components/primer/alpha/toggle_switch.d.ts +1 -1
  22. data/app/components/primer/alpha/toggle_switch.html.erb +2 -2
  23. data/app/components/primer/alpha/toggle_switch.js +44 -42
  24. data/app/components/primer/alpha/toggle_switch.pcss +4 -4
  25. data/app/components/primer/alpha/toggle_switch.rb +7 -0
  26. data/app/components/primer/alpha/toggle_switch.ts +50 -41
  27. data/app/components/primer/beta/auto_complete.rb +1 -1
  28. data/app/components/primer/focus_group.js +10 -6
  29. data/app/components/primer/focus_group.ts +10 -5
  30. data/lib/primer/forms/dsl/input.rb +4 -8
  31. data/lib/primer/forms/dsl/text_field_input.rb +0 -4
  32. data/lib/primer/forms/dsl/toggle_switch_input.rb +4 -0
  33. data/lib/primer/forms/form_control.html.erb +3 -5
  34. data/lib/primer/forms/primer_base_component_wrapper.html.erb +3 -0
  35. data/lib/primer/forms/primer_base_component_wrapper.rb +24 -0
  36. data/lib/primer/forms/toggle_switch.html.erb +3 -3
  37. data/lib/primer/forms/toggle_switch.rb +6 -2
  38. data/lib/primer/forms/toggle_switch_input.js +7 -2
  39. data/lib/primer/forms/toggle_switch_input.ts +9 -2
  40. data/lib/primer/static/generate_info_arch.rb +3 -0
  41. data/lib/primer/view_components/version.rb +1 -1
  42. data/lib/primer/yard/component_manifest.rb +1 -1
  43. data/lib/primer/yard/lookbook_pages_backend.rb +7 -1
  44. data/lib/primer/yard/registry.rb +4 -0
  45. data/previews/primer/alpha/overlay_preview/middle_of_page_with_relative_container.html.erb +19 -0
  46. data/previews/primer/alpha/overlay_preview.rb +31 -0
  47. data/static/arguments.json +7 -1
  48. data/static/info_arch.json +312 -1
  49. data/static/previews.json +5 -0
  50. metadata +5 -9
  51. data/lib/tasks/docs.rake +0 -185
  52. data/lib/tasks/helpers/ast_processor.rb +0 -44
  53. data/lib/tasks/helpers/ast_traverser.rb +0 -77
  54. data/lib/tasks/primer_view_components.rake +0 -47
  55. data/lib/tasks/static.rake +0 -29
  56. data/lib/tasks/test.rake +0 -83
  57. data/lib/tasks/utilities.rake +0 -109
data/static/previews.json CHANGED
@@ -1411,6 +1411,11 @@
1411
1411
  "inspect_path": "/lookbook/inspect/primer/alpha/overlay/middle_of_page",
1412
1412
  "preview_path": "/lookbook/preview/primer/alpha/overlay/middle_of_page",
1413
1413
  "name": "middle_of_page"
1414
+ },
1415
+ {
1416
+ "inspect_path": "/lookbook/inspect/primer/alpha/overlay/middle_of_page_with_relative_container",
1417
+ "preview_path": "/lookbook/preview/primer/alpha/overlay/middle_of_page_with_relative_container",
1418
+ "name": "middle_of_page_with_relative_container"
1414
1419
  }
1415
1420
  ]
1416
1421
  },
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: primer_view_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-03 00:00:00.000000000 Z
11
+ date: 2023-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -826,6 +826,8 @@ files:
826
826
  - lib/primer/forms/hidden_field.rb
827
827
  - lib/primer/forms/multi.html.erb
828
828
  - lib/primer/forms/multi.rb
829
+ - lib/primer/forms/primer_base_component_wrapper.html.erb
830
+ - lib/primer/forms/primer_base_component_wrapper.rb
829
831
  - lib/primer/forms/primer_multi_input.d.ts
830
832
  - lib/primer/forms/primer_multi_input.js
831
833
  - lib/primer/forms/primer_multi_input.ts
@@ -926,13 +928,6 @@ files:
926
928
  - lib/rubocop/cop/primer/system_argument_instead_of_class.rb
927
929
  - lib/rubocop/cop/primer/test_selector.rb
928
930
  - lib/tasks/custom_utilities.yml
929
- - lib/tasks/docs.rake
930
- - lib/tasks/helpers/ast_processor.rb
931
- - lib/tasks/helpers/ast_traverser.rb
932
- - lib/tasks/primer_view_components.rake
933
- - lib/tasks/static.rake
934
- - lib/tasks/test.rake
935
- - lib/tasks/utilities.rake
936
931
  - previews/pages/forms/01_introduction.md.erb
937
932
  - previews/pages/forms/02_getting_started.md.erb
938
933
  - previews/pages/forms/03_caption_templates.md.erb
@@ -981,6 +976,7 @@ files:
981
976
  - previews/primer/alpha/nav_list_preview/trailing_action.html.erb
982
977
  - previews/primer/alpha/overlay_preview.rb
983
978
  - previews/primer/alpha/overlay_preview/middle_of_page.html.erb
979
+ - previews/primer/alpha/overlay_preview/middle_of_page_with_relative_container.html.erb
984
980
  - previews/primer/alpha/radio_button_group_preview.rb
985
981
  - previews/primer/alpha/radio_button_preview.rb
986
982
  - previews/primer/alpha/segmented_control_preview.rb
data/lib/tasks/docs.rake DELETED
@@ -1,185 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_support/inflector"
4
-
5
- task :init_pvc do
6
- ENV["RAILS_ENV"] = "test"
7
- ENV["VC_COMPAT_PATCH_ENABLED"] = "true"
8
-
9
- require File.expand_path("./../../demo/config/environment.rb", __dir__)
10
- Dir[File.expand_path("../../app/components/primer/**/*.rb", __dir__)].sort.each { |file| require file }
11
- end
12
-
13
- namespace :docs do
14
- task :livereload do
15
- require "listen"
16
-
17
- Rake::Task["docs:build"].execute
18
-
19
- puts "Listening for changes to documentation..."
20
-
21
- listener = Listen.to("app") do |modified, added, removed|
22
- puts "modified absolute path: #{modified}"
23
- puts "added absolute path: #{added}"
24
- puts "removed absolute path: #{removed}"
25
-
26
- Rake::Task["docs:build"].execute
27
- end
28
- listener.start # not blocking
29
- sleep
30
- end
31
-
32
- task build: [:build_gatsby_pages, :build_gatsby_adrs, :build_lookbook_pages]
33
-
34
- task build_gatsby_pages: :build_yard_registry do
35
- require "primer/yard"
36
-
37
- registry = Primer::Yard::Registry.make
38
-
39
- require "primer/yard/legacy_gatsby_backend"
40
- require "primer/yard/component_manifest"
41
-
42
- puts "Converting YARD documentation to Markdown files."
43
-
44
- # Deletes docs before regenerating them, guaranteeing that we don't keep stale docs.
45
- components_content_glob = File.join(*%w[docs content components ** *.md])
46
- FileUtils.rm_rf(components_content_glob)
47
-
48
- manifest = Primer::Yard::ComponentManifest.where(published: true)
49
- backend = Primer::Yard::LegacyGatsbyBackend.new(registry, manifest)
50
- errors = backend.generate
51
-
52
- unless errors.empty?
53
- puts "==============================================="
54
- puts "===================== ERRORS =================="
55
- puts "===============================================\n\n"
56
- puts JSON.pretty_generate(errors)
57
- puts "\n\n==============================================="
58
- puts "==============================================="
59
- puts "==============================================="
60
-
61
- raise
62
- end
63
-
64
- puts "Markdown compiled."
65
-
66
- all_components = Primer::Component.descendants - [Primer::BaseComponent]
67
- components_needing_docs = all_components - Primer::Yard::ComponentManifest::COMPONENTS.keys
68
-
69
- if components_needing_docs.any?
70
- puts
71
- puts "The following components need docs. Care to contribute them? #{components_needing_docs.map(&:name).join(', ')}"
72
- end
73
- end
74
-
75
- task build_lookbook_pages: :build_yard_registry do
76
- require "primer/yard"
77
-
78
- registry = Primer::Yard::Registry.make
79
- manifest = Primer::Yard::ComponentManifest.where(form_component: true)
80
- backend = Primer::Yard::LookbookPagesBackend.new(registry, manifest)
81
- backend.generate
82
- end
83
-
84
- task :build_gatsby_adrs do
85
- adr_content_dir = File.join(*%w[docs content adr])
86
-
87
- FileUtils.rm_rf(File.join(adr_content_dir))
88
- FileUtils.mkdir(adr_content_dir)
89
-
90
- nav_entries = Dir[File.join(*%w[docs adr *.md])].sort.map do |orig_path|
91
- orig_file_name = File.basename(orig_path)
92
- url_name = orig_file_name.chomp(".md")
93
-
94
- file_contents = File.read(orig_path)
95
- file_contents = <<~CONTENTS.sub(/\n+\z/, "\n")
96
- <!-- Warning: AUTO-GENERATED file, do not edit. Make changes to the files in the adr/ directory instead. -->
97
- #{file_contents}
98
- CONTENTS
99
-
100
- title_match = /^# (.+)/.match(file_contents)
101
- title = title_match[1]
102
-
103
- # Don't include initial ADR for recording ADRs
104
- next nil if title == "Record architecture decisions"
105
-
106
- File.write(File.join(adr_content_dir, orig_file_name), file_contents)
107
- puts "Copied #{orig_path}"
108
-
109
- { "title" => title, "url" => "/adr/#{url_name}" }
110
- end
111
-
112
- nav_yaml_file = File.join(*%w[docs src @primer gatsby-theme-doctocat nav.yml])
113
- nav_yaml = YAML.load_file(nav_yaml_file)
114
- adr_entry = {
115
- "title" => "Architecture decisions",
116
- "children" => nav_entries.compact
117
- }
118
-
119
- existing_index = nav_yaml.index { |entry| entry["title"] == "Architecture decisions" }
120
- if existing_index
121
- nav_yaml[existing_index] = adr_entry
122
- else
123
- nav_yaml << adr_entry
124
- end
125
-
126
- File.write(nav_yaml_file, YAML.dump(nav_yaml))
127
- end
128
-
129
- task preview: :build_yard_registry do
130
- require "primer/yard"
131
-
132
- FileUtils.rm_rf("previews/primer/docs/")
133
-
134
- registry = Primer::Yard::Registry.make
135
-
136
- # Generate previews from documentation examples
137
- Primer::Yard::ComponentManifest.all.each do |component_ref|
138
- component = component_ref.klass
139
- docs = registry.find(component)
140
- next unless docs.constructor&.tags(:example)&.any?
141
-
142
- yard_example_tags = docs.constructor.tags(:example)
143
-
144
- path = Pathname.new("previews/docs/#{docs.short_name.underscore}_preview.rb")
145
- path.dirname.mkdir unless path.dirname.exist?
146
-
147
- File.open(path, "w") do |f|
148
- f.puts("module Docs")
149
- f.puts(" class #{docs.short_name}Preview < ViewComponent::Preview")
150
-
151
- yard_example_tags.each_with_index do |tag, index|
152
- name, _, code = Primer::Yard::LegacyGatsbyBackend.parse_example_tag(tag)
153
- method_name = name.split("|").first.downcase.parameterize.underscore
154
- f.puts(" def #{method_name}; end")
155
- f.puts unless index == yard_example_tags.size - 1
156
- path = Pathname.new("previews/docs/#{docs.short_name.underscore}_preview/#{method_name}.html.erb")
157
- path.dirname.mkdir unless path.dirname.exist?
158
- File.open(path, "w") do |view_file|
159
- view_file.puts(code.to_s)
160
- end
161
- end
162
-
163
- f.puts(" end")
164
- f.puts("end")
165
- end
166
- end
167
- end
168
-
169
- task build_yard_registry: :init_pvc do
170
- require "primer/yard"
171
-
172
- ::YARD::Rake::YardocTask.new do |task|
173
- task.options << "--no-output"
174
- end
175
-
176
- # Custom tags for yard
177
- ::YARD::Tags::Library.define_tag("Accessibility", :accessibility)
178
- ::YARD::Tags::Library.define_tag("Deprecation", :deprecation)
179
- ::YARD::Tags::Library.define_tag("Parameter", :param, :with_types_name_and_default)
180
- ::YARD::Tags::Library.define_tag("Form Usage", :form_usage)
181
-
182
- puts "Building YARD documentation."
183
- Rake::Task["yard"].execute
184
- end
185
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "ast_traverser"
4
-
5
- # :nodoc:
6
- class AstProcessor
7
- class << self
8
- def increment(stats, component, arg_name, value)
9
- stats[component][:arguments][arg_name][value] = 0 unless stats[component][:arguments][arg_name][value]
10
- stats[component][:arguments][arg_name][value] += 1
11
- end
12
-
13
- def process_ast(ast, stats)
14
- traverser = AstTraverser.new
15
- traverser.walk(ast)
16
-
17
- return if traverser.stats.empty?
18
-
19
- traverser.stats.each do |component, component_info|
20
- stats[component] ||= {
21
- paths: []
22
- }
23
-
24
- stats[component][:paths] << component_info[:path]
25
- stats[component][:paths].uniq!
26
- stats[component][:arguments] ||= {}
27
-
28
- component_info[:arguments]&.each do |arg, value|
29
- arg_name = arg.to_s
30
- stats[component][:arguments][arg_name] ||= {}
31
-
32
- # we want to count each class separately
33
- if arg_name == "classes"
34
- value.split.each do |val|
35
- increment(stats, component, arg_name, val)
36
- end
37
- else
38
- increment(stats, component, arg_name, value)
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "primer/view_components/statuses"
4
- require_relative "../../../app/lib/primer/view_helper"
5
-
6
- # :nodoc:
7
- class AstTraverser
8
- include RuboCop::AST::Traversal
9
-
10
- attr_reader :stats
11
-
12
- def initialize
13
- @stats = {}
14
- end
15
-
16
- def on_send(node)
17
- return super(node) unless component_node?(node)
18
-
19
- name = component_name(node)
20
- args = extract_arguments(node, name)
21
-
22
- @stats[name] = { path: node.loc.expression.source_buffer.name }
23
- @stats[name][:arguments] = args unless args.empty?
24
-
25
- super(node) # recursively iterate over children
26
- end
27
-
28
- def view_helpers
29
- @view_helpers ||= ::Primer::ViewHelper::HELPERS.keys.map { |key| "primer_#{key}".to_sym }
30
- end
31
-
32
- def component_node?(node)
33
- view_helpers.include?(node.method_name) || (node.method_name == :new && !node.receiver.nil? && ::Primer::ViewComponents::STATUSES.key?(node.receiver.const_name))
34
- end
35
-
36
- def component_name(node)
37
- return node.receiver.const_name if node.method_name == :new
38
-
39
- helper_key = node.method_name.to_s.gsub("primer_", "").to_sym
40
- Primer::ViewHelper::HELPERS[helper_key]
41
- end
42
-
43
- def extract_arguments(node, name)
44
- args = node.arguments
45
- res = {}
46
-
47
- return res if args.empty?
48
-
49
- kwargs = args.last
50
- if kwargs.respond_to?(:pairs)
51
- res = kwargs.pairs.each_with_object({}) do |pair, h|
52
- h.merge!(extract_values(pair))
53
- end
54
- end
55
-
56
- # Octicon is the only component that accepts positional arguments.
57
- res[:icon] = args.first.source if name == "Primer::Beta::Octicon" && args.size > 1
58
-
59
- res
60
- end
61
-
62
- def extract_values(pair)
63
- return { pair.key.value => pair.value.source } unless pair.value.type == :hash
64
-
65
- flatten_pairs(pair, prefix: "#{pair.key.value}-")
66
- end
67
-
68
- def flatten_pairs(pair, prefix: "")
69
- pair.value.pairs.each_with_object({}) do |value_pair, h|
70
- if value_pair.value.type == :hash
71
- h.merge!(flatten_pairs(value_pair, prefix: "#{prefix}#{value_pair.key.value}-"))
72
- else
73
- h.merge!("#{prefix}#{value_pair.key.value}" => value_pair.value.source)
74
- end
75
- end
76
- end
77
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ERB_GLOB = "**/*.html{+*,}.erb"
4
- RB_GLOB = "**/*.rb"
5
- BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/.freeze # copied from Rails: action_view/template/handlers/erb/erubi.rb
6
-
7
- namespace :primer_view_components do
8
- desc "Report arguments used in each component"
9
- task :report, [:paths] do |_, args|
10
- require "rubocop"
11
- require "better_html"
12
- require "better_html/parser"
13
- require "erb_lint/processed_source"
14
- require_relative "helpers/ast_processor"
15
-
16
- paths = args[:paths].split
17
- stats = {}
18
-
19
- rb_files = paths.reduce([]) { |mem, path| mem + Dir[File.join(path, RB_GLOB)] }
20
-
21
- rb_files.each do |f|
22
- ast = RuboCop::AST::ProcessedSource.from_file(f, RUBY_VERSION.to_f).ast
23
- AstProcessor.process_ast(ast, stats)
24
- end
25
-
26
- erb_files = paths.reduce([]) { |mem, path| mem + Dir[File.join(path, ERB_GLOB)] }
27
-
28
- erb_files.each do |f|
29
- erb_ast = ERBLint::ProcessedSource.new(f, File.read(f)).ast
30
-
31
- erb_ast.descendants(:erb).each do |erb_node|
32
- indicator, _, code_node, = *erb_node
33
-
34
- next if indicator&.children&.first == "#" # don't analyze comments
35
-
36
- trimmed_source = code_node.loc.source.sub(BLOCK_EXPR, "").strip
37
- ast = RuboCop::AST::ProcessedSource.new(trimmed_source, RUBY_VERSION.to_f).ast
38
- AstProcessor.process_ast(ast, stats)
39
- end
40
- end
41
-
42
- File.open(".primer-view-components-report.json", "w") do |f|
43
- f.write(JSON.pretty_generate(stats))
44
- f.write($INPUT_RECORD_SEPARATOR)
45
- end
46
- end
47
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- namespace :static do
4
- task dump: [:dump_statuses, :dump_constants, :dump_audited_at, :dump_previews, :dump_arguments, :dump_info_arch]
5
-
6
- task dump_statuses: :init_pvc do
7
- Primer::Static.dump(:statuses)
8
- end
9
-
10
- task dump_constants: :init_pvc do
11
- Primer::Static.dump(:constants)
12
- end
13
-
14
- task dump_audited_at: :init_pvc do
15
- Primer::Static.dump(:audited_at)
16
- end
17
-
18
- task dump_previews: :init_pvc do
19
- Primer::Static.dump(:previews)
20
- end
21
-
22
- task dump_arguments: ["docs:build_yard_registry", :init_pvc] do
23
- Primer::Static.dump(:arguments)
24
- end
25
-
26
- task dump_info_arch: ["docs:build_yard_registry", :dump_previews, :dump_arguments] do
27
- Primer::Static.dump(:info_arch)
28
- end
29
- end
data/lib/tasks/test.rake DELETED
@@ -1,83 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rake/testtask"
4
-
5
- namespace :test do
6
- desc "Run all tests"
7
- task all: [
8
- :components,
9
- :lib,
10
- :system,
11
- :accessibility,
12
- :performance
13
- ]
14
-
15
- Rake::TestTask.new(:single) do |t|
16
- t.warning = false
17
- t.libs << "test"
18
- t.libs << "lib"
19
- t.test_files = FileList[ENV["TEST"]]
20
- end
21
-
22
- Rake::TestTask.new(:components) do |t|
23
- t.warning = false
24
- t.libs << "test"
25
- t.test_files = FileList[
26
- "test/components/**/*_test.rb"
27
- ]
28
- end
29
-
30
- Rake::TestTask.new(:component_css) do |t|
31
- t.warning = false
32
- t.libs << "test"
33
- t.test_files = FileList[
34
- "test/css/**/*_test.rb"
35
- ]
36
- end
37
-
38
- Rake::TestTask.new(:lib) do |t|
39
- t.warning = false
40
- t.libs << "test"
41
- t.libs << "lib"
42
- t.test_files = FileList[
43
- "test/lib/**/*_test.rb"
44
- ]
45
- end
46
-
47
- Rake::TestTask.new(:system) do |t|
48
- t.warning = false
49
- t.libs << "test"
50
- t.test_files = FileList["test/system/**/*_test.rb"]
51
- end
52
-
53
- Rake::TestTask.new(:performance) do |t|
54
- t.warning = false
55
- t.verbose = true
56
- t.libs << "test"
57
- t.test_files = FileList[
58
- "test/performance/**/*_test.rb",
59
- "test/performance/**/bench_*.rb"
60
- ]
61
- end
62
-
63
- Rake::TestTask.new(:accessibility) do |t|
64
- t.warning = false
65
- t.libs << "test"
66
- t.test_files = FileList["test/accessibility_test.rb"]
67
- end
68
-
69
- task :coverage do
70
- require "simplecov"
71
-
72
- SimpleCov.minimum_coverage 100
73
- SimpleCov.collate Dir["coverage/.resultset.json"], "rails"
74
- end
75
- end
76
-
77
- task :test do
78
- if ENV["TEST"]
79
- Rake::Task["test:single"].invoke
80
- else
81
- Rake::Task["test:all"].invoke
82
- end
83
- end
@@ -1,109 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- namespace :utilities do
4
- task :build do
5
- require "yaml"
6
- require "json"
7
- ENV["RAILS_ENV"] = "test"
8
- require File.expand_path("./../../demo/config/environment.rb", __dir__)
9
- require "primer/classify/utilities"
10
-
11
- # Keys that are looked for to be included in the utilities.yml file
12
- # rubocop:disable Lint/ConstantDefinitionInBlock
13
- SUPPORTED_KEYS = [
14
- /^anim\b/,
15
- /^color-bg\b/,
16
- /^color-border\b/,
17
- /^color-fg\b/,
18
- /^col\b/,
19
- /^container\b/,
20
- /^clearfix\b/,
21
- /^d\b/,
22
- /^float\b/,
23
- /^height\b/,
24
- /^hide\b/,
25
- /^m[trblxy]?\b/,
26
- /^p[trblxy]?\b/,
27
- /^position\b/,
28
- /^wb\b/,
29
- /^width\b/,
30
- /^v\b/
31
- ].freeze
32
-
33
- BREAKPOINTS = [nil, "sm", "md", "lg", "xl"].freeze
34
- # rubocop:enable Lint/ConstantDefinitionInBlock
35
-
36
- utility_data = JSON.parse(File.read("app/lib/primer/css/utilities.css.json"))["selectors"]
37
- layout_data = JSON.parse(File.read("app/lib/primer/css/layout.css.json"))["selectors"]
38
- css_data = utility_data + layout_data
39
-
40
- output = {}
41
-
42
- css_data.each do |selector|
43
- selector.sub!(/^./, "")
44
- selector.sub!(/:[^\s]*$/, "")
45
-
46
- # Next if selector has ancestors or sibling selectors
47
- next if selector.match?(/[:><~\[.]/)
48
- next unless SUPPORTED_KEYS.any? { |key| selector =~ key }
49
-
50
- # Dupe so we still have the selector at the end of slicing it up
51
- classname = selector.dup
52
- key = ""
53
-
54
- # Look for a replacement key
55
- Primer::Classify::Utilities::REPLACEMENT_KEYS.each do |k, v|
56
- next unless classname.match?(Regexp.new(k))
57
-
58
- key = v
59
- classname.sub!(Regexp.new("#{k}-"), "")
60
- end
61
-
62
- # If we didn't find a replacement, grab the first text before hyphen
63
- if classname == selector
64
- key = classname.split("-").first
65
- classname.sub!(/^[^-]+-/, "")
66
- end
67
-
68
- # Check if the next bit of the classname is a breakpoint
69
- if classname.match?(/^(sm-|md-|lg-|xl-)/)
70
- breakpoint = classname.split("-").first
71
- classname.sub!(/^[^-]+-/, "")
72
- end
73
-
74
- # Change the rest from hyphens to underscores
75
- classname.sub!(/-/, "_")
76
-
77
- # convert padding/margin negative values ie n7 to -7
78
- classname.sub!(/^n/, "-") if classname.match?(/^n[0-9]/)
79
-
80
- # If key and classname are equal, then classname is boolean
81
- classname = true if key == classname
82
-
83
- key = key.to_sym
84
-
85
- if classname.is_a?(String)
86
- classname = classname.match?(/\A[-+]?[0-9]+\z/) ? classname.to_i : classname.to_sym
87
- end
88
-
89
- if output[key].nil?
90
- output[key] = { classname => Array.new(5, nil) }
91
- elsif output[key][classname].nil?
92
- output[key][classname] = Array.new(5, nil)
93
- end
94
-
95
- output[key][classname][BREAKPOINTS.index(breakpoint)] = selector
96
- end
97
-
98
- output.transform_values! do |x|
99
- x.transform_values { |y| y.reverse.drop_while(&:nil?).reverse }
100
- end
101
-
102
- custom_utility_data = YAML.load_file("lib/tasks/custom_utilities.yml")
103
- output.merge!(custom_utility_data)
104
-
105
- File.open("lib/primer/classify/utilities.yml", "w") do |f|
106
- f.puts YAML.dump(output)
107
- end
108
- end
109
- end