storybook-addon-pseudo-states 1.15.2--canary.46.5e95e86.0 → 1.15.2

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.
@@ -3,14 +3,19 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.TOOL_ID = exports.PSEUDO_STATES = exports.ADDON_ID = void 0;
6
+ exports.TOOL_ID = exports.PSEUDO_STATES = exports.EXCLUDED_PSEUDO_ELEMENTS = exports.ADDON_ID = void 0;
7
7
  const ADDON_ID = "storybook/pseudo-states";
8
8
  exports.ADDON_ID = ADDON_ID;
9
9
  const TOOL_ID = `${ADDON_ID}/tool`;
10
10
 
11
+ // Pseudo-elements which are not allowed to have classes applied on them
12
+ // E.g. ::-webkit-scrollbar-thumb.pseudo-hover is not a valid selector
13
+ exports.TOOL_ID = TOOL_ID;
14
+ const EXCLUDED_PSEUDO_ELEMENTS = ["::-webkit-scrollbar-thumb"];
15
+
11
16
  // Dynamic pseudo-classes
12
17
  // @see https://www.w3.org/TR/2018/REC-selectors-3-20181106/#dynamic-pseudos
13
- exports.TOOL_ID = TOOL_ID;
18
+ exports.EXCLUDED_PSEUDO_ELEMENTS = EXCLUDED_PSEUDO_ELEMENTS;
14
19
  const PSEUDO_STATES = {
15
20
  hover: "hover",
16
21
  active: "active",
@@ -16,6 +16,7 @@ const warnOnce = message => {
16
16
  console.warn(message);
17
17
  warnings.add(message);
18
18
  };
19
+ const isExcludedPseudoElement = (selector, pseudoState) => _constants.EXCLUDED_PSEUDO_ELEMENTS.some(element => selector.endsWith(`${element}:${pseudoState}`));
19
20
  const rewriteRule = (cssText, selectorText, shadowRoot) => {
20
21
  return cssText.replace(selectorText, (0, _splitSelectors.splitSelectors)(selectorText).flatMap(selector => {
21
22
  if (selector.includes(".pseudo-")) {
@@ -29,12 +30,12 @@ const rewriteRule = (cssText, selectorText, shadowRoot) => {
29
30
  states.push(state);
30
31
  return "";
31
32
  });
32
- const classSelector = states.reduce((acc, state) => acc.replace(new RegExp(`:${state}`, "g"), `.pseudo-${state}`), selector);
33
+ const classSelector = states.reduce((acc, state) => !isExcludedPseudoElement(selector, state) && acc.replace(new RegExp(`(?<!Y):${state}`, "g"), `.pseudo-${state}`), selector);
33
34
  if (selector.startsWith(":host(") || selector.startsWith("::slotted(")) {
34
- return [selector, classSelector];
35
+ return [selector, classSelector].filter(Boolean);
35
36
  }
36
37
  const ancestorSelector = shadowRoot ? `:host(${states.map(s => `.pseudo-${s}`).join("")}) ${plainSelector}` : `${states.map(s => `.pseudo-${s}`).join("")} ${plainSelector}`;
37
- return [selector, classSelector, ancestorSelector].filter(selector => !selector.includes(":not()"));
38
+ return [selector, classSelector, ancestorSelector].filter(selector => selector && !selector.includes(":not()"));
38
39
  }).join(", "));
39
40
  };
40
41
 
@@ -30,6 +30,12 @@ describe("rewriteStyleSheet", () => {
30
30
  (0, _rewriteStyleSheet.rewriteStyleSheet)(sheet);
31
31
  expect(sheet.cssRules[0]).toContain(".pseudo-hover a");
32
32
  });
33
+ it("does not add .pseudo-<class> to pseudo-class, which does not support classes", () => {
34
+ const sheet = new Sheet("::-webkit-scrollbar-thumb:hover { border-color: transparent; }");
35
+ (0, _rewriteStyleSheet.rewriteStyleSheet)(sheet);
36
+ console.log(sheet.cssRules[0]);
37
+ expect(sheet.cssRules[0]).not.toContain("::-webkit-scrollbar-thumb.pseudo-hover");
38
+ });
33
39
  it("adds alternative selector for each pseudo selector", () => {
34
40
  const sheet = new Sheet("a:hover, a:focus { color: red }");
35
41
  (0, _rewriteStyleSheet.rewriteStyleSheet)(sheet);
@@ -14,10 +14,9 @@ const channel = _addons.addons.getChannel();
14
14
  const shadowHosts = new Set();
15
15
 
16
16
  // Drops any existing pseudo state classnames that carried over from a previously viewed story
17
- // before adding the new classnames. We use forEach for IE compatibility.
17
+ // before adding the new classnames. We do this the old-fashioned way, for IE compatibility.
18
18
  const applyClasses = (element, classnames) => {
19
- Object.values(_constants.PSEUDO_STATES).forEach(state => element.classList.remove(`pseudo-${state}`));
20
- classnames.forEach(classname => element.classList.add(classname));
19
+ element.className = element.className.split(" ").filter(classname => classname && classname.indexOf("pseudo-") !== 0).concat(...classnames).join(" ");
21
20
  };
22
21
  const applyParameter = (rootElement, parameter) => {
23
22
  const map = new Map([[rootElement, new Set()]]);
@@ -67,11 +66,6 @@ const withPseudoState = (StoryFn, _ref2) => {
67
66
  const {
68
67
  pseudo: globals
69
68
  } = globalsArgs;
70
- const canvasElement = (0, _addons.useMemo)(() => {
71
- viewMode === "docs" ? document.getElementById(`story--${id}`) : document.getElementById("storybook-root") ||
72
- // Storybook 7.0+
73
- document.getElementById("root");
74
- }, [viewMode, id]);
75
69
 
76
70
  // Sync parameter to globals, used by the toolbar (only in canvas as this
77
71
  // doesn't make sense for docs because many stories are displayed at once)
@@ -89,11 +83,12 @@ const withPseudoState = (StoryFn, _ref2) => {
89
83
  // Then update each shadow host to redetermine its own pseudo classnames.
90
84
  (0, _addons.useEffect)(() => {
91
85
  const timeout = setTimeout(() => {
92
- applyParameter(canvasElement, globals || parameter);
86
+ const element = document.getElementById(viewMode === "docs" ? `story--${id}` : `root`);
87
+ applyParameter(element, globals || parameter);
93
88
  shadowHosts.forEach(updateShadowHost);
94
89
  }, 0);
95
90
  return () => clearTimeout(timeout);
96
- }, [canvasElement, globals, parameter]);
91
+ }, [globals, parameter, viewMode]);
97
92
  return StoryFn();
98
93
  };
99
94
 
@@ -1,6 +1,10 @@
1
1
  export const ADDON_ID = "storybook/pseudo-states";
2
2
  export const TOOL_ID = `${ADDON_ID}/tool`;
3
3
 
4
+ // Pseudo-elements which are not allowed to have classes applied on them
5
+ // E.g. ::-webkit-scrollbar-thumb.pseudo-hover is not a valid selector
6
+ export const EXCLUDED_PSEUDO_ELEMENTS = ["::-webkit-scrollbar-thumb"];
7
+
4
8
  // Dynamic pseudo-classes
5
9
  // @see https://www.w3.org/TR/2018/REC-selectors-3-20181106/#dynamic-pseudos
6
10
  export const PSEUDO_STATES = {
@@ -1,4 +1,4 @@
1
- import { PSEUDO_STATES } from "./constants";
1
+ import { PSEUDO_STATES, EXCLUDED_PSEUDO_ELEMENTS } from "./constants";
2
2
  import { splitSelectors } from "./splitSelectors";
3
3
  const pseudoStates = Object.values(PSEUDO_STATES);
4
4
  const matchOne = new RegExp(`:(${pseudoStates.join("|")})`);
@@ -10,6 +10,7 @@ const warnOnce = message => {
10
10
  console.warn(message);
11
11
  warnings.add(message);
12
12
  };
13
+ const isExcludedPseudoElement = (selector, pseudoState) => EXCLUDED_PSEUDO_ELEMENTS.some(element => selector.endsWith(`${element}:${pseudoState}`));
13
14
  const rewriteRule = (cssText, selectorText, shadowRoot) => {
14
15
  return cssText.replace(selectorText, splitSelectors(selectorText).flatMap(selector => {
15
16
  if (selector.includes(".pseudo-")) {
@@ -23,12 +24,12 @@ const rewriteRule = (cssText, selectorText, shadowRoot) => {
23
24
  states.push(state);
24
25
  return "";
25
26
  });
26
- const classSelector = states.reduce((acc, state) => acc.replace(new RegExp(`:${state}`, "g"), `.pseudo-${state}`), selector);
27
+ const classSelector = states.reduce((acc, state) => !isExcludedPseudoElement(selector, state) && acc.replace(new RegExp(`(?<!Y):${state}`, "g"), `.pseudo-${state}`), selector);
27
28
  if (selector.startsWith(":host(") || selector.startsWith("::slotted(")) {
28
- return [selector, classSelector];
29
+ return [selector, classSelector].filter(Boolean);
29
30
  }
30
31
  const ancestorSelector = shadowRoot ? `:host(${states.map(s => `.pseudo-${s}`).join("")}) ${plainSelector}` : `${states.map(s => `.pseudo-${s}`).join("")} ${plainSelector}`;
31
- return [selector, classSelector, ancestorSelector].filter(selector => !selector.includes(":not()"));
32
+ return [selector, classSelector, ancestorSelector].filter(selector => selector && !selector.includes(":not()"));
32
33
  }).join(", "));
33
34
  };
34
35
 
@@ -28,6 +28,12 @@ describe("rewriteStyleSheet", () => {
28
28
  rewriteStyleSheet(sheet);
29
29
  expect(sheet.cssRules[0]).toContain(".pseudo-hover a");
30
30
  });
31
+ it("does not add .pseudo-<class> to pseudo-class, which does not support classes", () => {
32
+ const sheet = new Sheet("::-webkit-scrollbar-thumb:hover { border-color: transparent; }");
33
+ rewriteStyleSheet(sheet);
34
+ console.log(sheet.cssRules[0]);
35
+ expect(sheet.cssRules[0]).not.toContain("::-webkit-scrollbar-thumb.pseudo-hover");
36
+ });
31
37
  it("adds alternative selector for each pseudo selector", () => {
32
38
  const sheet = new Sheet("a:hover, a:focus { color: red }");
33
39
  rewriteStyleSheet(sheet);
@@ -1,5 +1,5 @@
1
1
  /* eslint-env browser */
2
- import { addons, useEffect, useMemo } from "@storybook/addons";
2
+ import { addons, useEffect } from "@storybook/addons";
3
3
  import { DOCS_RENDERED, STORY_CHANGED, STORY_RENDERED, UPDATE_GLOBALS } from "@storybook/core-events";
4
4
  import { PSEUDO_STATES } from "./constants";
5
5
  import { rewriteStyleSheet } from "./rewriteStyleSheet";
@@ -7,10 +7,9 @@ const channel = addons.getChannel();
7
7
  const shadowHosts = new Set();
8
8
 
9
9
  // Drops any existing pseudo state classnames that carried over from a previously viewed story
10
- // before adding the new classnames. We use forEach for IE compatibility.
10
+ // before adding the new classnames. We do this the old-fashioned way, for IE compatibility.
11
11
  const applyClasses = (element, classnames) => {
12
- Object.values(PSEUDO_STATES).forEach(state => element.classList.remove(`pseudo-${state}`));
13
- classnames.forEach(classname => element.classList.add(classname));
12
+ element.className = element.className.split(" ").filter(classname => classname && classname.indexOf("pseudo-") !== 0).concat(...classnames).join(" ");
14
13
  };
15
14
  const applyParameter = (rootElement, parameter) => {
16
15
  const map = new Map([[rootElement, new Set()]]);
@@ -60,11 +59,6 @@ export const withPseudoState = (StoryFn, _ref2) => {
60
59
  const {
61
60
  pseudo: globals
62
61
  } = globalsArgs;
63
- const canvasElement = useMemo(() => {
64
- viewMode === "docs" ? document.getElementById(`story--${id}`) : document.getElementById("storybook-root") ||
65
- // Storybook 7.0+
66
- document.getElementById("root");
67
- }, [viewMode, id]);
68
62
 
69
63
  // Sync parameter to globals, used by the toolbar (only in canvas as this
70
64
  // doesn't make sense for docs because many stories are displayed at once)
@@ -82,11 +76,12 @@ export const withPseudoState = (StoryFn, _ref2) => {
82
76
  // Then update each shadow host to redetermine its own pseudo classnames.
83
77
  useEffect(() => {
84
78
  const timeout = setTimeout(() => {
85
- applyParameter(canvasElement, globals || parameter);
79
+ const element = document.getElementById(viewMode === "docs" ? `story--${id}` : `root`);
80
+ applyParameter(element, globals || parameter);
86
81
  shadowHosts.forEach(updateShadowHost);
87
82
  }, 0);
88
83
  return () => clearTimeout(timeout);
89
- }, [canvasElement, globals, parameter]);
84
+ }, [globals, parameter, viewMode]);
90
85
  return StoryFn();
91
86
  };
92
87
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storybook-addon-pseudo-states",
3
- "version": "1.15.2--canary.46.5e95e86.0",
3
+ "version": "1.15.2",
4
4
  "description": "CSS pseudo states for Storybook",
5
5
  "keywords": [
6
6
  "storybook-addons",
@@ -34,15 +34,17 @@
34
34
  },
35
35
  "dependencies": {},
36
36
  "devDependencies": {
37
- "@babel/cli": "^7.12.1",
38
- "@babel/core": "^7.12.3",
39
- "@babel/preset-env": "^7.12.1",
40
- "@babel/preset-react": "^7.12.5",
41
- "@storybook/addon-docs": "^6.5.0",
42
- "@storybook/react": "^6.5.0",
37
+ "@babel/cli": "^7.19.3",
38
+ "@babel/core": "^7.20.5",
39
+ "@babel/preset-env": "^7.20.2",
40
+ "@babel/preset-react": "^7.18.6",
41
+ "@storybook/addon-docs": "^6.5.14",
42
+ "@storybook/builder-webpack5": "^6.5.14",
43
+ "@storybook/manager-webpack5": "^6.5.14",
44
+ "@storybook/react": "^6.5.14",
43
45
  "auto": "^10.16.8",
44
- "babel-loader": "^8.1.0",
45
- "chromatic": "^5.6.0",
46
+ "babel-loader": "^9.1.0",
47
+ "chromatic": "^6.12.0",
46
48
  "concurrently": "^5.3.0",
47
49
  "jest": "^27.5.1",
48
50
  "react": "^17.0.1",
package/CHANGELOG.md DELETED
@@ -1,93 +0,0 @@
1
- # v1.15.1 (Wed Jun 22 2022)
2
-
3
- #### 🐛 Bug Fix
4
-
5
- - Update react and react-dom peer dependencies level [#35](https://github.com/chromaui/storybook-addon-pseudo-states/pull/35) ([@dsueltenfuss](https://github.com/dsueltenfuss))
6
-
7
- #### Authors: 1
8
-
9
- - Dave Sueltenfuss ([@dsueltenfuss](https://github.com/dsueltenfuss))
10
-
11
- ---
12
-
13
- # v1.15.0 (Thu Jun 16 2022)
14
-
15
- #### 🚀 Enhancement
16
-
17
- - Add support for targeting specific elements [#25](https://github.com/chromaui/storybook-addon-pseudo-states/pull/25) (sagiv.bengiat@appsflyer.com [@ghengeveld](https://github.com/ghengeveld) [@sag1v](https://github.com/sag1v))
18
-
19
- #### Authors: 3
20
-
21
- - Gert Hengeveld ([@ghengeveld](https://github.com/ghengeveld))
22
- - Sagiv ben giat ([@sag1v](https://github.com/sag1v))
23
- - sagiv.bengiat (sagiv.bengiat@appsflyer.com)
24
-
25
- ---
26
-
27
- # v1.14.1 (Wed Jun 15 2022)
28
-
29
- #### ⚠️ Pushed to `main`
30
-
31
- - Fix toolbar toggles ([@ghengeveld](https://github.com/ghengeveld))
32
- - Upgrade Storybook ([@ghengeveld](https://github.com/ghengeveld))
33
-
34
- #### Authors: 1
35
-
36
- - Gert Hengeveld ([@ghengeveld](https://github.com/ghengeveld))
37
-
38
- ---
39
-
40
- # v1.0.0 (Tue May 24 2022)
41
-
42
- #### 🚀 Enhancement
43
-
44
- - Merge branch 'main' into feature/docs-support [#20](https://github.com/chromaui/storybook-addon-pseudo-states/pull/20) ([@ghengeveld](https://github.com/ghengeveld))
45
- - Add support for custom elements using `:host(:hover)` like styling. [#17](https://github.com/chromaui/storybook-addon-pseudo-states/pull/17) (jeroen.zwartepoorte@iddinkgroup.com [@ghengeveld](https://github.com/ghengeveld))
46
-
47
- #### 🐛 Bug Fix
48
-
49
- - fix: only generate pseudo selector when the selector has a match [#30](https://github.com/chromaui/storybook-addon-pseudo-states/pull/30) ([@tobi-or-not-tobi](https://github.com/tobi-or-not-tobi) [@ghengeveld](https://github.com/ghengeveld))
50
- - Use personal access token to be able to push to main ([@ghengeveld](https://github.com/ghengeveld))
51
- - fix: Resolve crash for stories that use internal State [#28](https://github.com/chromaui/storybook-addon-pseudo-states/pull/28) (david.maulick@coinbase.com)
52
- - Fix CSS selector splitting [#24](https://github.com/chromaui/storybook-addon-pseudo-states/pull/24) ([@ilanus](https://github.com/ilanus) [@ghengeveld](https://github.com/ghengeveld))
53
- - Add support for slotted lit elements [#23](https://github.com/chromaui/storybook-addon-pseudo-states/pull/23) ([@ilanus](https://github.com/ilanus))
54
- - Setup auto [#7](https://github.com/chromaui/storybook-addon-pseudo-states/pull/7) ([@ghengeveld](https://github.com/ghengeveld))
55
-
56
- #### ⚠️ Pushed to `main`
57
-
58
- - Update config to checkout repo using personal access token ([@ghengeveld](https://github.com/ghengeveld))
59
- - Use chromatic@next ([@ghengeveld](https://github.com/ghengeveld))
60
- - [skip release] Revert back to disabling CustomElement stories ([@ghengeveld](https://github.com/ghengeveld))
61
- - Another attempt at dealing with IE ([@ghengeveld](https://github.com/ghengeveld))
62
- - Don't disable stories, just ignore IE ([@ghengeveld](https://github.com/ghengeveld))
63
- - Fix missing parameter ([@ghengeveld](https://github.com/ghengeveld))
64
- - Disable snapshotting for CustomElements stories ([@ghengeveld](https://github.com/ghengeveld))
65
- - 1.1.0 ([@ghengeveld](https://github.com/ghengeveld))
66
- - Simplify ([@ghengeveld](https://github.com/ghengeveld))
67
- - Small tweak ([@ghengeveld](https://github.com/ghengeveld))
68
- - Upgrade Storybook ([@ghengeveld](https://github.com/ghengeveld))
69
- - Ignore .env file ([@ghengeveld](https://github.com/ghengeveld))
70
-
71
- #### Authors: 5
72
-
73
- - David Maulick ([@dmaulick](https://github.com/dmaulick))
74
- - Gert Hengeveld ([@ghengeveld](https://github.com/ghengeveld))
75
- - Ilan ([@ilanus](https://github.com/ilanus))
76
- - Jeroen Zwartepoorte ([@jpzwarte](https://github.com/jpzwarte))
77
- - tobi-or-not-tobi ([@tobi-or-not-tobi](https://github.com/tobi-or-not-tobi))
78
-
79
- ---
80
-
81
- # v1.0.0 (Sat Feb 27 2021)
82
-
83
- #### 🐛 Bug Fix
84
-
85
- - Setup auto [#7](https://github.com/chromaui/storybook-addon-pseudo-states/pull/7) ([@ghengeveld](https://github.com/ghengeveld))
86
-
87
- #### ⚠️ Pushed to `main`
88
-
89
- - Ignore .env file ([@ghengeveld](https://github.com/ghengeveld))
90
-
91
- #### Authors: 1
92
-
93
- - Gert Hengeveld ([@ghengeveld](https://github.com/ghengeveld))