rollup-plugin-react-scoped-css 0.8.4 → 1.0.0-alpha.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.
package/README.md CHANGED
@@ -34,24 +34,20 @@ And just like that the styles will be scoped to the component.
34
34
  ## Limitations
35
35
  Due to the way this plugin is working, it will apply the scope to the file and not the component individually... This may differ from other frameworks since they don't really let you define multiple components in the same file. This then means that if you have 2 components in the same file, the styles might conflict.
36
36
 
37
- ## Technicality
38
- since this plugin uses the engine of vue to scope the css to the components, the following sections come straight from the [vue documentation](https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors).
39
-
40
37
  ### Deep selector
41
- If you want a selector in scoped styles to be "deep", i.e. affecting child components, you can use the >>> combinator:
38
+ If you want a selector in scoped styles to be "deep", i.e. affecting child components, you can use the ::deep combinator:
42
39
  ```css
43
- .a >>> .b { /* ... */ }
40
+ .a:deep .b { /* ... */ }
44
41
  ```
45
42
  The above will be compiled into:
46
43
  ```css
47
44
  .a[data-v-f3f3eg9] .b { /* ... */ }
48
45
  ```
49
- Some pre-processors, such as Sass, may not be able to parse >>> properly. In those cases you can use the /deep/ or ::v-deep combinator instead - both are aliases for >>> and work exactly the same. Based on the example above these two expressions will be compiled to the same output:
46
+ Another exepted format, which will generate the same resutl, is:
50
47
  ```scss
51
48
  .a::v-deep .b { /* ... */ }
52
- /* or */
53
- .a /deep/ .b { /* ... */ }
54
49
  ```
50
+ This is primarly for backwards compatibility, we recommend the `:deep` selector.
55
51
  ### Dynamically Generated Content
56
52
  DOM content created with dangerouslySetInnerHTML are not affected by scoped styles, but you can still style them using deep selectors.
57
53
 
@@ -148,4 +144,4 @@ export default {
148
144
  ```
149
145
 
150
146
  ## Contributing
151
- Anyone is free to open a PR and contribute to this project... just be civilized!
147
+ Anyone is free to open a PR and contribute to this project... just be civilized!
@@ -0,0 +1 @@
1
+ export declare function scopeCss(css: string, filename: string, hash: string): string;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scopeCss = void 0;
4
+ const css_tree_1 = require("css-tree");
5
+ function scopeCss(css, filename, hash) {
6
+ try {
7
+ const ast = (0, css_tree_1.parse)(css);
8
+ const attributeSelector = {
9
+ type: "AttributeSelector",
10
+ name: { type: "Identifier", name: hash },
11
+ matcher: null,
12
+ value: null,
13
+ flags: null,
14
+ };
15
+ const selectorLists = ast.children.reduce((acc, node) => {
16
+ if (node.type === "Rule") {
17
+ if (node?.prelude?.type === "SelectorList") {
18
+ acc.push(node.prelude);
19
+ }
20
+ }
21
+ else if (node.type === "Atrule" && node.name === "media") {
22
+ node.block?.children.map((rule) => {
23
+ if (rule.type === "Rule" && rule.prelude.type === "SelectorList") {
24
+ acc.push(rule.prelude);
25
+ }
26
+ });
27
+ }
28
+ return acc;
29
+ }, []);
30
+ selectorLists.map((selectorList) => {
31
+ const results = (0, css_tree_1.findAll)(selectorList, (node) => node.type === "PseudoElementSelector" &&
32
+ (node.name === "v-deep" || node.name === "deep"));
33
+ if (results.length > 0) {
34
+ results.map((node) => {
35
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
36
+ //@ts-ignore: optimization hack, we need to override the object without changing the reference.
37
+ node.children = undefined;
38
+ node.loc = undefined;
39
+ Object.assign(node, attributeSelector);
40
+ });
41
+ }
42
+ else {
43
+ selectorList.children.forEach((selector) => {
44
+ if (selector.type === "Selector") {
45
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
46
+ // @ts-ignore: Tail is not exposed via @types/css-tree but does exist.
47
+ let item = selector.children.tail;
48
+ while (item !== null &&
49
+ (item?.data?.type === "PseudoClassSelector" ||
50
+ item?.data?.type === "PseudoElementSelector" ||
51
+ item?.data?.type === "Combinator")) {
52
+ item = item.prev;
53
+ }
54
+ selector.children.insertData(attributeSelector, item.next);
55
+ }
56
+ });
57
+ }
58
+ });
59
+ return (0, css_tree_1.generate)(ast);
60
+ }
61
+ catch (e) {
62
+ console.log(`Failed scoping css of file: ${filename}\n\nError:\n`, e);
63
+ return css;
64
+ }
65
+ }
66
+ exports.scopeCss = scopeCss;
package/dist/index.js CHANGED
@@ -5,9 +5,9 @@ exports.reactScopedCssPlugin = void 0;
5
5
  const path_1 = require("path");
6
6
  const js_xxhash_1 = require("js-xxhash");
7
7
  const pluginutils_1 = require("@rollup/pluginutils");
8
- const component_compiler_utils_1 = require("@vue/component-compiler-utils");
9
8
  const escodegen_1 = require("escodegen");
10
9
  const ast_program_1 = require("./ast-program");
10
+ const scope_css_1 = require("./css/scope-css");
11
11
  const getFilenameFromPath = (filePath) => {
12
12
  const parts = filePath.split("/");
13
13
  return parts[parts.length - 1].split("?")[0];
@@ -21,16 +21,6 @@ const generateHash = (input, seed = 0) => {
21
21
  const hashNum = (0, js_xxhash_1.xxHash32)(Buffer.from(input, "utf8"), seed);
22
22
  return hashNum.toString(16);
23
23
  };
24
- const addAttributesToCss = (src, fileName, hash) => {
25
- const { code } = (0, component_compiler_utils_1.compileStyle)({
26
- source: src,
27
- filename: fileName,
28
- id: hash,
29
- scoped: true,
30
- trim: true,
31
- });
32
- return code;
33
- };
34
24
  function reactScopedCssPlugin(optionsIn = {}) {
35
25
  const options = {
36
26
  hashPrefix: "v",
@@ -82,7 +72,7 @@ function reactScopedCssPlugin(optionsIn = {}) {
82
72
  }
83
73
  if (scopedCssRegex.test(getFilenameFromPath(id))) {
84
74
  const importerHash = getHashFromPath(id);
85
- return addAttributesToCss(code, getFilenameFromPath(id), `data-${options.hashPrefix}-${importerHash}`);
75
+ return (0, scope_css_1.scopeCss)(code, getFilenameFromPath(id), `data-${options.hashPrefix}-${importerHash}`);
86
76
  }
87
77
  },
88
78
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rollup-plugin-react-scoped-css",
3
- "version": "0.8.4",
3
+ "version": "1.0.0-alpha.0",
4
4
  "description": "A rollup plugin designed to allow scoped css to be run in react (Compatible with vite and rollup)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,7 +34,7 @@
34
34
  "homepage": "https://github.com/cmseguin/rollup-plugin-react-scoped-css#readme",
35
35
  "dependencies": {
36
36
  "@rollup/pluginutils": "5.0.2",
37
- "@vue/component-compiler-utils": "3.3.0",
37
+ "css-tree": "2.3.1",
38
38
  "escodegen": "2.0.0",
39
39
  "js-xxhash": "2.0.0",
40
40
  "rollup": "3.10.0"
@@ -49,6 +49,7 @@
49
49
  "@semantic-release/github": "8.0.7",
50
50
  "@semantic-release/npm": "11.0.1",
51
51
  "@semantic-release/release-notes-generator": "10.0.3",
52
+ "@types/css-tree": "^2.3.3",
52
53
  "@types/escodegen": "0.0.7",
53
54
  "@types/estree": "1.0.0",
54
55
  "@types/jest": "29.2.5",