tailwindcss-rails 0.3.0 → 0.4.1
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/README.md +17 -10
- data/app/assets/stylesheets/tailwind.css +172198 -158668
- data/lib/install/{tailwindcss_with_asset_pipeline.rb → tailwindcss.rb} +3 -0
- data/lib/tailwindcss/engine.rb +4 -0
- data/lib/tailwindcss/purger.rb +94 -34
- data/lib/tailwindcss/version.rb +1 -1
- data/lib/tasks/tailwindcss_tasks.rake +2 -21
- metadata +8 -10
- data/lib/install/stylesheets/application.scss +0 -3
- data/lib/install/tailwindcss_with_webpacker.rb +0 -24
@@ -8,5 +8,8 @@ else
|
|
8
8
|
say %( Add <%= stylesheet_link_tag "inter-font" %> and <%= stylesheet_link_tag "tailwind" %> within the <head> tag in your custom layout.)
|
9
9
|
end
|
10
10
|
|
11
|
+
say "Removing scaffold styles"
|
12
|
+
remove_file Rails.root.join("app/assets/stylesheets/scaffolds.scss")
|
13
|
+
|
11
14
|
say "Turn on purging of unused css classes in production"
|
12
15
|
gsub_file Rails.root.join("config/environments/production.rb"), /^\s+#?\s+config.assets.css_compressor =.*$/, %( config.assets.css_compressor = :purger)
|
data/lib/tailwindcss/engine.rb
CHANGED
@@ -10,6 +10,10 @@ module Tailwindcss
|
|
10
10
|
Rails.application.config.assets.precompile += %w( tailwind.css inter-font.css )
|
11
11
|
end
|
12
12
|
|
13
|
+
initializer "tailwindcss.disable_generator_stylesheets" do
|
14
|
+
Rails.application.config.generators.stylesheets = false
|
15
|
+
end
|
16
|
+
|
13
17
|
initializer "tailwindcss.disable_assets_cache" do
|
14
18
|
Rails.application.config.assets.configure do |env|
|
15
19
|
env.cache = ActiveSupport::Cache.lookup_store(:null_store)
|
data/lib/tailwindcss/purger.rb
CHANGED
@@ -1,8 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Tailwindcss::Purger
|
2
|
-
CLASS_NAME_PATTERN
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
CLASS_NAME_PATTERN = /[:A-Za-z0-9_-]+[\.]*[\\\/:A-Za-z0-9_-]*/
|
5
|
+
|
6
|
+
CLASS_BREAK = /(?![-_a-z0-9\\])/i # `\b` for class selectors
|
7
|
+
|
8
|
+
COMMENT = /#{Regexp.escape "/*"}.*?#{Regexp.escape "*/"}/m
|
9
|
+
COMMENTS_AND_BLANK_LINES = /\A(?:^#{COMMENT}?[ \t]*(?:\n|\z)|[ \t]*#{COMMENT})+/
|
10
|
+
|
11
|
+
AT_RULE = /@[^{]+/
|
12
|
+
CLASSLESS_SELECTOR_GROUP = /[^.{]+/
|
13
|
+
CLASSLESS_BEGINNING_OF_BLOCK = /\A\s*(?:#{AT_RULE}|#{CLASSLESS_SELECTOR_GROUP})\{\n?/
|
14
|
+
|
15
|
+
SELECTOR_GROUP = /[^{]+/
|
16
|
+
BEGINNING_OF_BLOCK = /\A#{SELECTOR_GROUP}\{\n?/
|
17
|
+
|
18
|
+
PROPERTY_NAME = /[-_a-z0-9]+/i
|
19
|
+
PROPERTY_VALUE = /(?:[^;]|;\S)+/
|
20
|
+
PROPERTIES = /\A(?:\s*#{PROPERTY_NAME}:#{PROPERTY_VALUE};\n?)+/
|
21
|
+
|
22
|
+
END_OF_BLOCK = /\A\s*\}\n?/
|
6
23
|
|
7
24
|
attr_reader :keep_these_class_names
|
8
25
|
|
@@ -12,11 +29,15 @@ class Tailwindcss::Purger
|
|
12
29
|
end
|
13
30
|
|
14
31
|
def extract_class_names(string)
|
15
|
-
string.scan(CLASS_NAME_PATTERN).
|
32
|
+
string.scan(CLASS_NAME_PATTERN).uniq.sort!
|
16
33
|
end
|
17
34
|
|
18
35
|
def extract_class_names_from(files)
|
19
|
-
Array(files).flat_map { |file| extract_class_names(file.read) }.uniq.sort
|
36
|
+
Array(files).flat_map { |file| extract_class_names(file.read) }.uniq.sort!
|
37
|
+
end
|
38
|
+
|
39
|
+
def escape_class_selector(class_name)
|
40
|
+
class_name.gsub(/\A\d|[^-_a-z0-9]/, '\\\\\0')
|
20
41
|
end
|
21
42
|
end
|
22
43
|
|
@@ -25,40 +46,79 @@ class Tailwindcss::Purger
|
|
25
46
|
end
|
26
47
|
|
27
48
|
def purge(input)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
inside_ignored_selector = false if line =~ CLOSING_SELECTOR_PATTERN
|
38
|
-
when line =~ OPENING_SELECTOR_PATTERN
|
39
|
-
if keep_these_class_names.include? class_name_in(line)
|
40
|
-
output << line
|
41
|
-
inside_kept_selector = true
|
42
|
-
else
|
43
|
-
inside_ignored_selector = true
|
44
|
-
end
|
45
|
-
else
|
46
|
-
output << line
|
47
|
-
end
|
49
|
+
conveyor = Conveyor.new(input)
|
50
|
+
|
51
|
+
until conveyor.done?
|
52
|
+
conveyor.discard(COMMENTS_AND_BLANK_LINES) \
|
53
|
+
or conveyor.conditionally_keep(PROPERTIES) { conveyor.staged_output.last != "" } \
|
54
|
+
or conveyor.conditionally_keep(END_OF_BLOCK) { not conveyor.staged_output.pop } \
|
55
|
+
or conveyor.stage_output(CLASSLESS_BEGINNING_OF_BLOCK) \
|
56
|
+
or conveyor.stage_output(BEGINNING_OF_BLOCK) { |match| purge_beginning_of_block(match.to_s) } \
|
57
|
+
or raise "infinite loop"
|
48
58
|
end
|
49
59
|
|
50
|
-
|
60
|
+
conveyor.output
|
51
61
|
end
|
52
62
|
|
53
63
|
private
|
54
|
-
def
|
55
|
-
|
56
|
-
.
|
57
|
-
.
|
58
|
-
|
64
|
+
def keep_these_selectors_pattern
|
65
|
+
@keep_these_selectors_pattern ||= begin
|
66
|
+
escaped_classes = @keep_these_class_names.map { |name| Regexp.escape self.class.escape_class_selector(name) }
|
67
|
+
/(?:\A|,)[^.,{]*(?:[.](?:#{escaped_classes.join("|")})#{CLASS_BREAK}[^.,{]*)*(?=[,{])/
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def purge_beginning_of_block(string)
|
72
|
+
purged = string.scan(keep_these_selectors_pattern).join
|
73
|
+
unless purged.empty?
|
74
|
+
purged.sub!(/\A,\s*/, "")
|
75
|
+
purged.rstrip!
|
76
|
+
purged << " {\n"
|
77
|
+
end
|
78
|
+
purged
|
59
79
|
end
|
60
80
|
|
61
|
-
|
62
|
-
output
|
81
|
+
class Conveyor
|
82
|
+
attr_reader :output, :staged_output
|
83
|
+
|
84
|
+
def initialize(input, output = +"")
|
85
|
+
@input = input
|
86
|
+
@output = output
|
87
|
+
@staged_output = []
|
88
|
+
end
|
89
|
+
|
90
|
+
def consume(pattern)
|
91
|
+
match = pattern.match(@input)
|
92
|
+
@input = match.post_match if match
|
93
|
+
match
|
94
|
+
end
|
95
|
+
alias :discard :consume
|
96
|
+
|
97
|
+
def stage_output(pattern)
|
98
|
+
if match = consume(pattern)
|
99
|
+
string = block_given? ? (yield match) : match.to_s
|
100
|
+
@staged_output << string
|
101
|
+
string
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def keep(pattern)
|
106
|
+
if match = consume(pattern)
|
107
|
+
string = block_given? ? (yield match) : match.to_s
|
108
|
+
@output << @staged_output.shift until @staged_output.empty?
|
109
|
+
@output << string
|
110
|
+
string
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def conditionally_keep(pattern)
|
115
|
+
keep(pattern) do |match|
|
116
|
+
(yield match) ? match.to_s : (break "")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def done?
|
121
|
+
@input.empty?
|
122
|
+
end
|
63
123
|
end
|
64
124
|
end
|
data/lib/tailwindcss/version.rb
CHANGED
@@ -1,23 +1,7 @@
|
|
1
1
|
namespace :tailwindcss do
|
2
2
|
desc "Install Tailwind CSS into the app"
|
3
3
|
task :install do
|
4
|
-
|
5
|
-
Rake::Task["tailwindcss:install:webpacker"].invoke
|
6
|
-
else
|
7
|
-
Rake::Task["tailwindcss:install:asset_pipeline"].invoke
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
namespace :install do
|
12
|
-
desc "Install Tailwind CSS with the asset pipeline"
|
13
|
-
task :asset_pipeline do
|
14
|
-
run_install_template "tailwindcss_with_asset_pipeline"
|
15
|
-
end
|
16
|
-
|
17
|
-
desc "Install Tailwind CSS with webpacker"
|
18
|
-
task :webpacker do
|
19
|
-
run_install_template "tailwindcss_with_webpacker"
|
20
|
-
end
|
4
|
+
system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/tailwindcss.rb", __dir__)}"
|
21
5
|
end
|
22
6
|
|
23
7
|
desc "Show the list of class names being kept in Tailwind CSS"
|
@@ -31,10 +15,6 @@ namespace :tailwindcss do
|
|
31
15
|
end
|
32
16
|
end
|
33
17
|
|
34
|
-
def run_install_template(path)
|
35
|
-
system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/#{path}.rb", __dir__)}"
|
36
|
-
end
|
37
|
-
|
38
18
|
def default_files_with_class_names
|
39
19
|
Rails.root.glob("app/views/**/*.*") + Rails.root.glob("app/helpers/**/*.rb")
|
40
20
|
end
|
@@ -42,3 +22,4 @@ end
|
|
42
22
|
def tailwind_css
|
43
23
|
Pathname.new(__FILE__).join("../../../app/assets/stylesheets/tailwind.css").read
|
44
24
|
end
|
25
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tailwindcss-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 6.0.0
|
27
|
-
description:
|
27
|
+
description:
|
28
28
|
email: david@loudthinking.com
|
29
29
|
executables: []
|
30
30
|
extensions: []
|
@@ -51,9 +51,7 @@ files:
|
|
51
51
|
- app/assets/fonts/Inter-roman.vietnamese.var.woff2
|
52
52
|
- app/assets/stylesheets/inter-font.css.erb
|
53
53
|
- app/assets/stylesheets/tailwind.css
|
54
|
-
- lib/install/
|
55
|
-
- lib/install/tailwindcss_with_asset_pipeline.rb
|
56
|
-
- lib/install/tailwindcss_with_webpacker.rb
|
54
|
+
- lib/install/tailwindcss.rb
|
57
55
|
- lib/tailwindcss-rails.rb
|
58
56
|
- lib/tailwindcss/compressor.rb
|
59
57
|
- lib/tailwindcss/engine.rb
|
@@ -65,7 +63,7 @@ licenses:
|
|
65
63
|
- MIT
|
66
64
|
metadata:
|
67
65
|
homepage_uri: https://github.com/rails/tailwindcss-rails
|
68
|
-
post_install_message:
|
66
|
+
post_install_message:
|
69
67
|
rdoc_options: []
|
70
68
|
require_paths:
|
71
69
|
- lib
|
@@ -80,8 +78,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
78
|
- !ruby/object:Gem::Version
|
81
79
|
version: '0'
|
82
80
|
requirements: []
|
83
|
-
rubygems_version: 3.1.
|
84
|
-
signing_key:
|
81
|
+
rubygems_version: 3.1.4
|
82
|
+
signing_key:
|
85
83
|
specification_version: 4
|
86
84
|
summary: Integrate Tailwind CSS with the asset pipeline in Rails.
|
87
85
|
test_files: []
|
@@ -1,24 +0,0 @@
|
|
1
|
-
LATEST_WEBPACKER = "\"@rails\/webpacker\": \"rails\/webpacker#b6c2180\","
|
2
|
-
WEBPACK_STYLESHEETS_PATH = "#{Webpacker.config.source_path}/stylesheets"
|
3
|
-
APPLICATION_LAYOUT_PATH = Rails.root.join("app/views/layouts/application.html.erb")
|
4
|
-
|
5
|
-
# Current webpacker version relies on an older version of PostCSS
|
6
|
-
# which the latest TailwindCSS version is not compatible with
|
7
|
-
gsub_file("package.json", /\"@rails\/webpacker\".*/) { |matched_line| matched_line = LATEST_WEBPACKER }
|
8
|
-
|
9
|
-
say "Adding latest Tailwind CSS and postCSS"
|
10
|
-
run "yarn add tailwindcss@latest postcss@latest autoprefixer@latest"
|
11
|
-
insert_into_file "#{Webpacker.config.source_entry_path}/application.js", "\nrequire(\"stylesheets/application.scss\")\n"
|
12
|
-
|
13
|
-
say "Adding minimal configuration for Tailwind CSS to work properly"
|
14
|
-
directory Pathname.new(__dir__).join("stylesheets"), Webpacker.config.source_path.join("stylesheets")
|
15
|
-
|
16
|
-
insert_into_file "postcss.config.js", "require('tailwindcss'),\n\t", before: "require('postcss-import')"
|
17
|
-
|
18
|
-
if APPLICATION_LAYOUT_PATH.exist?
|
19
|
-
say "Add Tailwindcss include tags in application layout"
|
20
|
-
insert_into_file Rails.root.join("app/views/layouts/application.html.erb").to_s, %(\n <%= stylesheet_pack_tag "application", "data-turbo-track": "reload" %>), before: /\s*<\/head>/
|
21
|
-
else
|
22
|
-
say "Default application.html.erb is missing!", :red
|
23
|
-
say %( Add <%= stylesheet_pack_tag "application", "data-turbo-track": "reload" %> within the <head> tag in your custom layout.)
|
24
|
-
end
|