primer_view_components 0.1.8 → 0.1.9

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