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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 271a2b804dd59ec03250304b63c4c6e2f789984eef0a054f146d946679837361
4
- data.tar.gz: 25247c46c616a5cc4fa505779917a1e195cbcda3aa52b6afca93b79fa8d4efab
3
+ metadata.gz: d22f4bc34ab3304b899f7d195dcbeb00feeb81fde432467f7c2d27e04ab8a543
4
+ data.tar.gz: 86c44ee8942497bc4e3bb13b21b4ae9083ccdeee0564a0072bd6bcd9b5e60a34
5
5
  SHA512:
6
- metadata.gz: ecc7197301ae8c84f2d783a660596d33024aaf07e875adba714ea9380bb8c3bdf315be4f49dd743861be182591760bf9782e411ef57a17828002621314106fdd
7
- data.tar.gz: 6ce32962dd8c4238cfa10720f8c45607de65800322b134ba72d248ed96ed5edd69cbcab726c02e23c1dad9cdea603d23652714f0f7188d375fdd506d94d1f593
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 gives access to the standard Tailwind CSS framework configured for dark mode, forms, aspect-ratio, typography, and the Inter font via the asset pipeline using Sprockets (and soon [Propshaft](https://github.com/rails/propshaft)).
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
- If you need to customize Tailwind, you will need to install it under a full JavaScript bundling setup, such as [cssbundling-rails](https://github.com/rails/cssbundling-rails). This gem was specifically designed not to require a Node.js environment. If you're already using such an environment, you won't need this gem.
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
- Production-mode purging of unused css class names is provided by a Sprockets compressor built into this gem. This compressor ensures that only the css classes used by files in `app/views` and `app/helpers` are included. In development mode, the full 7mb+ Tailwind stylesheet is loaded.
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
- ## Installation
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
- ## Configuration
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
- * @tailwindcss/aspect-ratio 0.2.1
55
- * @tailwindcss/forms 0.3.3
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
- ## Compatibility with Tailwind 3.0
24
+ ## Building in production
62
25
 
63
- This gem is not yet compatible with the JIT approach taken with Tailwind 3.0. We're working with the team on an approach that would bring compatibility, but at the moment you'd need to use [cssbundling-rails](https://github.com/rails/cssbundling-rails/) (and thus bring Node into your app) in order to use 3.0.
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('<%= asset_path "Inter-italic.extra.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.alternates.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.symbols.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.extra.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.alternates.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.symbols.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.cyrillic.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.greek.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.vietnamese.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.latin-ext.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-italic.latin.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-roman.extra.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-roman.alternates.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-roman.symbols.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-roman.cyrillic.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-roman.greek.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-roman.vietnamese.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-roman.latin-ext.var.woff2" %>') format('woff2');
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('<%= asset_path "Inter-roman.latin.var.woff2" %>') format('woff2');
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
  }
@@ -0,0 +1,2 @@
1
+ web: bin/rails server -p 3000
2
+ css: rails tailwindcss:watch
@@ -0,0 +1,13 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ /*
6
+
7
+ @layer components {
8
+ .btn-primary {
9
+ @apply py-2 px-4 bg-blue-200;
10
+ }
11
+ }
12
+
13
+ */
data/lib/install/dev ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if ! command -v foreman &> /dev/null
4
+ then
5
+ echo "Installing foreman..."
6
+ gem install foreman
7
+ fi
8
+
9
+ foreman start -f Procfile.dev
@@ -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
+ }
@@ -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 "inter-font", "data-turbo-track": "reload" %> and <%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %> within the <head> tag in your custom layout.)
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
- # No longer included by default in Rails 7, but for earlier versions of Rails
17
- if (scaffolds_css_path = Rails.root.join("app/assets/stylesheets/scaffolds.scss")).exist?
18
- remove_file scaffolds_css_path
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 "Turn on purging of unused css classes in production"
22
- gsub_file Rails.root.join("config/environments/production.rb"), /^\s+#?\s+config.assets.css_compressor =.*$/, %( config.assets.css_compressor = :purger)
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"
@@ -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( tailwind.css inter-font.css )
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
@@ -1,3 +1,3 @@
1
1
  module Tailwindcss
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0.rc1"
3
3
  end
@@ -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
@@ -0,0 +1,8 @@
1
+ namespace :tailwindcss do
2
+ desc "Remove CSS builds"
3
+ task :clobber do
4
+ rm_rf Dir["app/assets/builds/[^.]*.css"], verbose: false
5
+ end
6
+ end
7
+
8
+ Rake::Task["assets:clobber"].enhance(["tailwindcss:clobber"])
@@ -0,0 +1,6 @@
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
+ 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: 1.0.0
4
+ version: 2.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-14 00:00:00.000000000 Z
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.erb
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/tailwindcss_tasks.rake
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: '0'
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
@@ -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
-