tailwindcss-rails 1.0.0 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -48
- data/app/assets/stylesheets/{inter-font.css.erb → inter-font.css} +19 -19
- data/lib/install/Procfile.dev +2 -0
- data/lib/install/application.tailwind.css +13 -0
- data/lib/install/dev +9 -0
- data/lib/install/tailwind.config.js +22 -0
- data/lib/install/tailwindcss.rb +38 -8
- data/lib/tailwindcss/engine.rb +1 -12
- data/lib/tailwindcss/version.rb +1 -1
- data/lib/tasks/build.rake +20 -0
- data/lib/tasks/clobber.rake +8 -0
- data/lib/tasks/install.rake +6 -0
- metadata +13 -9
- data/lib/tailwindcss/compressor.rb +0 -33
- data/lib/tailwindcss/purger.rb +0 -124
- data/lib/tasks/tailwindcss_tasks.rake +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d22f4bc34ab3304b899f7d195dcbeb00feeb81fde432467f7c2d27e04ab8a543
|
4
|
+
data.tar.gz: 86c44ee8942497bc4e3bb13b21b4ae9083ccdeee0564a0072bd6bcd9b5e60a34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4c956629e2327712f54111be1388c701a357c435ceabf65bac7a3ceddf0d04ca0d570f517fb65315d3635162c8c1036218e1b54712b82cbb586a53606edca58
|
7
|
+
data.tar.gz: 88ef347089d11ac3edb5d04d121898eaee279aafb627db1cac290cd527e68bc1249d74578c9b525ffe0f277c64eb50fea9d0a49eb67ef5d765ccb75b74922636
|
data/README.md
CHANGED
@@ -2,65 +2,28 @@
|
|
2
2
|
|
3
3
|
[Tailwind CSS](https://tailwindcss.com) is a utility-first CSS framework packed with classes like flex, pt-4, text-center and rotate-90 that can be composed to build any design, directly in your markup.
|
4
4
|
|
5
|
-
This gem
|
5
|
+
This gem wraps [the standalone executable version](https://tailwindcss.com/blog/standalone-cli) of the Tailwind CSS 3 framework. These executables are platform specific, but so there's actually separate underlying gems per platform, but the correct gem will automatically be picked for your platform. Supported platforms are Linux x64, macOS arm64, macOS x64, and Windows x64. (Note that due to this setup, you must install the actual gems – you can't pin your gem to the github repo.)
|
6
6
|
|
7
|
-
|
7
|
+
You can customize the Tailwind build through the `config/tailwind.config.js` file, just like you would if Tailwind was running in a traditional node installation. All the first-party plugins are supported.
|
8
8
|
|
9
|
-
|
9
|
+
The installer will create your Tailwind input file in `app/assets/stylesheets/application.tailwind.css`. This is where you import the plugins you want to use, and where you can setup your custom `@apply` rules. When you run `rails tailwindcss:build`, this input file will be used to generate the output in `app/assets/builds/tailwind.css`. That's the output CSS that you'll include in your app (the installer automatically configures this, alongside the Inter font as well).
|
10
10
|
|
11
|
+
If you need to use a custom input or output file, you can run `bundle exec tailwindcss` to access the platform-specific executable, and give it your own build options.
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
1. Run `./bin/bundle add tailwindcss-rails`
|
15
|
-
2. Run `./bin/rails tailwindcss:install`
|
16
|
-
|
17
|
-
The last step adds the purger compressor to `config/environments/production.rb`. This ensures that when `assets:precompile` is called during deployment that the unused class names are not included in the tailwind output css used by the app. It also adds a `stylesheet_link_tag "tailwind"` and `stylesheet_link_tag "inter-font"` to your `app/views/layouts/application.html.erb` file.
|
18
|
-
|
19
|
-
You can do these things yourself, if you've changed the default setup.
|
20
|
-
|
21
|
-
|
22
|
-
## Purging in production
|
23
|
-
|
24
|
-
The Tailwind CSS framework starts out as a massive file, which gives you all the combinations of utility classes for development, but you wouldn't want to ship all those unused classes in production. So the Sprockets compressor included in this gem is used to purge the tailwind file from all those unused classes for production.
|
25
|
-
|
26
|
-
Note: This compressor is currently not compatible with the default Sprockets cache system due to the fact its output depends on files outside of Sprockets (all the files observed for utility class name usage), so this cache is disabled in production. If you need to disable it in other deployed environments, add the following to that environment configuration file:
|
13
|
+
When you're developing your application, you want to run Tailwind in watch mode, so changes are automatically reflected in the generated CSS output. You can do this either by running `rails tailwindcss:watch` as a separate process, or by running `./bin/dev` which uses [foreman](https://github.com/ddollar/foreman) to starts both the Tailwind watch process and the rails server in development mode.
|
27
14
|
|
28
|
-
```ruby
|
29
|
-
Rails.application.config.assets.configure do |env|
|
30
|
-
env.cache = ActiveSupport::Cache.lookup_store(:null_store)
|
31
|
-
end
|
32
|
-
```
|
33
15
|
|
16
|
+
## Installation
|
34
17
|
|
35
|
-
|
36
|
-
|
37
|
-
If you need to customize what files are searched for class names when using the asset pipeline, you need to replace the compressor line with something like:
|
38
|
-
|
39
|
-
```ruby
|
40
|
-
config.assets.css_compressor = Tailwindcss::Compressor.new(files_with_class_names: Rails.root.glob("app/somewhere/**/*.*"))
|
41
|
-
```
|
42
|
-
|
43
|
-
By default, the CSS purger will only operate on the tailwind css file included with this gem. If you want to use it more broadly:
|
44
|
-
|
45
|
-
```ruby
|
46
|
-
config.assets.css_compressor = Tailwindcss::Compressor.new(only_purge: %w[ tailwind and_my_other_css_file ])
|
47
|
-
```
|
48
|
-
|
49
|
-
|
50
|
-
## Tailwind versions
|
51
|
-
|
52
|
-
The Tailwind CSS main file that's being used before purging consists of these versions:
|
18
|
+
With Rails 7 you can generate a new application preconfigured with Tailwind by using `--css tailwind`. If you're adding Tailwind later, you need to:
|
53
19
|
|
54
|
-
|
55
|
-
|
56
|
-
* @tailwindcss/typography 0.4.1
|
57
|
-
* autoprefixer 10.3.1
|
58
|
-
* tailwindcss 2.2.15
|
20
|
+
1. Run `./bin/bundle add tailwindcss-rails`
|
21
|
+
2. Run `./bin/rails tailwindcss:install`
|
59
22
|
|
60
23
|
|
61
|
-
##
|
24
|
+
## Building in production
|
62
25
|
|
63
|
-
|
26
|
+
The `tailwindcss:build` is automatically attached to `assets:precompile`, so before the asset pipeline digests the files, the Tailwind output will be generated.
|
64
27
|
|
65
28
|
|
66
29
|
## Conflict with sassc-rails
|
@@ -7,7 +7,7 @@
|
|
7
7
|
font-style: italic;
|
8
8
|
font-weight: 100 900;
|
9
9
|
font-display: swap;
|
10
|
-
src: url('
|
10
|
+
src: url('Inter-italic.extra.var.woff2') format('woff2');
|
11
11
|
unicode-range: U+E000,U+E002-E081,U+E093-E097,U+E0A5-E0E7,U+E0F3-E11D,U+E11E-E165,U+EE01,U+F6C3;
|
12
12
|
font-named-instance: 'Italic';
|
13
13
|
}
|
@@ -17,7 +17,7 @@
|
|
17
17
|
font-style: italic;
|
18
18
|
font-weight: 100 900;
|
19
19
|
font-display: swap;
|
20
|
-
src: url('
|
20
|
+
src: url('Inter-italic.alternates.var.woff2') format('woff2');
|
21
21
|
unicode-range: U+E000,U+E002-E081,U+E093-E097,U+E0A5-E0E7,U+E0F3-E11D,U+E11E-E165,U+EE01,U+F6C3;
|
22
22
|
font-named-instance: 'Italic';
|
23
23
|
}
|
@@ -27,7 +27,7 @@
|
|
27
27
|
font-style: italic;
|
28
28
|
font-weight: 100 900;
|
29
29
|
font-display: swap;
|
30
|
-
src: url('
|
30
|
+
src: url('Inter-italic.symbols.var.woff2') format('woff2');
|
31
31
|
unicode-range: U+20DD-20DF,U+2190-219A,U+21A9-21AB,U+21B0-21B2,U+21B3-21B6,U+21BA-21BC,U+21D0,U+21D2,U+21D4,U+21DE-21E0,U+21E4-21E6,U+21E7,U+21EA,U+2303,U+2305,U+2318,U+2325-2328,U+232B,U+2380,U+2387,U+238B,U+23CE-23D0,U+2460-2469,U+24B6-24D0,U+24EA,U+25A0-25A3,U+25B2-25B4,U+25B6-25B8,U+25BA-25BE,U+25C0-25C2,U+25C4-25C8,U+25CB,U+25CF,U+25EF,U+2600,U+2605-2607,U+263C,U+2661,U+2665,U+26A0,U+2713,U+2717,U+2756,U+2764,U+2780-2789,U+27F5-27FB,U+2B06,U+2B12-2B14,U+2B1C,U+E000,U+E12B-E164,U+1F130-1F14A,U+1F850,U+1F852;
|
32
32
|
font-named-instance: 'Italic';
|
33
33
|
}
|
@@ -38,7 +38,7 @@
|
|
38
38
|
font-style: italic;
|
39
39
|
font-weight: 100 900;
|
40
40
|
font-display: swap;
|
41
|
-
src: url('
|
41
|
+
src: url('Inter-italic.extra.var.woff2') format('woff2');
|
42
42
|
unicode-range: U+E000,U+E002-E081,U+E093-E097,U+E0A5-E0E7,U+E0F3-E11D,U+E11E-E165,U+EE01,U+F6C3;
|
43
43
|
font-named-instance: 'Italic';
|
44
44
|
}
|
@@ -48,7 +48,7 @@
|
|
48
48
|
font-style: italic;
|
49
49
|
font-weight: 100 900;
|
50
50
|
font-display: swap;
|
51
|
-
src: url('
|
51
|
+
src: url('Inter-italic.alternates.var.woff2') format('woff2');
|
52
52
|
unicode-range: U+E000,U+E002-E081,U+E093-E097,U+E0A5-E0E7,U+E0F3-E11D,U+E11E-E165,U+EE01,U+F6C3;
|
53
53
|
font-named-instance: 'Italic';
|
54
54
|
}
|
@@ -58,7 +58,7 @@
|
|
58
58
|
font-style: italic;
|
59
59
|
font-weight: 100 900;
|
60
60
|
font-display: swap;
|
61
|
-
src: url('
|
61
|
+
src: url('Inter-italic.symbols.var.woff2') format('woff2');
|
62
62
|
unicode-range: U+20DD-20DF,U+2190-219A,U+21A9-21AB,U+21B0-21B2,U+21B3-21B6,U+21BA-21BC,U+21D0,U+21D2,U+21D4,U+21DE-21E0,U+21E4-21E6,U+21E7,U+21EA,U+2303,U+2305,U+2318,U+2325-2328,U+232B,U+2380,U+2387,U+238B,U+23CE-23D0,U+2460-2469,U+24B6-24D0,U+24EA,U+25A0-25A3,U+25B2-25B4,U+25B6-25B8,U+25BA-25BE,U+25C0-25C2,U+25C4-25C8,U+25CB,U+25CF,U+25EF,U+2600,U+2605-2607,U+263C,U+2661,U+2665,U+26A0,U+2713,U+2717,U+2756,U+2764,U+2780-2789,U+27F5-27FB,U+2B06,U+2B12-2B14,U+2B1C,U+E000,U+E12B-E164,U+1F130-1F14A,U+1F850,U+1F852;
|
63
63
|
font-named-instance: 'Italic';
|
64
64
|
}
|
@@ -68,7 +68,7 @@
|
|
68
68
|
font-style: italic;
|
69
69
|
font-weight: 100 900;
|
70
70
|
font-display: swap;
|
71
|
-
src: url('
|
71
|
+
src: url('Inter-italic.cyrillic.var.woff2') format('woff2');
|
72
72
|
unicode-range: U+0400-049E,U+04A0-0500,U+052F,U+20B4,U+2116,U+2DFF,U+A69F;
|
73
73
|
font-named-instance: 'Italic';
|
74
74
|
}
|
@@ -78,7 +78,7 @@
|
|
78
78
|
font-style: italic;
|
79
79
|
font-weight: 100 900;
|
80
80
|
font-display: swap;
|
81
|
-
src: url('
|
81
|
+
src: url('Inter-italic.greek.var.woff2') format('woff2');
|
82
82
|
unicode-range: U+0370-0378,U+037A-0380,U+0384-038B,U+038C,U+038E-03A2,U+03A3-03E2,U+03F0-0400,U+1F00-1F16,U+1F18-1F1E,U+1F20-1F46,U+1F48-1F4E,U+1F50-1F58,U+1F59,U+1F5B,U+1F5D,U+1F5F-1F7E,U+1F80-1FB5,U+1FB6-1FC5,U+1FC6-1FD4,U+1FD6-1FDC,U+1FDD-1FF0,U+1FF2-1FF5,U+1FF6-1FFF;
|
83
83
|
font-named-instance: 'Italic';
|
84
84
|
}
|
@@ -88,7 +88,7 @@
|
|
88
88
|
font-style: italic;
|
89
89
|
font-weight: 100 900;
|
90
90
|
font-display: swap;
|
91
|
-
src: url('
|
91
|
+
src: url('Inter-italic.vietnamese.var.woff2') format('woff2');
|
92
92
|
unicode-range: U+0102-0104,U+0110-0112,U+0128-012A,U+0168-016A,U+01A0-01A2,U+01AF-01B1,U+1EA0-1EFA,U+20AB;
|
93
93
|
font-named-instance: 'Italic';
|
94
94
|
}
|
@@ -98,7 +98,7 @@
|
|
98
98
|
font-style: italic;
|
99
99
|
font-weight: 100 900;
|
100
100
|
font-display: swap;
|
101
|
-
src: url('
|
101
|
+
src: url('Inter-italic.latin-ext.var.woff2') format('woff2');
|
102
102
|
unicode-range: U+0100-0149,U+014A-01C4,U+01C5-0250,U+0259,U+1E00-1F00,U+2020,U+20A0-20AC,U+20AD-20C0,U+2113,U+2C7C,U+2C7F,U+A7FF;
|
103
103
|
font-named-instance: 'Italic';
|
104
104
|
}
|
@@ -108,7 +108,7 @@
|
|
108
108
|
font-style: italic;
|
109
109
|
font-weight: 100 900;
|
110
110
|
font-display: swap;
|
111
|
-
src: url('
|
111
|
+
src: url('Inter-italic.latin.var.woff2') format('woff2');
|
112
112
|
unicode-range: U+0000-007F,U+00A0-0100,U+0131,U+0152-0154,U+02BB-02BD,U+02C6,U+02DA,U+02DC,U+2000-200C,U+2010-2028,U+202F-2060,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+FEFF;
|
113
113
|
font-named-instance: 'Italic';
|
114
114
|
}
|
@@ -118,7 +118,7 @@
|
|
118
118
|
font-style: normal;
|
119
119
|
font-weight: 100 900;
|
120
120
|
font-display: swap;
|
121
|
-
src: url('
|
121
|
+
src: url('Inter-roman.extra.var.woff2') format('woff2');
|
122
122
|
unicode-range: U+E000,U+E002-E081,U+E093-E097,U+E0A5-E0E7,U+E0F3-E11D,U+E11E-E165,U+EE01,U+F6C3;
|
123
123
|
font-named-instance: 'Regular';
|
124
124
|
}
|
@@ -128,7 +128,7 @@
|
|
128
128
|
font-style: normal;
|
129
129
|
font-weight: 100 900;
|
130
130
|
font-display: swap;
|
131
|
-
src: url('
|
131
|
+
src: url('Inter-roman.alternates.var.woff2') format('woff2');
|
132
132
|
unicode-range: U+E000,U+E002-E081,U+E093-E097,U+E0A5-E0E7,U+E0F3-E11D,U+E11E-E165,U+EE01,U+F6C3;
|
133
133
|
font-named-instance: 'Regular';
|
134
134
|
}
|
@@ -138,7 +138,7 @@
|
|
138
138
|
font-style: normal;
|
139
139
|
font-weight: 100 900;
|
140
140
|
font-display: swap;
|
141
|
-
src: url('
|
141
|
+
src: url('Inter-roman.symbols.var.woff2') format('woff2');
|
142
142
|
unicode-range: U+20DD-20DF,U+2190-219A,U+21A9-21AB,U+21B0-21B2,U+21B3-21B6,U+21BA-21BC,U+21D0,U+21D2,U+21D4,U+21DE-21E0,U+21E4-21E6,U+21E7,U+21EA,U+2303,U+2305,U+2318,U+2325-2328,U+232B,U+2380,U+2387,U+238B,U+23CE-23D0,U+2460-2469,U+24B6-24D0,U+24EA,U+25A0-25A3,U+25B2-25B4,U+25B6-25B8,U+25BA-25BE,U+25C0-25C2,U+25C4-25C8,U+25CB,U+25CF,U+25EF,U+2600,U+2605-2607,U+263C,U+2661,U+2665,U+26A0,U+2713,U+2717,U+2756,U+2764,U+2780-2789,U+27F5-27FB,U+2B06,U+2B12-2B14,U+2B1C,U+E000,U+E12B-E164,U+1F130-1F14A,U+1F850,U+1F852;
|
143
143
|
font-named-instance: 'Regular';
|
144
144
|
}
|
@@ -148,7 +148,7 @@
|
|
148
148
|
font-style: normal;
|
149
149
|
font-weight: 100 900;
|
150
150
|
font-display: swap;
|
151
|
-
src: url('
|
151
|
+
src: url('Inter-roman.cyrillic.var.woff2') format('woff2');
|
152
152
|
unicode-range: U+0400-049E,U+04A0-0500,U+052F,U+20B4,U+2116,U+2DFF,U+A69F;
|
153
153
|
font-named-instance: 'Regular';
|
154
154
|
}
|
@@ -158,7 +158,7 @@
|
|
158
158
|
font-style: normal;
|
159
159
|
font-weight: 100 900;
|
160
160
|
font-display: swap;
|
161
|
-
src: url('
|
161
|
+
src: url('Inter-roman.greek.var.woff2') format('woff2');
|
162
162
|
unicode-range: U+0370-0378,U+037A-0380,U+0384-038B,U+038C,U+038E-03A2,U+03A3-03E2,U+03F0-0400,U+1F00-1F16,U+1F18-1F1E,U+1F20-1F46,U+1F48-1F4E,U+1F50-1F58,U+1F59,U+1F5B,U+1F5D,U+1F5F-1F7E,U+1F80-1FB5,U+1FB6-1FC5,U+1FC6-1FD4,U+1FD6-1FDC,U+1FDD-1FF0,U+1FF2-1FF5,U+1FF6-1FFF;
|
163
163
|
font-named-instance: 'Regular';
|
164
164
|
}
|
@@ -168,7 +168,7 @@
|
|
168
168
|
font-style: normal;
|
169
169
|
font-weight: 100 900;
|
170
170
|
font-display: swap;
|
171
|
-
src: url('
|
171
|
+
src: url('Inter-roman.vietnamese.var.woff2') format('woff2');
|
172
172
|
unicode-range: U+0102-0104,U+0110-0112,U+0128-012A,U+0168-016A,U+01A0-01A2,U+01AF-01B1,U+1EA0-1EFA,U+20AB;
|
173
173
|
font-named-instance: 'Regular';
|
174
174
|
}
|
@@ -178,7 +178,7 @@
|
|
178
178
|
font-style: normal;
|
179
179
|
font-weight: 100 900;
|
180
180
|
font-display: swap;
|
181
|
-
src: url('
|
181
|
+
src: url('Inter-roman.latin-ext.var.woff2') format('woff2');
|
182
182
|
unicode-range: U+0100-0149,U+014A-01C4,U+01C5-0250,U+0259,U+1E00-1F00,U+2020,U+20A0-20AC,U+20AD-20C0,U+2113,U+2C7C,U+2C7F,U+A7FF;
|
183
183
|
font-named-instance: 'Regular';
|
184
184
|
}
|
@@ -188,7 +188,7 @@
|
|
188
188
|
font-style: normal;
|
189
189
|
font-weight: 100 900;
|
190
190
|
font-display: swap;
|
191
|
-
src: url('
|
191
|
+
src: url('Inter-roman.latin.var.woff2') format('woff2');
|
192
192
|
unicode-range: U+0000-007F,U+00A0-0100,U+0131,U+0152-0154,U+02BB-02BD,U+02C6,U+02DA,U+02DC,U+2000-200C,U+2010-2028,U+202F-2060,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+FEFF;
|
193
193
|
font-named-instance: 'Regular';
|
194
194
|
}
|
data/lib/install/dev
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
const defaultTheme = require('tailwindcss/defaultTheme')
|
2
|
+
|
3
|
+
module.exports = {
|
4
|
+
darkMode: 'media',
|
5
|
+
content: [
|
6
|
+
'./app/helpers/**/*.rb',
|
7
|
+
'./app/javascript/**/*.js',
|
8
|
+
'./app/views/**/*'
|
9
|
+
],
|
10
|
+
theme: {
|
11
|
+
extend: {
|
12
|
+
fontFamily: {
|
13
|
+
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
|
14
|
+
},
|
15
|
+
},
|
16
|
+
},
|
17
|
+
plugins: [
|
18
|
+
require('@tailwindcss/forms'),
|
19
|
+
require('@tailwindcss/aspect-ratio'),
|
20
|
+
require('@tailwindcss/typography'),
|
21
|
+
]
|
22
|
+
}
|
data/lib/install/tailwindcss.rb
CHANGED
@@ -3,20 +3,50 @@ APPLICATION_LAYOUT_PATH = Rails.root.join("app/views/layouts/application.html.er
|
|
3
3
|
if APPLICATION_LAYOUT_PATH.exist?
|
4
4
|
say "Add Tailwindcss include tags and container element in application layout"
|
5
5
|
insert_into_file APPLICATION_LAYOUT_PATH.to_s, <<~ERB.indent(4), before: /^\s*<%= stylesheet_link_tag/
|
6
|
-
<%= stylesheet_link_tag "inter-font", "data-turbo-track": "reload" %>
|
7
|
-
<%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %>
|
6
|
+
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
|
8
7
|
ERB
|
9
8
|
insert_into_file APPLICATION_LAYOUT_PATH.to_s, %( <main class="container mx-auto mt-28 px-5 flex">\n ), before: /^\s*<%= yield/
|
10
9
|
insert_into_file APPLICATION_LAYOUT_PATH.to_s, %(\n </main>), after: /^\s*<%= yield %>/
|
11
10
|
else
|
12
11
|
say "Default application.html.erb is missing!", :red
|
13
|
-
say %( Add <%= stylesheet_link_tag "
|
12
|
+
say %( Add <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %> within the <head> tag in your custom layout.)
|
14
13
|
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
say "Build into app/assets/builds"
|
16
|
+
empty_directory "app/assets/builds"
|
17
|
+
keep_file "app/assets/builds"
|
18
|
+
|
19
|
+
if (sprockets_manifest_path = Rails.root.join("app/assets/config/manifest.js")).exist?
|
20
|
+
append_to_file sprockets_manifest_path, %(//= link_tree ../builds\n)
|
21
|
+
end
|
22
|
+
|
23
|
+
if Rails.root.join(".gitignore").exist?
|
24
|
+
append_to_file(".gitignore", %(\n/app/assets/builds/*\n!/app/assets/builds/.keep\n))
|
25
|
+
end
|
26
|
+
|
27
|
+
unless Rails.root.join("config/tailwind.config.js").exist?
|
28
|
+
say "Add default config/tailwindcss.config.js"
|
29
|
+
copy_file "#{__dir__}/tailwind.config.js", "config/tailwind.config.js"
|
30
|
+
end
|
31
|
+
|
32
|
+
unless Rails.root.join("app/assets/stylesheets/application.tailwind.css").exist?
|
33
|
+
say "Add default app/assets/stylesheets/application.tailwind.css"
|
34
|
+
copy_file "#{__dir__}/application.tailwind.css", "app/assets/stylesheets/application.tailwind.css"
|
35
|
+
end
|
36
|
+
|
37
|
+
if Rails.root.join("Procfile.dev").exist?
|
38
|
+
append_to_file "Procfile.dev", "css: rails tailwindcss:watch\n"
|
39
|
+
else
|
40
|
+
say "Add default Procfile.dev"
|
41
|
+
copy_file "#{__dir__}/Procfile.dev", "Procfile.dev"
|
42
|
+
|
43
|
+
say "Ensure foreman is installed"
|
44
|
+
run "gem install foreman"
|
19
45
|
end
|
20
46
|
|
21
|
-
say "
|
22
|
-
|
47
|
+
say "Add bin/dev to start foreman"
|
48
|
+
copy_file "#{__dir__}/dev", "bin/dev"
|
49
|
+
chmod "bin/dev", 0755, verbose: false
|
50
|
+
|
51
|
+
say "Compile initial Tailwind build"
|
52
|
+
run "rails tailwindcss:build"
|
data/lib/tailwindcss/engine.rb
CHANGED
@@ -1,26 +1,15 @@
|
|
1
1
|
require "rails"
|
2
|
-
require "tailwindcss/compressor"
|
3
2
|
|
4
3
|
module Tailwindcss
|
5
4
|
class Engine < ::Rails::Engine
|
6
|
-
initializer "tailwindcss.compressor" do
|
7
|
-
Sprockets.register_compressor "text/css", :purger, Tailwindcss::Compressor
|
8
|
-
end
|
9
|
-
|
10
5
|
initializer "tailwindcss.assets" do
|
11
|
-
Rails.application.config.assets.precompile += %w(
|
6
|
+
Rails.application.config.assets.precompile += %w( inter-font.css )
|
12
7
|
end
|
13
8
|
|
14
9
|
initializer "tailwindcss.disable_generator_stylesheets" do
|
15
10
|
Rails.application.config.generators.stylesheets = false
|
16
11
|
end
|
17
12
|
|
18
|
-
initializer "tailwindcss.disable_assets_cache" do
|
19
|
-
Rails.application.config.assets.configure do |env|
|
20
|
-
env.cache = ActiveSupport::Cache.lookup_store(:null_store)
|
21
|
-
end if Rails.env.production?
|
22
|
-
end
|
23
|
-
|
24
13
|
config.app_generators do |g|
|
25
14
|
g.template_engine :tailwindcss
|
26
15
|
end
|
data/lib/tailwindcss/version.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
TAILWIND_COMPILE_COMMAND = "#{Pathname.new(__dir__).to_s}/../../exe/tailwindcss -i #{Rails.root.join("app/assets/stylesheets/application.tailwind.css")} -o #{Rails.root.join("app/assets/builds/tailwind.css")} -c #{Rails.root.join("config/tailwind.config.js")}"
|
2
|
+
|
3
|
+
namespace :tailwindcss do
|
4
|
+
desc "Build your Tailwind CSS"
|
5
|
+
task :build do
|
6
|
+
system TAILWIND_COMPILE_COMMAND
|
7
|
+
end
|
8
|
+
|
9
|
+
task :watch do
|
10
|
+
system "#{TAILWIND_COMPILE_COMMAND} -w"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Rake::Task["assets:precompile"].enhance(["tailwindcss:build"])
|
15
|
+
|
16
|
+
if Rake::Task.task_defined?("test:prepare")
|
17
|
+
Rake::Task["test:prepare"].enhance(["tailwindcss:build"])
|
18
|
+
elsif Rake::Task.task_defined?("db:test:prepare")
|
19
|
+
Rake::Task["db:test:prepare"].enhance(["tailwindcss:build"])
|
20
|
+
end
|
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:
|
4
|
+
version: 2.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -49,7 +49,7 @@ files:
|
|
49
49
|
- app/assets/fonts/Inter-roman.latin.var.woff2
|
50
50
|
- app/assets/fonts/Inter-roman.symbols.var.woff2
|
51
51
|
- app/assets/fonts/Inter-roman.vietnamese.var.woff2
|
52
|
-
- app/assets/stylesheets/inter-font.css
|
52
|
+
- app/assets/stylesheets/inter-font.css
|
53
53
|
- app/assets/stylesheets/tailwind.css
|
54
54
|
- lib/generators/tailwindcss/controller/controller_generator.rb
|
55
55
|
- lib/generators/tailwindcss/controller/templates/view.html.erb.tt
|
@@ -63,13 +63,17 @@ files:
|
|
63
63
|
- lib/generators/tailwindcss/scaffold/templates/new.html.erb.tt
|
64
64
|
- lib/generators/tailwindcss/scaffold/templates/partial.html.erb.tt
|
65
65
|
- lib/generators/tailwindcss/scaffold/templates/show.html.erb.tt
|
66
|
+
- lib/install/Procfile.dev
|
67
|
+
- lib/install/application.tailwind.css
|
68
|
+
- lib/install/dev
|
69
|
+
- lib/install/tailwind.config.js
|
66
70
|
- lib/install/tailwindcss.rb
|
67
71
|
- lib/tailwindcss-rails.rb
|
68
|
-
- lib/tailwindcss/compressor.rb
|
69
72
|
- lib/tailwindcss/engine.rb
|
70
|
-
- lib/tailwindcss/purger.rb
|
71
73
|
- lib/tailwindcss/version.rb
|
72
|
-
- lib/tasks/
|
74
|
+
- lib/tasks/build.rake
|
75
|
+
- lib/tasks/clobber.rake
|
76
|
+
- lib/tasks/install.rake
|
73
77
|
homepage: https://github.com/rails/tailwindcss-rails
|
74
78
|
licenses:
|
75
79
|
- MIT
|
@@ -87,9 +91,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
91
|
version: '0'
|
88
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
93
|
requirements:
|
90
|
-
- - "
|
94
|
+
- - ">"
|
91
95
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
96
|
+
version: 1.3.1
|
93
97
|
requirements: []
|
94
98
|
rubygems_version: 3.2.32
|
95
99
|
signing_key:
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require "tailwindcss/purger"
|
2
|
-
|
3
|
-
class Tailwindcss::Compressor
|
4
|
-
def self.instance
|
5
|
-
@instance ||= new
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.call(input)
|
9
|
-
instance.call(input)
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(options = {})
|
13
|
-
@options = {
|
14
|
-
files_with_class_names: files_with_class_names,
|
15
|
-
only_purge: %w[ tailwind ]
|
16
|
-
}.merge(options).freeze
|
17
|
-
end
|
18
|
-
|
19
|
-
def call(input)
|
20
|
-
if input[:name].in?(@options[:only_purge])
|
21
|
-
{ data: Tailwindcss::Purger.purge(input[:data], keeping_class_names_from_files: @options[:files_with_class_names]) }
|
22
|
-
else
|
23
|
-
input[:data]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
def files_with_class_names
|
29
|
-
Rails.root.glob("app/views/**/*.*") +
|
30
|
-
Rails.root.glob("app/helpers/**/*.rb") +
|
31
|
-
Rails.root.glob("app/javascript/**/*.js")
|
32
|
-
end
|
33
|
-
end
|
data/lib/tailwindcss/purger.rb
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Tailwindcss::Purger
|
4
|
-
CLASS_NAME_PATTERN = /((?:[:A-Za-z0-9_-]+[\\\/:A-Za-z0-9_-]*[0-3][\\.]*5)|(?:[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?/
|
23
|
-
|
24
|
-
attr_reader :keep_these_class_names
|
25
|
-
|
26
|
-
class << self
|
27
|
-
def purge(input, keeping_class_names_from_files:)
|
28
|
-
new(extract_class_names_from(keeping_class_names_from_files)).purge(input)
|
29
|
-
end
|
30
|
-
|
31
|
-
def extract_class_names(string)
|
32
|
-
string.scan(CLASS_NAME_PATTERN).flatten.uniq.sort!
|
33
|
-
end
|
34
|
-
|
35
|
-
def extract_class_names_from(files)
|
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')
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def initialize(keep_these_class_names)
|
45
|
-
@keep_these_class_names = keep_these_class_names
|
46
|
-
end
|
47
|
-
|
48
|
-
def purge(input)
|
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"
|
58
|
-
end
|
59
|
-
|
60
|
-
conveyor.output
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
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
|
79
|
-
end
|
80
|
-
|
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
|
123
|
-
end
|
124
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
namespace :tailwindcss do
|
2
|
-
desc "Install Tailwind CSS into the app"
|
3
|
-
task :install do
|
4
|
-
system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/tailwindcss.rb", __dir__)}"
|
5
|
-
end
|
6
|
-
|
7
|
-
desc "Show the list of class names being kept in Tailwind CSS"
|
8
|
-
task :keeping_class_names do
|
9
|
-
puts Tailwindcss::Purger.extract_class_names_from(default_files_with_class_names)
|
10
|
-
end
|
11
|
-
|
12
|
-
desc "Show Tailwind CSS styles that are left after purging unused class names"
|
13
|
-
task :preview_purge do
|
14
|
-
puts Tailwindcss::Purger.purge tailwind_css, keeping_class_names_from_files: default_files_with_class_names
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def default_files_with_class_names
|
19
|
-
Rails.root.glob("app/views/**/*.*") + Rails.root.glob("app/helpers/**/*.rb")
|
20
|
-
end
|
21
|
-
|
22
|
-
def tailwind_css
|
23
|
-
Pathname.new(__FILE__).join("../../../app/assets/stylesheets/tailwind.css").read
|
24
|
-
end
|
25
|
-
|