@fohte/storybook-addon 0.1.1 → 0.1.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.
- package/README.md +5 -3
- package/lib/checks/overflow-check.d.ts +0 -3
- package/lib/checks/overflow-check.js +20 -11
- package/lib/checks/unhandled-api-request-check.d.ts +8 -0
- package/lib/checks/unhandled-api-request-check.js +13 -14
- package/lib/preview.d.ts +0 -1
- package/lib/preview.js +0 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,12 +37,14 @@ This wires up `overflow-check` and `external-resource-check` — no further setu
|
|
|
37
37
|
|
|
38
38
|
### overflow-check
|
|
39
39
|
|
|
40
|
-
To exempt a selector across every story (e.g. a component whose oversized hit target never visibly clips anything),
|
|
40
|
+
To exempt a selector across every story (e.g. a component whose oversized hit target never visibly clips anything), set `parameters.overflowCheck.globalIgnoreSelectors` once in `.storybook/preview.ts`. It's additive with a story's own `parameters.overflowCheck.ignoreSelectors` — both apply, since they're separate keys and Storybook deep-merges parameter objects by key (only arrays at the same key replace wholesale, so a story-level `ignoreSelectors` can't drop the global list):
|
|
41
41
|
|
|
42
42
|
```ts
|
|
43
|
-
import {
|
|
43
|
+
import type { Parameters } from 'storybook/internal/types'
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
export const parameters: Parameters = {
|
|
46
|
+
overflowCheck: { globalIgnoreSelectors: ['[data-slot="checkbox"]'] },
|
|
47
|
+
}
|
|
46
48
|
```
|
|
47
49
|
|
|
48
50
|
### unhandled-api-request-check
|
|
@@ -83,16 +83,6 @@ function findOverflows(root, ignoreSelectors) {
|
|
|
83
83
|
}
|
|
84
84
|
return groupByAncestor(entries);
|
|
85
85
|
}
|
|
86
|
-
// Exempted everywhere, not per-story: configured once by the consuming app
|
|
87
|
-
// for markup that recurs across many stories (e.g. a component whose
|
|
88
|
-
// oversized hit target never visibly clips anything). Kept separate from
|
|
89
|
-
// parameters.overflowCheck.ignoreSelectors — which storybook's
|
|
90
|
-
// combineParameters replaces wholesale rather than merges — so a story
|
|
91
|
-
// setting its own ignoreSelectors can't silently drop this list.
|
|
92
|
-
let globalIgnoreSelectors = [];
|
|
93
|
-
export function configureOverflowCheck(options) {
|
|
94
|
-
globalIgnoreSelectors = options.ignoreSelectors;
|
|
95
|
-
}
|
|
96
86
|
function overflowCheckParameters(storyParameters) {
|
|
97
87
|
if (typeof storyParameters !== 'object' || storyParameters === null) {
|
|
98
88
|
return undefined;
|
|
@@ -125,6 +115,25 @@ function ignoreSelectorsOf(overflowCheck) {
|
|
|
125
115
|
return [];
|
|
126
116
|
return ignoreSelectors.filter((s) => typeof s === 'string');
|
|
127
117
|
}
|
|
118
|
+
// A separate key from `ignoreSelectors`, set once by the consuming app in
|
|
119
|
+
// its top-level `preview.ts` `parameters` export (not via a module-level
|
|
120
|
+
// setter — a story's own `parameters.overflowCheck` and the app's global one
|
|
121
|
+
// live in different Storybook parameter scopes, which Storybook deep-merges
|
|
122
|
+
// by object key, so a story setting `ignoreSelectors` can't drop this list).
|
|
123
|
+
// This also sidesteps bundlers that resolve this addon's module twice for
|
|
124
|
+
// one consumer (once from the app's own import, once via Storybook's addon
|
|
125
|
+
// loader) — `context.parameters` comes from Storybook itself, not from
|
|
126
|
+
// either module instance, so it's unaffected either way.
|
|
127
|
+
function globalIgnoreSelectorsOf(overflowCheck) {
|
|
128
|
+
if (overflowCheck === undefined)
|
|
129
|
+
return [];
|
|
130
|
+
if (!('globalIgnoreSelectors' in overflowCheck))
|
|
131
|
+
return [];
|
|
132
|
+
const { globalIgnoreSelectors } = overflowCheck;
|
|
133
|
+
if (!Array.isArray(globalIgnoreSelectors))
|
|
134
|
+
return [];
|
|
135
|
+
return globalIgnoreSelectors.filter((s) => typeof s === 'string');
|
|
136
|
+
}
|
|
128
137
|
export const overflowCheck = {
|
|
129
138
|
reset: () => { },
|
|
130
139
|
assert: (storyParameters, canvasElement) => {
|
|
@@ -140,7 +149,7 @@ export const overflowCheck = {
|
|
|
140
149
|
return;
|
|
141
150
|
}
|
|
142
151
|
throwIfNotEmpty(findOverflows(canvasElement, [
|
|
143
|
-
...
|
|
152
|
+
...globalIgnoreSelectorsOf(params),
|
|
144
153
|
...ignoreSelectorsOf(params),
|
|
145
154
|
]), 'Story has element(s) overflowing their container (clipped and invisible)');
|
|
146
155
|
},
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import type { StorybookCheck } from '#checks/check.js';
|
|
2
|
+
interface UnhandledApiRequestState {
|
|
3
|
+
pathPrefixes: string[];
|
|
4
|
+
unhandledApiRequestUrls: string[];
|
|
5
|
+
}
|
|
6
|
+
declare global {
|
|
7
|
+
var __fohteStorybookAddonUnhandledApiRequestState__: UnhandledApiRequestState | undefined;
|
|
8
|
+
}
|
|
2
9
|
export declare function configureUnhandledApiRequestCheck(options: {
|
|
3
10
|
pathPrefixes: string[];
|
|
4
11
|
}): void;
|
|
5
12
|
export declare function reportUnhandledApiRequest(url: string): boolean;
|
|
6
13
|
export declare const unhandledApiRequestCheck: StorybookCheck;
|
|
14
|
+
export {};
|
|
7
15
|
//# sourceMappingURL=unhandled-api-request-check.d.ts.map
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { throwIfNotEmpty } from '#checks/check.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// by the consuming app rather than hardcoded here.
|
|
10
|
-
let pathPrefixes = [];
|
|
2
|
+
function globalState() {
|
|
3
|
+
globalThis.__fohteStorybookAddonUnhandledApiRequestState__ ??= {
|
|
4
|
+
pathPrefixes: [],
|
|
5
|
+
unhandledApiRequestUrls: [],
|
|
6
|
+
};
|
|
7
|
+
return globalThis.__fohteStorybookAddonUnhandledApiRequestState__;
|
|
8
|
+
}
|
|
11
9
|
export function configureUnhandledApiRequestCheck(options) {
|
|
12
|
-
pathPrefixes = options.pathPrefixes;
|
|
10
|
+
globalState().pathPrefixes = options.pathPrefixes;
|
|
13
11
|
}
|
|
14
12
|
// Returns whether the request was recorded, so the caller can decide whether
|
|
15
13
|
// to also print MSW's own error for it.
|
|
@@ -17,18 +15,19 @@ export function reportUnhandledApiRequest(url) {
|
|
|
17
15
|
const parsed = new URL(url);
|
|
18
16
|
if (parsed.origin !== window.location.origin)
|
|
19
17
|
return false;
|
|
20
|
-
|
|
18
|
+
const state = globalState();
|
|
19
|
+
if (!state.pathPrefixes.some((prefix) => parsed.pathname.startsWith(prefix))) {
|
|
21
20
|
return false;
|
|
22
21
|
}
|
|
23
|
-
unhandledApiRequestUrls.push(parsed.pathname);
|
|
22
|
+
state.unhandledApiRequestUrls.push(parsed.pathname);
|
|
24
23
|
return true;
|
|
25
24
|
}
|
|
26
25
|
export const unhandledApiRequestCheck = {
|
|
27
26
|
reset: () => {
|
|
28
|
-
unhandledApiRequestUrls.length = 0;
|
|
27
|
+
globalState().unhandledApiRequestUrls.length = 0;
|
|
29
28
|
},
|
|
30
29
|
assert: () => {
|
|
31
|
-
throwIfNotEmpty(unhandledApiRequestUrls, 'Story made unhandled API request(s); add an MSW handler for');
|
|
30
|
+
throwIfNotEmpty(globalState().unhandledApiRequestUrls, 'Story made unhandled API request(s); add an MSW handler for');
|
|
32
31
|
},
|
|
33
32
|
};
|
|
34
33
|
//# sourceMappingURL=unhandled-api-request-check.js.map
|
package/lib/preview.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { AfterEach, BeforeEach, Parameters, WebRenderer } from 'storybook/internal/types';
|
|
2
|
-
export { configureOverflowCheck } from '#checks/overflow-check.js';
|
|
3
2
|
export { configureUnhandledApiRequestCheck, reportUnhandledApiRequest, } from '#checks/unhandled-api-request-check.js';
|
|
4
3
|
export declare const parameters: Parameters;
|
|
5
4
|
export declare const beforeEach: BeforeEach<WebRenderer>;
|
package/lib/preview.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { externalResourceCheck } from '#checks/external-resource-check.js';
|
|
2
2
|
import { overflowCheck } from '#checks/overflow-check.js';
|
|
3
3
|
import { unhandledApiRequestCheck } from '#checks/unhandled-api-request-check.js';
|
|
4
|
-
export { configureOverflowCheck } from '#checks/overflow-check.js';
|
|
5
4
|
export { configureUnhandledApiRequestCheck, reportUnhandledApiRequest, } from '#checks/unhandled-api-request-check.js';
|
|
6
5
|
function injectStyle(css) {
|
|
7
6
|
const style = document.createElement('style');
|