storybook-addon-pseudo-states 1.15.0 → 1.15.2--canary.45.07abc1b.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.
@@ -1,82 +1,66 @@
1
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
-
3
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
4
-
5
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
6
-
7
1
  import { rewriteStyleSheet } from "./rewriteStyleSheet";
8
-
9
- var Sheet = /*#__PURE__*/function () {
10
- function Sheet() {
11
- _classCallCheck(this, Sheet);
12
-
2
+ class Sheet {
3
+ constructor() {
13
4
  this.__pseudoStatesRewritten = false;
14
-
15
5
  for (var _len = arguments.length, rules = new Array(_len), _key = 0; _key < _len; _key++) {
16
6
  rules[_key] = arguments[_key];
17
7
  }
18
-
19
- this.cssRules = rules.map(function (cssText) {
20
- return {
21
- cssText: cssText,
22
- selectorText: cssText.slice(0, cssText.indexOf(" {"))
23
- };
24
- });
8
+ this.cssRules = rules.map(cssText => ({
9
+ cssText,
10
+ selectorText: cssText.slice(0, cssText.indexOf(" {"))
11
+ }));
25
12
  }
26
-
27
- _createClass(Sheet, [{
28
- key: "deleteRule",
29
- value: function deleteRule(index) {
30
- this.cssRules.splice(index, 1);
31
- }
32
- }, {
33
- key: "insertRule",
34
- value: function insertRule(cssText, index) {
35
- this.cssRules.splice(index, 0, cssText);
36
- }
37
- }]);
38
-
39
- return Sheet;
40
- }();
41
-
42
- describe("rewriteStyleSheet", function () {
43
- it("adds alternative selector targeting the element directly", function () {
44
- var sheet = new Sheet("a:hover { color: red }");
13
+ deleteRule(index) {
14
+ this.cssRules.splice(index, 1);
15
+ }
16
+ insertRule(cssText, index) {
17
+ this.cssRules.splice(index, 0, cssText);
18
+ }
19
+ }
20
+ describe("rewriteStyleSheet", () => {
21
+ it("adds alternative selector targeting the element directly", () => {
22
+ const sheet = new Sheet("a:hover { color: red }");
45
23
  rewriteStyleSheet(sheet);
46
24
  expect(sheet.cssRules[0]).toContain("a.pseudo-hover");
47
25
  });
48
- it("adds alternative selector targeting an ancestor", function () {
49
- var sheet = new Sheet("a:hover { color: red }");
26
+ it("adds alternative selector targeting an ancestor", () => {
27
+ const sheet = new Sheet("a:hover { color: red }");
50
28
  rewriteStyleSheet(sheet);
51
29
  expect(sheet.cssRules[0]).toContain(".pseudo-hover a");
52
30
  });
53
- it("adds alternative selector for each pseudo selector", function () {
54
- var sheet = new Sheet("a:hover, a:focus { color: red }");
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
+ });
37
+ it("adds alternative selector for each pseudo selector", () => {
38
+ const sheet = new Sheet("a:hover, a:focus { color: red }");
55
39
  rewriteStyleSheet(sheet);
56
40
  expect(sheet.cssRules[0]).toContain("a.pseudo-hover");
57
41
  expect(sheet.cssRules[0]).toContain("a.pseudo-focus");
58
42
  expect(sheet.cssRules[0]).toContain(".pseudo-hover a");
59
43
  expect(sheet.cssRules[0]).toContain(".pseudo-focus a");
60
44
  });
61
- it("keeps non-pseudo selectors as-is", function () {
62
- var sheet = new Sheet("a.class, a:hover, a:focus, a#id { color: red }");
45
+ it("keeps non-pseudo selectors as-is", () => {
46
+ const sheet = new Sheet("a.class, a:hover, a:focus, a#id { color: red }");
63
47
  rewriteStyleSheet(sheet);
64
48
  expect(sheet.cssRules[0]).toContain("a.class");
65
49
  expect(sheet.cssRules[0]).toContain("a#id");
66
50
  });
67
- it("supports combined pseudo selectors", function () {
68
- var sheet = new Sheet("a:hover:focus { color: red }");
51
+ it("supports combined pseudo selectors", () => {
52
+ const sheet = new Sheet("a:hover:focus { color: red }");
69
53
  rewriteStyleSheet(sheet);
70
54
  expect(sheet.cssRules[0]).toContain("a.pseudo-hover.pseudo-focus");
71
55
  expect(sheet.cssRules[0]).toContain(".pseudo-hover.pseudo-focus a");
72
56
  });
73
- it('supports ":host"', function () {
74
- var sheet = new Sheet(":host(:hover) { color: red }");
57
+ it('supports ":host"', () => {
58
+ const sheet = new Sheet(":host(:hover) { color: red }");
75
59
  rewriteStyleSheet(sheet);
76
60
  expect(sheet.cssRules[0]).toEqual(":host(:hover), :host(.pseudo-hover) { color: red }");
77
61
  });
78
- it('supports ":not"', function () {
79
- var sheet = new Sheet(":not(:hover) { color: red }");
62
+ it('supports ":not"', () => {
63
+ const sheet = new Sheet(":not(:hover) { color: red }");
80
64
  rewriteStyleSheet(sheet);
81
65
  expect(sheet.cssRules[0]).toEqual(":not(:hover), :not(.pseudo-hover) { color: red }");
82
66
  });
@@ -1,17 +1,12 @@
1
- var isAtRule = function isAtRule(selector) {
2
- return selector.indexOf("@") === 0;
3
- };
4
-
5
- export var splitSelectors = function splitSelectors(selectors) {
1
+ const isAtRule = selector => selector.indexOf("@") === 0;
2
+ export const splitSelectors = selectors => {
6
3
  if (isAtRule(selectors)) return [selectors];
7
- var result = [];
8
- var parentheses = 0;
9
- var brackets = 0;
10
- var selector = "";
11
-
12
- for (var i = 0, len = selectors.length; i < len; i++) {
13
- var char = selectors[i];
14
-
4
+ let result = [];
5
+ let parentheses = 0;
6
+ let brackets = 0;
7
+ let selector = "";
8
+ for (let i = 0, len = selectors.length; i < len; i++) {
9
+ const char = selectors[i];
15
10
  if (char === "(") {
16
11
  parentheses += 1;
17
12
  } else if (char === ")") {
@@ -27,10 +22,8 @@ export var splitSelectors = function splitSelectors(selectors) {
27
22
  continue;
28
23
  }
29
24
  }
30
-
31
25
  selector += char;
32
26
  }
33
-
34
27
  result.push(selector.trim());
35
28
  return result;
36
29
  };
@@ -1,14 +1,14 @@
1
1
  import { splitSelectors } from "./splitSelectors";
2
- describe("splitSelectors", function () {
3
- test("handles basic selectors", function () {
2
+ describe("splitSelectors", () => {
3
+ test("handles basic selectors", () => {
4
4
  expect(splitSelectors(".a")).toEqual([".a"]);
5
5
  expect(splitSelectors(".a, .b")).toEqual([".a", ".b"]);
6
6
  });
7
- test("supports ::slotted and :is", function () {
7
+ test("supports ::slotted and :is", () => {
8
8
  expect(splitSelectors("::slotted(:is(button, a):active)")).toEqual(["::slotted(:is(button, a):active)"]);
9
9
  expect(splitSelectors("::slotted(:is(button, a):active), ::slotted(:is(button, a):hover)")).toEqual(["::slotted(:is(button, a):active)", "::slotted(:is(button, a):hover)"]);
10
10
  });
11
- test("supports :host", function () {
11
+ test("supports :host", () => {
12
12
  expect(splitSelectors(":host([type='secondary']) ::slotted(:is(button, a)), :host([type='primary']) ::slotted(:is(button, a):active)")).toEqual([":host([type='secondary']) ::slotted(:is(button, a))", ":host([type='primary']) ::slotted(:is(button, a):active)"]);
13
13
  expect(splitSelectors(":host([outline]) ::slotted(:is(button, a):focus-within:focus-visible:not(:active))")).toEqual([":host([outline]) ::slotted(:is(button, a):focus-within:focus-visible:not(:active))"]);
14
14
  });
@@ -1,112 +1,68 @@
1
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
-
3
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
-
5
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
-
7
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
8
-
9
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
10
-
11
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
12
-
13
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
14
-
15
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
16
-
17
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
18
-
19
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
20
-
21
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
22
-
23
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
24
-
25
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
26
-
27
1
  /* eslint-env browser */
28
2
  import { addons, useEffect } from "@storybook/addons";
29
3
  import { DOCS_RENDERED, STORY_CHANGED, STORY_RENDERED, UPDATE_GLOBALS } from "@storybook/core-events";
30
4
  import { PSEUDO_STATES } from "./constants";
31
5
  import { rewriteStyleSheet } from "./rewriteStyleSheet";
32
- var channel = addons.getChannel();
33
- var shadowHosts = new Set(); // Drops any existing pseudo state classnames that carried over from a previously viewed story
34
- // before adding the new classnames. We do this the old-fashioned way, for IE compatibility.
35
-
36
- var applyClasses = function applyClasses(element, classnames) {
37
- var _element$className$sp;
6
+ const channel = addons.getChannel();
7
+ const shadowHosts = new Set();
38
8
 
39
- element.className = (_element$className$sp = element.className.split(" ").filter(function (classname) {
40
- return classname && classname.indexOf("pseudo-") !== 0;
41
- })).concat.apply(_element$className$sp, _toConsumableArray(classnames)).join(" ");
9
+ // Drops any existing pseudo state classnames that carried over from a previously viewed story
10
+ // before adding the new classnames. We do this the old-fashioned way, for IE compatibility.
11
+ const applyClasses = (element, classnames) => {
12
+ element.className = element.className.split(" ").filter(classname => classname && classname.indexOf("pseudo-") !== 0).concat(...classnames).join(" ");
42
13
  };
43
-
44
- var applyParameter = function applyParameter(rootElement, parameter) {
45
- var map = new Map([[rootElement, new Set()]]);
46
-
47
- var add = function add(target, state) {
48
- return map.set(target, new Set([].concat(_toConsumableArray(map.get(target) || []), [state])));
49
- };
50
-
51
- Object.entries(parameter || {}).forEach(function (_ref) {
52
- var _ref2 = _slicedToArray(_ref, 2),
53
- state = _ref2[0],
54
- value = _ref2[1];
55
-
14
+ const applyParameter = (rootElement, parameter) => {
15
+ const map = new Map([[rootElement, new Set()]]);
16
+ const add = (target, state) => map.set(target, new Set([...(map.get(target) || []), state]));
17
+ Object.entries(parameter || {}).forEach(_ref => {
18
+ let [state, value] = _ref;
56
19
  if (typeof value === "boolean") {
57
20
  // default API - applying pseudo class to root element.
58
21
  add(rootElement, value && state);
59
22
  } else if (typeof value === "string") {
60
23
  // explicit selectors API - applying pseudo class to a specific element
61
- rootElement.querySelectorAll(value).forEach(function (el) {
62
- return add(el, state);
63
- });
24
+ rootElement.querySelectorAll(value).forEach(el => add(el, state));
64
25
  } else if (Array.isArray(value)) {
65
26
  // explicit selectors API - we have an array (of strings) recursively handle each one
66
- value.forEach(function (sel) {
67
- return rootElement.querySelectorAll(sel).forEach(function (el) {
68
- return add(el, state);
69
- });
70
- });
27
+ value.forEach(sel => rootElement.querySelectorAll(sel).forEach(el => add(el, state)));
71
28
  }
72
29
  });
73
- map.forEach(function (states, target) {
74
- var classnames = [];
75
- states.forEach(function (key) {
76
- return PSEUDO_STATES[key] && classnames.push("pseudo-".concat(PSEUDO_STATES[key]));
77
- });
30
+ map.forEach((states, target) => {
31
+ const classnames = [];
32
+ states.forEach(key => PSEUDO_STATES[key] && classnames.push(`pseudo-${PSEUDO_STATES[key]}`));
78
33
  applyClasses(target, classnames);
79
34
  });
80
- }; // Traverses ancestry to collect relevant pseudo classnames, and applies them to the shadow host.
81
- // Shadow DOM can only access classes on its host. Traversing is needed to mimic the CSS cascade.
82
-
83
-
84
- var updateShadowHost = function updateShadowHost(shadowHost) {
85
- var classnames = new Set();
35
+ };
86
36
 
87
- for (var element = shadowHost.parentElement; element; element = element.parentElement) {
37
+ // Traverses ancestry to collect relevant pseudo classnames, and applies them to the shadow host.
38
+ // Shadow DOM can only access classes on its host. Traversing is needed to mimic the CSS cascade.
39
+ const updateShadowHost = shadowHost => {
40
+ const classnames = new Set();
41
+ for (let element = shadowHost.parentElement; element; element = element.parentElement) {
88
42
  if (!element.className) continue;
89
- element.className.split(" ").filter(function (classname) {
90
- return classname.indexOf("pseudo-") === 0;
91
- }).forEach(function (classname) {
92
- return classnames.add(classname);
93
- });
43
+ element.className.split(" ").filter(classname => classname.indexOf("pseudo-") === 0).forEach(classname => classnames.add(classname));
94
44
  }
95
-
96
45
  applyClasses(shadowHost, classnames);
97
- }; // Global decorator that rewrites stylesheets and applies classnames to render pseudo styles
98
-
46
+ };
99
47
 
100
- export var withPseudoState = function withPseudoState(StoryFn, _ref3) {
101
- var viewMode = _ref3.viewMode,
102
- parameters = _ref3.parameters,
103
- id = _ref3.id,
104
- globalsArgs = _ref3.globals;
105
- var parameter = parameters.pseudo;
106
- var globals = globalsArgs.pseudo; // Sync parameter to globals, used by the toolbar (only in canvas as this
48
+ // Global decorator that rewrites stylesheets and applies classnames to render pseudo styles
49
+ export const withPseudoState = (StoryFn, _ref2) => {
50
+ let {
51
+ viewMode,
52
+ parameters,
53
+ id,
54
+ globals: globalsArgs
55
+ } = _ref2;
56
+ const {
57
+ pseudo: parameter
58
+ } = parameters;
59
+ const {
60
+ pseudo: globals
61
+ } = globalsArgs;
62
+
63
+ // Sync parameter to globals, used by the toolbar (only in canvas as this
107
64
  // doesn't make sense for docs because many stories are displayed at once)
108
-
109
- useEffect(function () {
65
+ useEffect(() => {
110
66
  if (parameter !== globals && viewMode === "story") {
111
67
  channel.emit(UPDATE_GLOBALS, {
112
68
  globals: {
@@ -114,57 +70,49 @@ export var withPseudoState = function withPseudoState(StoryFn, _ref3) {
114
70
  }
115
71
  });
116
72
  }
117
- }, [parameter, viewMode]); // Convert selected states to classnames and apply them to the story root element.
118
- // Then update each shadow host to redetermine its own pseudo classnames.
73
+ }, [parameter, viewMode]);
119
74
 
120
- useEffect(function () {
121
- var timeout = setTimeout(function () {
122
- var element = document.getElementById(viewMode === "docs" ? "story--".concat(id) : "root");
75
+ // Convert selected states to classnames and apply them to the story root element.
76
+ // Then update each shadow host to redetermine its own pseudo classnames.
77
+ useEffect(() => {
78
+ const timeout = setTimeout(() => {
79
+ const element = document.getElementById(viewMode === "docs" ? `story--${id}` : `root`);
123
80
  applyParameter(element, globals || parameter);
124
81
  shadowHosts.forEach(updateShadowHost);
125
82
  }, 0);
126
- return function () {
127
- return clearTimeout(timeout);
128
- };
83
+ return () => clearTimeout(timeout);
129
84
  }, [globals, parameter, viewMode]);
130
85
  return StoryFn();
131
- }; // Rewrite CSS rules for pseudo-states on all stylesheets to add an alternative selector
132
-
133
- var rewriteStyleSheets = function rewriteStyleSheets(shadowRoot) {
134
- var _shadowRoot$adoptedSt;
135
-
136
- var styleSheets = shadowRoot ? shadowRoot.styleSheets : document.styleSheets;
137
- if (shadowRoot !== null && shadowRoot !== void 0 && (_shadowRoot$adoptedSt = shadowRoot.adoptedStyleSheets) !== null && _shadowRoot$adoptedSt !== void 0 && _shadowRoot$adoptedSt.length) styleSheets = shadowRoot.adoptedStyleSheets;
138
- Array.from(styleSheets).forEach(function (sheet) {
139
- return rewriteStyleSheet(sheet, shadowRoot, shadowHosts);
140
- });
141
- }; // Only track shadow hosts for the current story
86
+ };
142
87
 
88
+ // Rewrite CSS rules for pseudo-states on all stylesheets to add an alternative selector
89
+ const rewriteStyleSheets = shadowRoot => {
90
+ let styleSheets = shadowRoot ? shadowRoot.styleSheets : document.styleSheets;
91
+ if (shadowRoot?.adoptedStyleSheets?.length) styleSheets = shadowRoot.adoptedStyleSheets;
92
+ Array.from(styleSheets).forEach(sheet => rewriteStyleSheet(sheet, shadowRoot, shadowHosts));
93
+ };
143
94
 
144
- channel.on(STORY_CHANGED, function () {
145
- return shadowHosts.clear();
146
- }); // Reinitialize CSS enhancements every time the story changes
95
+ // Only track shadow hosts for the current story
96
+ channel.on(STORY_CHANGED, () => shadowHosts.clear());
147
97
 
148
- channel.on(STORY_RENDERED, function () {
149
- return rewriteStyleSheets();
150
- }); // Reinitialize CSS enhancements every time a docs page is rendered
98
+ // Reinitialize CSS enhancements every time the story changes
99
+ channel.on(STORY_RENDERED, () => rewriteStyleSheets());
151
100
 
152
- channel.on(DOCS_RENDERED, function () {
153
- return rewriteStyleSheets();
154
- }); // IE doesn't support shadow DOM
101
+ // Reinitialize CSS enhancements every time a docs page is rendered
102
+ channel.on(DOCS_RENDERED, () => rewriteStyleSheets());
155
103
 
104
+ // IE doesn't support shadow DOM
156
105
  if (Element.prototype.attachShadow) {
157
106
  // Monkeypatch the attachShadow method so we can handle pseudo styles inside shadow DOM
158
107
  Element.prototype._attachShadow = Element.prototype.attachShadow;
159
-
160
108
  Element.prototype.attachShadow = function attachShadow(init) {
161
109
  // Force "open" mode, so we can access the shadowRoot
162
- var shadowRoot = this._attachShadow(_objectSpread(_objectSpread({}, init), {}, {
110
+ const shadowRoot = this._attachShadow({
111
+ ...init,
163
112
  mode: "open"
164
- })); // Wait for it to render and apply its styles before rewriting them
165
-
166
-
167
- requestAnimationFrame(function () {
113
+ });
114
+ // Wait for it to render and apply its styles before rewriting them
115
+ requestAnimationFrame(() => {
168
116
  rewriteStyleSheets(shadowRoot);
169
117
  updateShadowHost(shadowRoot.host);
170
118
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storybook-addon-pseudo-states",
3
- "version": "1.15.0",
3
+ "version": "1.15.2--canary.45.07abc1b.0",
4
4
  "description": "CSS pseudo states for Storybook",
5
5
  "keywords": [
6
6
  "storybook-addons",
@@ -55,8 +55,8 @@
55
55
  "@storybook/components": "^6.5.0",
56
56
  "@storybook/core-events": "^6.5.0",
57
57
  "@storybook/theming": "^6.5.0",
58
- "react": "^16.8.0 || ^17.0.0",
59
- "react-dom": "^16.8.0 || ^17.0.0"
58
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
59
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
60
60
  },
61
61
  "peerDependenciesMeta": {
62
62
  "react": {