view_component-scoped_styles 0.6.1 → 0.8.0
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 +90 -17
- data/lib/view_component/scoped_styles/concern.rb +29 -32
- data/lib/view_component/scoped_styles/css_selectors.rb +151 -0
- data/lib/view_component/scoped_styles/stylist/writer.rb +5 -5
- data/lib/view_component/scoped_styles/version.rb +1 -1
- data/lib/view_component/scoped_styles.rb +2 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cbe5f5accd78d4f725e75db0267dad949175cbe53ed68bb003dccc4745c294f4
|
|
4
|
+
data.tar.gz: 2f90b7dd291d0b5b3910a8c4e5e8be1e9c5000d8a69b07315582afac30abd2df
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 89c318654efd8e5dbba628f5aade499754d32588b35fee364c7e91a45bc3fb0ae2001c1e1b3fdd390ede8890f081d060ed221551e513ee021c5639aafc708b4b
|
|
7
|
+
data.tar.gz: 0d6adc27535b6ab7219935e78964b305cc13fd5b8590a82487b9dbc2d418deaddc15d0d870cd87bf8d1a4d62e96a993437909f4fe807d0a413dda3851a5eb05d
|
data/README.md
CHANGED
|
@@ -15,8 +15,9 @@ E.g. `.button` becomes `.button_a1b2c3d4`
|
|
|
15
15
|
- [1. Using a sidecar stylesheet](#1-using-a-sidecar-stylesheet)
|
|
16
16
|
- [2. Using a styles block in the component](#2-using-a-styles-block-in-the-component)
|
|
17
17
|
- [Referencing classes](#referencing-classes)
|
|
18
|
-
- [
|
|
18
|
+
- [Global classes](#global-classes)
|
|
19
19
|
- [Using the scoped CSS](#using-the-scoped-css)
|
|
20
|
+
- [Multiple stylesheets](#multiple-stylesheets)
|
|
20
21
|
- [Configuration](#configuration)
|
|
21
22
|
- [Related projects](#related-projects)
|
|
22
23
|
- [Development](#development)
|
|
@@ -248,36 +249,76 @@ end
|
|
|
248
249
|
|
|
249
250
|
**Upgrading from 0.4.x:** set `config.css_class_prefix = "c-"` (and per-component overrides) to keep the previous `c-a1b2c3d4` class names without updating templates.
|
|
250
251
|
|
|
251
|
-
###
|
|
252
|
+
### Global classes
|
|
252
253
|
|
|
253
|
-
|
|
254
|
+
Use CSS Modules-style `:global(...)` to leave class selectors unchanged in a sidecar stylesheet or `styles` block:
|
|
254
255
|
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
```css
|
|
257
|
+
.component:global(.is-open) {
|
|
258
|
+
display: block;
|
|
259
|
+
}
|
|
258
260
|
|
|
259
|
-
|
|
261
|
+
:global(.active) .label {
|
|
262
|
+
font-weight: bold;
|
|
263
|
+
}
|
|
264
|
+
```
|
|
260
265
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
266
|
+
The compiler removes `:global(...)` and leaves its contents unscoped. In these examples, `.component` and `.label` get scoped names, while `.is-open` and `.active` stay unchanged. Nested selector functions work too:
|
|
267
|
+
|
|
268
|
+
```css
|
|
269
|
+
.component:has(:global(.external:not(.disabled))) {
|
|
270
|
+
border-color: green;
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Bare `:global` makes the rest of the current selector global. Use `:local(...)` for a local selector within it, or bare `:local` to switch back. Scope resets at each comma, at the end of a selector function, and for each new rule.
|
|
275
|
+
|
|
276
|
+
```css
|
|
277
|
+
.component :global .external .icon :local(.label) {
|
|
278
|
+
color: red;
|
|
279
|
+
}
|
|
268
280
|
```
|
|
269
|
-
|
|
281
|
+
|
|
282
|
+
For selector lists, write `:global(.first), :global(.second)`. Lists inside a single `:global(...)` are not supported.
|
|
283
|
+
|
|
284
|
+
Global scope applies to each occurrence. A class can be global in one selector and local in another. `component_class("name")` returns the scoped name when there is a local occurrence, or the original name when every occurrence is global. The root helper uses the configured root class when present, otherwise the first local class, or the first global class if there are no local classes.
|
|
285
|
+
|
|
286
|
+
In your view, reference a global class directly:
|
|
287
|
+
|
|
270
288
|
```erb
|
|
271
289
|
<div class="<%= component_class %> is-open">
|
|
272
290
|
```
|
|
273
|
-
|
|
291
|
+
|
|
292
|
+
Or use the helper for a class that appears only in global scope:
|
|
293
|
+
|
|
274
294
|
```erb
|
|
275
295
|
<div class="<%= component_class %> <%= component_class("is-open") %>">
|
|
276
296
|
```
|
|
277
297
|
|
|
298
|
+
#### Migrating from ignored_css_classes
|
|
299
|
+
|
|
300
|
+
`ignored_css_classes` is deprecated and emits an ActiveSupport deprecation warning. It continues to leave every occurrence of the listed classes unchanged, including their helper results.
|
|
301
|
+
|
|
302
|
+
Remove the Ruby declaration and wrap each occurrence of those classes in `:global(...)`:
|
|
303
|
+
|
|
304
|
+
```ruby
|
|
305
|
+
# Remove this from your component:
|
|
306
|
+
ignored_css_classes "is-open", "active"
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
```css
|
|
310
|
+
/* Before */
|
|
311
|
+
.component.is-open .active { color: red; }
|
|
312
|
+
|
|
313
|
+
/* After */
|
|
314
|
+
.component:global(.is-open) :global(.active) { color: red; }
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Regenerate the bundled stylesheet after migrating. Scoped names are content-derived, so changing the CSS changes their hashes.
|
|
318
|
+
|
|
278
319
|
### Using the scoped CSS
|
|
279
320
|
|
|
280
|
-
|
|
321
|
+
Scoped CSS is compiled into `app/assets/stylesheets/components.scoped.css` by default. Components can select a different output bundle with `stylesheet`. The default stylesheet is `app/assets/stylesheets/components.scoped.css`; both the directory and filename are configurable (see [Configuration](#configuration)).
|
|
281
322
|
|
|
282
323
|
You should import this stylesheet within your app:
|
|
283
324
|
|
|
@@ -287,6 +328,38 @@ You should import this stylesheet within your app:
|
|
|
287
328
|
@import url("./components.scoped.css");
|
|
288
329
|
```
|
|
289
330
|
|
|
331
|
+
### Multiple stylesheets
|
|
332
|
+
|
|
333
|
+
Set `stylesheet` before declaring a `styles` block to choose the component's output bundle. The gem appends `.scoped.css` to the name. This also works with sidecar CSS:
|
|
334
|
+
|
|
335
|
+
```ruby
|
|
336
|
+
class Admin::ButtonComponent < ViewComponent::Base
|
|
337
|
+
include ViewComponent::ScopedStyles
|
|
338
|
+
|
|
339
|
+
stylesheet "admin"
|
|
340
|
+
|
|
341
|
+
styles do
|
|
342
|
+
".component { color: blue; }"
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
class Admin::CardComponent < ViewComponent::Base
|
|
347
|
+
include ViewComponent::ScopedStyles
|
|
348
|
+
|
|
349
|
+
stylesheet "admin"
|
|
350
|
+
end
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Both components compile into `app/assets/stylesheets/admin.scoped.css`. Any number of components can use the same bundle name. Components without a selection use `config.stylesheet_name`. Subclasses inherit their parent's selection and can override it.
|
|
354
|
+
|
|
355
|
+
All output files use `config.assets_path` and, when configured, `config.components_layer`. Include each bundle where you need it:
|
|
356
|
+
|
|
357
|
+
```erb
|
|
358
|
+
<%= stylesheet_link_tag "admin.scoped", "data-turbo-track": "reload" %>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Cross-component class references still work across bundles. Load both bundles when both components' styles are needed. When moving an existing component between bundles, remove its marked CSS block from the old generated file, since registration updates the selected file only.
|
|
362
|
+
|
|
290
363
|
## Configuration
|
|
291
364
|
|
|
292
365
|
Run the install generator in your Rails app:
|
|
@@ -7,7 +7,7 @@ module ViewComponent
|
|
|
7
7
|
extend ActiveSupport::Concern
|
|
8
8
|
|
|
9
9
|
CACHED_VARIABLES = %i[@component_styles @component_id @component_class_map].freeze
|
|
10
|
-
|
|
10
|
+
DEPRECATOR = ActiveSupport::Deprecation.new("a future release", "ViewComponent::ScopedStyles")
|
|
11
11
|
COMPONENT_REFERENCE_PATTERN = /
|
|
12
12
|
:component\(
|
|
13
13
|
\s*
|
|
@@ -23,6 +23,21 @@ module ViewComponent
|
|
|
23
23
|
IGNORED_CSS_CLASSES = [].freeze
|
|
24
24
|
|
|
25
25
|
class_methods do
|
|
26
|
+
# Selects an output bundle, written as <name>.scoped.css in assets_path.
|
|
27
|
+
# Subclasses inherit this choice unless they specify their own bundle.
|
|
28
|
+
def stylesheet(name = nil)
|
|
29
|
+
if name
|
|
30
|
+
@scoped_stylesheet = name.to_s
|
|
31
|
+
register_styles_if_rails_loaded
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if defined?(@scoped_stylesheet)
|
|
35
|
+
@scoped_stylesheet
|
|
36
|
+
elsif superclass.respond_to?(:stylesheet)
|
|
37
|
+
superclass.stylesheet
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
26
41
|
# Sets which CSS class is the root for +component_class+ (no argument).
|
|
27
42
|
# Also triggers style registration in development when Rails is loaded
|
|
28
43
|
# (registration also runs via the Railtie for all styled components).
|
|
@@ -52,7 +67,12 @@ module ViewComponent
|
|
|
52
67
|
# Clears cached generated styles when the list changes.
|
|
53
68
|
#
|
|
54
69
|
# @param classes [String, Symbol] selector names without a leading dot
|
|
70
|
+
# @deprecated Wrap selectors in +:global(...)+ in the stylesheet instead.
|
|
55
71
|
def ignored_css_classes(*classes)
|
|
72
|
+
DEPRECATOR.warn(
|
|
73
|
+
"ignored_css_classes is deprecated. Use :global(...) in your CSS instead, " \
|
|
74
|
+
"for example :global(.active)."
|
|
75
|
+
)
|
|
56
76
|
if classes.any?
|
|
57
77
|
names = classes.flatten.map { |css_class| css_class.to_s.delete_prefix(".") }
|
|
58
78
|
const_set(:IGNORED_CSS_CLASSES, names.freeze)
|
|
@@ -134,13 +154,15 @@ module ViewComponent
|
|
|
134
154
|
component_resolution_stack.push(self)
|
|
135
155
|
pushed = true
|
|
136
156
|
styles_content = generate_styles_content
|
|
137
|
-
|
|
138
|
-
|
|
157
|
+
selectors = CssSelectors.new(styles_content)
|
|
158
|
+
css_classes = selectors.local_classes
|
|
159
|
+
primary_class = primary_css_class(css_classes + selectors.global_classes)
|
|
139
160
|
|
|
140
|
-
@component_id = component_id_for(primary_class, styles_content)
|
|
141
161
|
@component_class_map = build_component_class_map(styles_content, css_classes, primary_class)
|
|
162
|
+
selectors.global_classes.each { |name| @component_class_map[name] ||= name }
|
|
163
|
+
@component_id = @component_class_map[primary_class]
|
|
142
164
|
@component_styles = replace_component_references(
|
|
143
|
-
|
|
165
|
+
selectors.render(@component_class_map)
|
|
144
166
|
)
|
|
145
167
|
ensure
|
|
146
168
|
component_resolution_stack.pop if pushed
|
|
@@ -150,10 +172,6 @@ module ViewComponent
|
|
|
150
172
|
@styles_block ? @styles_block.call : File.read(stylesheet_path)
|
|
151
173
|
end
|
|
152
174
|
|
|
153
|
-
def extract_css_classes(styles_content)
|
|
154
|
-
styles_content.scan(CLASS_SELECTOR_PATTERN).flatten.uniq
|
|
155
|
-
end
|
|
156
|
-
|
|
157
175
|
def primary_css_class(css_classes)
|
|
158
176
|
configured = self::COMPONENT_CSS_CLASS.delete_prefix(".")
|
|
159
177
|
css_classes.include?(configured) ? configured : css_classes.first
|
|
@@ -169,20 +187,6 @@ module ViewComponent
|
|
|
169
187
|
end
|
|
170
188
|
end
|
|
171
189
|
|
|
172
|
-
def replace_css_classes(styles_content, class_map)
|
|
173
|
-
scoped_map = class_map.reject do |css_class, scoped|
|
|
174
|
-
css_class == scoped
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
sorted_classes = scoped_map.keys.sort_by(&:length).reverse
|
|
178
|
-
|
|
179
|
-
sorted_classes.reduce(styles_content) do |content, css_class|
|
|
180
|
-
scoped = class_map[css_class]
|
|
181
|
-
escaped = CssClassPrefix.escape_for_css_selector(scoped)
|
|
182
|
-
content.gsub(/\.#{Regexp.escape(css_class)}\b/, ".#{escaped}")
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
190
|
def replace_component_references(styles_content)
|
|
187
191
|
styles_content.gsub(COMPONENT_REFERENCE_PATTERN) do
|
|
188
192
|
component_name = Regexp.last_match[:component_name]
|
|
@@ -194,14 +198,6 @@ module ViewComponent
|
|
|
194
198
|
end
|
|
195
199
|
end
|
|
196
200
|
|
|
197
|
-
def component_id_for(primary_class, styles_content)
|
|
198
|
-
if ignored_css_class?(primary_class)
|
|
199
|
-
primary_class
|
|
200
|
-
else
|
|
201
|
-
generate_scoped_class_id(styles_content, primary_class, primary_class)
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
|
|
205
201
|
def ignored_css_class?(css_class)
|
|
206
202
|
self::IGNORED_CSS_CLASSES.include?(css_class)
|
|
207
203
|
end
|
|
@@ -275,7 +271,8 @@ module ViewComponent
|
|
|
275
271
|
# Scoped CSS class for a selector (e.g. +"c-99d08d5a"+).
|
|
276
272
|
#
|
|
277
273
|
# With no argument, returns the scoped root class ({COMPONENT_CSS_CLASS} when it
|
|
278
|
-
# appears in the CSS, otherwise the first class
|
|
274
|
+
# appears in the CSS, otherwise the first local class, or the first global
|
|
275
|
+
# class when the stylesheet has no local classes).
|
|
279
276
|
#
|
|
280
277
|
# @param name [String, Symbol] CSS class without a leading dot (e.g. +"input-box"+)
|
|
281
278
|
# @param from [Class] component class to read scoped CSS classes from
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "strscan"
|
|
4
|
+
|
|
5
|
+
module ViewComponent
|
|
6
|
+
module ScopedStyles
|
|
7
|
+
# Records each class occurrence with its scope, preserving non-selector CSS.
|
|
8
|
+
class CssSelectors
|
|
9
|
+
COMMENT = %r{/\*.*?\*/}m
|
|
10
|
+
PROTECTED = %r{/\*.*?\*/|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\\.}m
|
|
11
|
+
CLASS_SELECTOR = /\.([a-zA-Z_][\w-]*)\b/
|
|
12
|
+
ClassSelector = Struct.new(:name, :local)
|
|
13
|
+
|
|
14
|
+
attr_reader :local_classes, :global_classes
|
|
15
|
+
|
|
16
|
+
def initialize(css)
|
|
17
|
+
@local_classes = []
|
|
18
|
+
@global_classes = []
|
|
19
|
+
@parts = parse_stylesheet(css)
|
|
20
|
+
@local_classes.uniq!
|
|
21
|
+
@global_classes.uniq!
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def render(class_map)
|
|
25
|
+
@parts.map do |part|
|
|
26
|
+
if part.is_a?(ClassSelector)
|
|
27
|
+
name = part.local ? class_map.fetch(part.name) : part.name
|
|
28
|
+
".#{CssClassPrefix.escape_for_css_selector(name)}"
|
|
29
|
+
else
|
|
30
|
+
part
|
|
31
|
+
end
|
|
32
|
+
end.join
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# A rule's prelude ends at an opening brace. Semicolons and closing
|
|
38
|
+
# braces flush declarations without interpreting them as selectors.
|
|
39
|
+
def parse_stylesheet(css)
|
|
40
|
+
scanner = StringScanner.new(css)
|
|
41
|
+
parts = []
|
|
42
|
+
prelude = +""
|
|
43
|
+
depth = 0
|
|
44
|
+
|
|
45
|
+
until scanner.eos?
|
|
46
|
+
if (literal = scanner.scan(PROTECTED))
|
|
47
|
+
prelude << literal
|
|
48
|
+
next
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
char = scanner.getch
|
|
52
|
+
case char
|
|
53
|
+
when "(", "["
|
|
54
|
+
depth += 1
|
|
55
|
+
when ")", "]"
|
|
56
|
+
depth -= 1
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
if depth.zero? && "{};".include?(char)
|
|
60
|
+
if char == "{"
|
|
61
|
+
parts.concat(parse_prelude(prelude))
|
|
62
|
+
else
|
|
63
|
+
parts << prelude
|
|
64
|
+
end
|
|
65
|
+
parts << char
|
|
66
|
+
prelude = +""
|
|
67
|
+
else
|
|
68
|
+
prelude << char
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
parts << prelude
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def parse_prelude(prelude)
|
|
76
|
+
rule = prelude.gsub(COMMENT, "").lstrip
|
|
77
|
+
scanner = StringScanner.new(prelude)
|
|
78
|
+
return parse_selector(scanner) unless rule.start_with?("@") && !rule.match?(/\A@scope\b/)
|
|
79
|
+
return [prelude] unless rule.match?(/\A@supports\b/)
|
|
80
|
+
|
|
81
|
+
parts = []
|
|
82
|
+
until scanner.eos?
|
|
83
|
+
if (literal = scanner.scan(PROTECTED))
|
|
84
|
+
parts << literal
|
|
85
|
+
elsif scanner.scan(/\bselector\(/)
|
|
86
|
+
parts << "selector("
|
|
87
|
+
parts.concat(parse_selector(scanner, closing: ")"))
|
|
88
|
+
parts << ")"
|
|
89
|
+
else
|
|
90
|
+
parts << scanner.getch
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
parts
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def parse_selector(scanner, local: true, closing: nil, scope_function: false)
|
|
97
|
+
parts = []
|
|
98
|
+
initial_scope = local
|
|
99
|
+
|
|
100
|
+
until scanner.eos?
|
|
101
|
+
if closing && scanner.scan(/#{Regexp.escape(closing)}/)
|
|
102
|
+
return parts
|
|
103
|
+
elsif (literal = scanner.scan(PROTECTED))
|
|
104
|
+
parts << literal
|
|
105
|
+
elsif scanner.scan(/\[/)
|
|
106
|
+
parts << "[" << read_attribute(scanner)
|
|
107
|
+
elsif scanner.scan(/:(global|local)\(/)
|
|
108
|
+
scope = scanner[1] == "local"
|
|
109
|
+
parts.concat(parse_selector(scanner, local: scope, closing: ")", scope_function: true))
|
|
110
|
+
elsif scanner.scan(/:(global|local)(?=\s)/)
|
|
111
|
+
local = scanner[1] == "local"
|
|
112
|
+
scanner.scan(/\s+/)
|
|
113
|
+
elsif scanner.scan(CLASS_SELECTOR)
|
|
114
|
+
name = scanner[1]
|
|
115
|
+
(local ? @local_classes : @global_classes) << name
|
|
116
|
+
parts << ClassSelector.new(name, local)
|
|
117
|
+
elsif scanner.scan(/\(/)
|
|
118
|
+
parts << "("
|
|
119
|
+
parts.concat(parse_selector(scanner, local: local, closing: ")"))
|
|
120
|
+
parts << ")"
|
|
121
|
+
elsif scanner.scan(/,/)
|
|
122
|
+
raise ArgumentError, "Use a separate :global(...) or :local(...) for each selector" if scope_function
|
|
123
|
+
|
|
124
|
+
local = initial_scope
|
|
125
|
+
parts << ","
|
|
126
|
+
else
|
|
127
|
+
parts << scanner.getch
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
raise ArgumentError, "Unclosed selector function in scoped CSS" if closing
|
|
132
|
+
|
|
133
|
+
parts
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def read_attribute(scanner)
|
|
137
|
+
value = +""
|
|
138
|
+
until scanner.eos?
|
|
139
|
+
if (literal = scanner.scan(PROTECTED))
|
|
140
|
+
value << literal
|
|
141
|
+
else
|
|
142
|
+
char = scanner.getch
|
|
143
|
+
value << char
|
|
144
|
+
break if char == "]"
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
value
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -9,6 +9,9 @@ module ViewComponent
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def print!(component_class)
|
|
12
|
+
bundle = component_class.stylesheet
|
|
13
|
+
filename = bundle ? "#{bundle}.scoped.css" : config.stylesheet_name
|
|
14
|
+
@stylesheet_path = Rails.root.join(config.assets_path, filename)
|
|
12
15
|
component_name = component_class.name
|
|
13
16
|
component_class.instance_variable_get(:@component_id)
|
|
14
17
|
styles = component_class.component_styles
|
|
@@ -29,6 +32,7 @@ module ViewComponent
|
|
|
29
32
|
|
|
30
33
|
def update_stylesheet_with(component_name, styles)
|
|
31
34
|
content = File.read(stylesheet_path)
|
|
35
|
+
content = content.sub(/\n\}\s*\z/, "\n") if config.components_layer
|
|
32
36
|
updated_content = merge_styles_into(content, component_name, styles)
|
|
33
37
|
|
|
34
38
|
write_atomically(updated_content)
|
|
@@ -91,11 +95,7 @@ module ViewComponent
|
|
|
91
95
|
content
|
|
92
96
|
end
|
|
93
97
|
|
|
94
|
-
|
|
95
|
-
@stylesheet_path ||= begin
|
|
96
|
-
Rails.root.join(config.assets_path, config.stylesheet_name)
|
|
97
|
-
end
|
|
98
|
-
end
|
|
98
|
+
attr_reader :stylesheet_path
|
|
99
99
|
|
|
100
100
|
def config
|
|
101
101
|
@config ||= ViewComponent::ScopedStyles.configuration
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
require_relative "scoped_styles/version"
|
|
4
4
|
require_relative "scoped_styles/configuration"
|
|
5
5
|
require_relative "scoped_styles/css_class_prefix"
|
|
6
|
+
require_relative "scoped_styles/css_selectors"
|
|
6
7
|
require "active_support/concern"
|
|
8
|
+
require "active_support/deprecation"
|
|
7
9
|
require "active_support/core_ext/enumerable"
|
|
8
10
|
require_relative "scoped_styles/concern"
|
|
9
11
|
require_relative "scoped_styles/stylist"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: view_component-scoped_styles
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Edwards
|
|
@@ -119,6 +119,7 @@ files:
|
|
|
119
119
|
- lib/view_component/scoped_styles/concern.rb
|
|
120
120
|
- lib/view_component/scoped_styles/configuration.rb
|
|
121
121
|
- lib/view_component/scoped_styles/css_class_prefix.rb
|
|
122
|
+
- lib/view_component/scoped_styles/css_selectors.rb
|
|
122
123
|
- lib/view_component/scoped_styles/railtie.rb
|
|
123
124
|
- lib/view_component/scoped_styles/stylist.rb
|
|
124
125
|
- lib/view_component/scoped_styles/stylist/writer.rb
|