storybook-addon-pseudo-states 1.8.0 → 1.11.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/CHANGELOG.md +6 -2
- package/dist/cjs/splitSelectors.js +45 -0
- package/dist/cjs/splitSelectors.test.js +18 -0
- package/dist/cjs/withPseudoState.js +15 -9
- package/dist/esm/splitSelectors.js +36 -0
- package/dist/esm/splitSelectors.test.js +15 -0
- package/dist/esm/withPseudoState.js +16 -12
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# v1.0.0 (
|
|
1
|
+
# v1.0.0 (Mon May 23 2022)
|
|
2
2
|
|
|
3
3
|
#### 🚀 Enhancement
|
|
4
4
|
|
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
#### 🐛 Bug Fix
|
|
9
9
|
|
|
10
|
+
- fix: Resolve crash for stories that use internal State [#28](https://github.com/chromaui/storybook-addon-pseudo-states/pull/28) (david.maulick@coinbase.com)
|
|
11
|
+
- 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))
|
|
10
12
|
- Add support for slotted lit elements [#23](https://github.com/chromaui/storybook-addon-pseudo-states/pull/23) ([@ilanus](https://github.com/ilanus))
|
|
11
13
|
- Setup auto [#7](https://github.com/chromaui/storybook-addon-pseudo-states/pull/7) ([@ghengeveld](https://github.com/ghengeveld))
|
|
12
14
|
|
|
13
15
|
#### ⚠️ Pushed to `main`
|
|
14
16
|
|
|
17
|
+
- Use chromatic@next ([@ghengeveld](https://github.com/ghengeveld))
|
|
15
18
|
- [skip release] Revert back to disabling CustomElement stories ([@ghengeveld](https://github.com/ghengeveld))
|
|
16
19
|
- Another attempt at dealing with IE ([@ghengeveld](https://github.com/ghengeveld))
|
|
17
20
|
- Don't disable stories, just ignore IE ([@ghengeveld](https://github.com/ghengeveld))
|
|
@@ -23,8 +26,9 @@
|
|
|
23
26
|
- Upgrade Storybook ([@ghengeveld](https://github.com/ghengeveld))
|
|
24
27
|
- Ignore .env file ([@ghengeveld](https://github.com/ghengeveld))
|
|
25
28
|
|
|
26
|
-
#### Authors:
|
|
29
|
+
#### Authors: 4
|
|
27
30
|
|
|
31
|
+
- David Maulick ([@dmaulick](https://github.com/dmaulick))
|
|
28
32
|
- Gert Hengeveld ([@ghengeveld](https://github.com/ghengeveld))
|
|
29
33
|
- Ilan ([@ilanus](https://github.com/ilanus))
|
|
30
34
|
- Jeroen Zwartepoorte ([@jpzwarte](https://github.com/jpzwarte))
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.splitSelectors = void 0;
|
|
7
|
+
|
|
8
|
+
var isAtRule = function isAtRule(selector) {
|
|
9
|
+
return selector.indexOf("@") === 0;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
var splitSelectors = function splitSelectors(selectors) {
|
|
13
|
+
if (isAtRule(selectors)) return [selectors];
|
|
14
|
+
var result = [];
|
|
15
|
+
var parentheses = 0;
|
|
16
|
+
var brackets = 0;
|
|
17
|
+
var selector = "";
|
|
18
|
+
|
|
19
|
+
for (var i = 0, len = selectors.length; i < len; i++) {
|
|
20
|
+
var char = selectors[i];
|
|
21
|
+
|
|
22
|
+
if (char === "(") {
|
|
23
|
+
parentheses += 1;
|
|
24
|
+
} else if (char === ")") {
|
|
25
|
+
parentheses -= 1;
|
|
26
|
+
} else if (char === "[") {
|
|
27
|
+
brackets += 1;
|
|
28
|
+
} else if (char === "]") {
|
|
29
|
+
brackets -= 1;
|
|
30
|
+
} else if (char === ",") {
|
|
31
|
+
if (!parentheses && !brackets) {
|
|
32
|
+
result.push(selector.trim());
|
|
33
|
+
selector = "";
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
selector += char;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
result.push(selector.trim());
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
exports.splitSelectors = splitSelectors;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _splitSelectors = require("./splitSelectors");
|
|
4
|
+
|
|
5
|
+
describe("splitSelectors", function () {
|
|
6
|
+
test("handles basic selectors", function () {
|
|
7
|
+
expect((0, _splitSelectors.splitSelectors)(".a")).toEqual([".a"]);
|
|
8
|
+
expect((0, _splitSelectors.splitSelectors)(".a, .b")).toEqual([".a", ".b"]);
|
|
9
|
+
});
|
|
10
|
+
test("supports ::slotted and :is", function () {
|
|
11
|
+
expect((0, _splitSelectors.splitSelectors)("::slotted(:is(button, a):active)")).toEqual(["::slotted(:is(button, a):active)"]);
|
|
12
|
+
expect((0, _splitSelectors.splitSelectors)("::slotted(:is(button, a):active), ::slotted(:is(button, a):hover)")).toEqual(["::slotted(:is(button, a):active)", "::slotted(:is(button, a):hover)"]);
|
|
13
|
+
});
|
|
14
|
+
test("supports :host", function () {
|
|
15
|
+
expect((0, _splitSelectors.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)"]);
|
|
16
|
+
expect((0, _splitSelectors.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))"]);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -11,6 +11,8 @@ var _coreEvents = require("@storybook/core-events");
|
|
|
11
11
|
|
|
12
12
|
var _constants = require("./constants");
|
|
13
13
|
|
|
14
|
+
var _splitSelectors = require("./splitSelectors");
|
|
15
|
+
|
|
14
16
|
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; }
|
|
15
17
|
|
|
16
18
|
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; }
|
|
@@ -95,20 +97,23 @@ _addons.addons.getChannel().on(_coreEvents.STORY_CHANGED, function () {
|
|
|
95
97
|
var withPseudoState = function withPseudoState(StoryFn, _ref5) {
|
|
96
98
|
var viewMode = _ref5.viewMode,
|
|
97
99
|
parameters = _ref5.parameters,
|
|
98
|
-
id = _ref5.id
|
|
100
|
+
id = _ref5.id,
|
|
101
|
+
globalsArgs = _ref5.globals;
|
|
99
102
|
var parameter = parameters.pseudo;
|
|
103
|
+
var globals = globalsArgs.pseudo;
|
|
100
104
|
|
|
101
|
-
var
|
|
102
|
-
_useGlobals2 = _slicedToArray(_useGlobals, 2),
|
|
103
|
-
globals = _useGlobals2[0].pseudo,
|
|
104
|
-
updateGlobals = _useGlobals2[1]; // Sync parameter to globals, used by the toolbar (only in canvas as this
|
|
105
|
+
var channel = _addons.addons.getChannel(); // Sync parameter to globals, used by the toolbar (only in canvas as this
|
|
105
106
|
// doesn't make sense for docs because many stories are displayed at once)
|
|
106
107
|
|
|
107
108
|
|
|
108
109
|
(0, _addons.useEffect)(function () {
|
|
109
|
-
if (parameter !== globals && viewMode === "story")
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
if (parameter !== globals && viewMode === "story") {
|
|
111
|
+
channel.emit(_coreEvents.UPDATE_GLOBALS, {
|
|
112
|
+
globals: {
|
|
113
|
+
pseudo: parameter
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
112
117
|
}, [parameter, viewMode]); // Convert selected states to classnames and apply them to the story root element.
|
|
113
118
|
// Then update each shadow host to redetermine its own pseudo classnames.
|
|
114
119
|
|
|
@@ -168,7 +173,8 @@ function rewriteStyleSheets(shadowRoot) {
|
|
|
168
173
|
selectorText = _step2$value.selectorText;
|
|
169
174
|
|
|
170
175
|
if (matchOne.test(selectorText)) {
|
|
171
|
-
var
|
|
176
|
+
var selectors = (0, _splitSelectors.splitSelectors)(selectorText);
|
|
177
|
+
var newRule = cssText.replace(selectorText, selectors.flatMap(function (selector) {
|
|
172
178
|
if (selector.includes(".pseudo-")) return [];
|
|
173
179
|
var states = [];
|
|
174
180
|
var plainSelector = selector.replace(matchAll, function (_, state) {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
var isAtRule = function isAtRule(selector) {
|
|
2
|
+
return selector.indexOf("@") === 0;
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
export var splitSelectors = function splitSelectors(selectors) {
|
|
6
|
+
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
|
+
|
|
15
|
+
if (char === "(") {
|
|
16
|
+
parentheses += 1;
|
|
17
|
+
} else if (char === ")") {
|
|
18
|
+
parentheses -= 1;
|
|
19
|
+
} else if (char === "[") {
|
|
20
|
+
brackets += 1;
|
|
21
|
+
} else if (char === "]") {
|
|
22
|
+
brackets -= 1;
|
|
23
|
+
} else if (char === ",") {
|
|
24
|
+
if (!parentheses && !brackets) {
|
|
25
|
+
result.push(selector.trim());
|
|
26
|
+
selector = "";
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
selector += char;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
result.push(selector.trim());
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { splitSelectors } from "./splitSelectors";
|
|
2
|
+
describe("splitSelectors", function () {
|
|
3
|
+
test("handles basic selectors", function () {
|
|
4
|
+
expect(splitSelectors(".a")).toEqual([".a"]);
|
|
5
|
+
expect(splitSelectors(".a, .b")).toEqual([".a", ".b"]);
|
|
6
|
+
});
|
|
7
|
+
test("supports ::slotted and :is", function () {
|
|
8
|
+
expect(splitSelectors("::slotted(:is(button, a):active)")).toEqual(["::slotted(:is(button, a):active)"]);
|
|
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
|
+
});
|
|
11
|
+
test("supports :host", function () {
|
|
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
|
+
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
|
+
});
|
|
15
|
+
});
|
|
@@ -27,9 +27,11 @@ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToAr
|
|
|
27
27
|
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; }
|
|
28
28
|
|
|
29
29
|
/* eslint-env browser */
|
|
30
|
-
import { addons, useEffect
|
|
30
|
+
import { addons, useEffect } from "@storybook/addons";
|
|
31
31
|
import { DOCS_RENDERED, STORY_CHANGED, STORY_RENDERED } from "@storybook/core-events";
|
|
32
|
+
import { UPDATE_GLOBALS } from '@storybook/core-events';
|
|
32
33
|
import { PSEUDO_STATES } from "./constants";
|
|
34
|
+
import { splitSelectors } from "./splitSelectors";
|
|
33
35
|
var pseudoStates = Object.values(PSEUDO_STATES);
|
|
34
36
|
var matchOne = new RegExp(":(".concat(pseudoStates.join("|"), ")"));
|
|
35
37
|
var matchAll = new RegExp(":(".concat(pseudoStates.join("|"), ")"), "g"); // Drops any existing pseudo state classnames that carried over from a previously viewed story
|
|
@@ -84,20 +86,21 @@ addons.getChannel().on(STORY_CHANGED, function () {
|
|
|
84
86
|
export var withPseudoState = function withPseudoState(StoryFn, _ref5) {
|
|
85
87
|
var viewMode = _ref5.viewMode,
|
|
86
88
|
parameters = _ref5.parameters,
|
|
87
|
-
id = _ref5.id
|
|
89
|
+
id = _ref5.id,
|
|
90
|
+
globalsArgs = _ref5.globals;
|
|
88
91
|
var parameter = parameters.pseudo;
|
|
89
|
-
|
|
90
|
-
var
|
|
91
|
-
_useGlobals2 = _slicedToArray(_useGlobals, 2),
|
|
92
|
-
globals = _useGlobals2[0].pseudo,
|
|
93
|
-
updateGlobals = _useGlobals2[1]; // Sync parameter to globals, used by the toolbar (only in canvas as this
|
|
92
|
+
var globals = globalsArgs.pseudo;
|
|
93
|
+
var channel = addons.getChannel(); // Sync parameter to globals, used by the toolbar (only in canvas as this
|
|
94
94
|
// doesn't make sense for docs because many stories are displayed at once)
|
|
95
95
|
|
|
96
|
-
|
|
97
96
|
useEffect(function () {
|
|
98
|
-
if (parameter !== globals && viewMode === "story")
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
if (parameter !== globals && viewMode === "story") {
|
|
98
|
+
channel.emit(UPDATE_GLOBALS, {
|
|
99
|
+
globals: {
|
|
100
|
+
pseudo: parameter
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
101
104
|
}, [parameter, viewMode]); // Convert selected states to classnames and apply them to the story root element.
|
|
102
105
|
// Then update each shadow host to redetermine its own pseudo classnames.
|
|
103
106
|
|
|
@@ -155,7 +158,8 @@ function rewriteStyleSheets(shadowRoot) {
|
|
|
155
158
|
selectorText = _step2$value.selectorText;
|
|
156
159
|
|
|
157
160
|
if (matchOne.test(selectorText)) {
|
|
158
|
-
var
|
|
161
|
+
var selectors = splitSelectors(selectorText);
|
|
162
|
+
var newRule = cssText.replace(selectorText, selectors.flatMap(function (selector) {
|
|
159
163
|
if (selector.includes(".pseudo-")) return [];
|
|
160
164
|
var states = [];
|
|
161
165
|
var plainSelector = selector.replace(matchAll, function (_, state) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storybook-addon-pseudo-states",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "CSS pseudo states for Storybook",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook-addons",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"clean": "rimraf ./dist",
|
|
26
26
|
"start": "concurrently \"yarn storybook --no-manager-cache --quiet\" \"yarn build:dist --watch\"",
|
|
27
27
|
"storybook": "start-storybook -p 6006",
|
|
28
|
+
"test": "jest src",
|
|
28
29
|
"chromatic": "chromatic",
|
|
29
30
|
"build:dist": "babel ./src --out-dir ./dist/cjs && BABEL_ESM=\"true\" babel ./src --out-dir ./dist/esm",
|
|
30
31
|
"build:storybook": "build-storybook",
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
"babel-loader": "^8.1.0",
|
|
44
45
|
"chromatic": "^5.6.0",
|
|
45
46
|
"concurrently": "^5.3.0",
|
|
47
|
+
"jest": "^27.5.1",
|
|
46
48
|
"react": "^17.0.1",
|
|
47
49
|
"react-dom": "^17.0.1",
|
|
48
50
|
"rimraf": "^3.0.2"
|