Skip to content

Commit aaa20f4

Browse files
committed
feat(storybook): decorator for chromatic alignment
1 parent 18d2d7d commit aaa20f4

File tree

110 files changed

+2061
-2221
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+2061
-2221
lines changed

.storybook/assets/base.css

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,47 @@
1212
*/
1313

1414
body {
15+
--spectrum-font-family-ar: myriad-arabic, adobe-clean, 'Source Sans Pro', -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, ubuntu, 'Trebuchet MS', 'Lucida Grande', sans-serif;
16+
--spectrum-font-family-he: myriad-hebrew, adobe-clean, 'Source Sans Pro', -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, ubuntu, 'Trebuchet MS', 'Lucida Grande', sans-serif;
17+
18+
--spectrum-font-family: var(--spectrum-sans-font-family-stack);
19+
--spectrum-font-style: var(--spectrum-default-font-style);
20+
21+
min-block-size: 100%;
22+
1523
margin: 0;
1624
background-color: var(--spectrum-background-layer-2-color);
1725
color: var(--spectrum-neutral-content-color-default);
1826

1927
font-family: var(--spectrum-sans-font-family-stack);
2028
font-style: var(--spectrum-default-font-style);
2129
font-size: 16px;
30+
31+
&:lang(ar) {
32+
font-family: var(--spectrum-font-family-ar);
33+
}
34+
35+
&:lang(he) {
36+
font-family: var(--spectrum-font-family-he);
37+
}
2238
}
2339

2440
.spectrum {
2541
background-color: var(--spectrum-background-layer-1-color);
2642

2743
/* @todo: add back the text color and update VRTs */
2844
/* color: var(--spectrum-neutral-content-color-default); */
45+
2946
-webkit-tap-highlight-color: rgba(0, 0, 0, 0%);
47+
48+
font-size: var(--spectrum-font-size, var(--spectrum-font-size-100, 16px));
3049
}
3150

3251
/* Hide the SVG elements that only include references */
3352
svg:has(symbol):not(:has(use)) {
3453
display: none;
3554
}
55+
56+
.docs-story > div:first-child {
57+
padding: 0;
58+
}

.storybook/assets/index.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,8 @@ select:focus,
118118
border-color: rgb(2, 101, 220) !important;
119119
box-shadow: rgb(2, 101, 220) 0 0 0 1px inset !important;
120120
}
121+
122+
/* Hides the empty divider bar at the start of the top navigation */
123+
div[role="main"] span:first-child:empty {
124+
display: none;
125+
}

.storybook/decorators/context.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { FORCE_RE_RENDER } from '@storybook/core-events';
2+
3+
import { addons, makeDecorator, useEffect } from "@storybook/preview-api";
4+
5+
/**
6+
* @type import('@storybook/csf').DecoratorFunction<import('@storybook/web-components').WebComponentsFramework>
7+
* @description Global properties added to each component; determines what stylesheets are loaded
8+
**/
9+
export const withContextWrapper = makeDecorator({
10+
name: "withContextWrapper",
11+
parameterName: "context",
12+
wrapper: (StoryFn, context) => {
13+
const { args = {}, globals = {}, viewMode } = context;
14+
let { color = "light", express = false, scale = "medium" } = globals;
15+
const { rootClass } = args;
16+
17+
if (!window) window = {};
18+
19+
const isDocs = viewMode === "docs";
20+
const isExpress = Boolean(express);
21+
let shouldRefresh = false;
22+
23+
if (scale !== window.scale) {
24+
window.scale = scale;
25+
shouldRefresh = true;
26+
}
27+
if (color !== window.color) {
28+
window.color = color;
29+
shouldRefresh = true;
30+
}
31+
if (isExpress !== window.isExpress) {
32+
window.isExpress = isExpress;
33+
shouldRefresh = true;
34+
}
35+
36+
useEffect(() => {
37+
let containers = [...document.querySelectorAll(".docs-story,#storybook-docs")];
38+
if (!isDocs || containers.length === 0) containers = [document.body];
39+
40+
if (!containers) return;
41+
42+
containers.forEach(container => {
43+
container.classList.toggle("spectrum", true);
44+
45+
container.classList.toggle("spectrum--express", isExpress);
46+
47+
container.style.removeProperty("background");
48+
49+
const hasStaticElement = container.querySelector(`.${rootClass}--staticWhite, .${rootClass}--staticBlack, .${rootClass}--overBackground`);
50+
if (hasStaticElement) {
51+
if (container.querySelector(`.${rootClass}--staticBlack`)) {
52+
container.style.background = "rgb(181, 209, 211)";
53+
window.color = "light";
54+
shouldRefresh = true;
55+
} else if (container.querySelector(`.${rootClass}--staticWhite, .${rootClass}--overBackground`)) {
56+
container.style.background = "rgb(15, 121, 125)";
57+
window.color = "dark";
58+
shouldRefresh = true;
59+
}
60+
}
61+
62+
for (const c of ["light", "dark", "darkest"]) {
63+
container.classList.toggle(`spectrum--${c}`, c === window.color);
64+
}
65+
66+
for (const s of ["medium", "large"]) {
67+
container.classList.toggle(`spectrum--${s}`, s === window.scale);
68+
}
69+
70+
if (shouldRefresh) {
71+
// Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh
72+
addons.getChannel().emit(FORCE_RE_RENDER);
73+
}
74+
});
75+
}, [window, isExpress, isDocs, rootClass]);
76+
77+
return StoryFn(context);
78+
},
79+
});

.storybook/decorators/contextsWrapper.js

Lines changed: 0 additions & 72 deletions
This file was deleted.

.storybook/decorators/index.js

Lines changed: 13 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,13 @@
1-
import { makeDecorator, useEffect } from "@storybook/preview-api";
2-
import { html } from "lit";
3-
4-
export { withContextWrapper } from "./contextsWrapper.js";
5-
export { withTestingPreviewWrapper } from "./withTestingPreviewWrapper.js";
6-
7-
/**
8-
* @type import('@storybook/csf').DecoratorFunction<import('@storybook/web-components').WebComponentsFramework>
9-
* @description Sets the text direction of the document, using the global set with a toolbar control. These properties are assigned to the document root element.
10-
**/
11-
export const withTextDirectionWrapper = makeDecorator({
12-
name: "withTextDirectionWrapper",
13-
parameterName: "textDecoration",
14-
wrapper: (StoryFn, context) => {
15-
const { globals, parameters } = context;
16-
const defaultDirection = "ltr"
17-
const textDirection = parameters.textDirection || globals.textDirection || defaultDirection;
18-
19-
useEffect(() => {
20-
if (textDirection) document.documentElement.dir = textDirection;
21-
}, [textDirection]);
22-
23-
return StoryFn(context);
24-
},
25-
});
26-
27-
/**
28-
* @type import('@storybook/csf').DecoratorFunction<import('@storybook/web-components').WebComponentsFramework>
29-
**/
30-
export const withReducedMotionWrapper = makeDecorator({
31-
name: "withReducedMotionWrapper",
32-
parameterName: "context",
33-
wrapper: (StoryFn, context) => {
34-
const { args } = context;
35-
const reducedMotion = args.reducedMotion;
36-
37-
return html`
38-
${reducedMotion
39-
? html`
40-
<style data-source="decorator">
41-
.spectrum #root #root-inner {
42-
--spectrum-animation-duration-100: 0ms;
43-
--spectrum-animation-duration-200: 0ms;
44-
--spectrum-animation-duration-300: 0ms;
45-
--spectrum-animation-duration-400: 0ms;
46-
--spectrum-animation-duration-500: 0ms;
47-
--spectrum-animation-duration-600: 0ms;
48-
--spectrum-animation-duration-700: 0ms;
49-
--spectrum-animation-duration-800: 0ms;
50-
--spectrum-animation-duration-900: 0ms;
51-
--spectrum-animation-duration-1000: 0ms;
52-
--spectrum-animation-duration-2000: 0ms;
53-
--spectrum-animation-duration-4000: 0ms;
54-
--spectrum-coachmark-animation-indicator-ring-duration: 0ms;
55-
}
56-
</style>
57-
`
58-
: ""}
59-
${StoryFn(context)}
60-
`;
61-
},
62-
});
63-
64-
/**
65-
* @type import('@storybook/csf').DecoratorFunction<import('@storybook/web-components').WebComponentsFramework>
66-
**/
67-
export const withLanguageWrapper = makeDecorator({
68-
name: "withLanguageWrapper",
69-
parameterName: "context",
70-
wrapper: (StoryFn, context) => {
71-
const { globals } = context;
72-
const lang = globals.lang;
73-
74-
useEffect(() => {
75-
if (lang) document.documentElement.lang = lang;
76-
}, [lang]);
77-
78-
return StoryFn(context);
79-
},
80-
});
81-
82-
/**
83-
* @type import('@storybook/csf').DecoratorFunction<import('@storybook/web-components').WebComponentsFramework>
84-
**/
85-
export const withSizingWrapper = makeDecorator({
86-
name: "withSizingWrapper",
87-
parameterName: "context",
88-
wrapper: (StoryFn, context) => {
89-
const { argTypes, parameters } = context;
90-
const sizes = argTypes?.size?.options || [];
91-
const sizeVariants =
92-
typeof parameters?.sizeVariants === "undefined"
93-
? true
94-
: parameters.sizeVariants;
95-
96-
/** To suppress the sizing wrapper, add `sizeVariants: false` to the parameters of a story */
97-
if (sizes.length === 0 || !sizeVariants) return StoryFn(context);
98-
const printSize = (size) => {
99-
if (size === "xs") return "Extra-small";
100-
if (size === "s") return "Small";
101-
if (size === "m") return "Medium";
102-
if (size === "l") return "Large";
103-
if (size === "xl") return "Extra-large";
104-
if (size === "xxl") return "Extra-extra-large";
105-
return size;
106-
};
107-
108-
context.parameters.html.root =
109-
'.spectrum-Examples-item[data-value="m"] #scoped-root';
110-
context.argTypes.size.table = {
111-
...context.argTypes.size.table,
112-
disable: true,
113-
};
114-
115-
return html` <div class="spectrum-Examples">
116-
${sizes.map((size) => {
117-
context.args.size = size;
118-
return html` <div class="spectrum-Examples-item" data-value=${size}>
119-
<div class="spectrum-Examples-itemGroup" id="scoped-root">
120-
${StoryFn(context)}
121-
</div>
122-
<h4
123-
class="spectrum-Detail spectrum-Detail--sizeXS spectrum-Examples-itemHeading"
124-
>
125-
${printSize(size)}
126-
</h4>
127-
</div>`;
128-
})}
129-
</div>`;
130-
},
131-
});
1+
export { withContextWrapper } from "./context.js";
2+
export { withLanguageWrapper } from "./language.js";
3+
export { withPreviewStyles } from "./preview-styles.js";
4+
export { withReducedMotionWrapper } from "./reduced-motion.js";
5+
export { withTestingPreviewWrapper } from "./testing-preview.js";
6+
export { withTextDirectionWrapper } from "./text-direction.js";
7+
8+
/* This is exported but must be opted-into on a component-by-component basis */
9+
export { withSizingWrapper } from "./sizing.js";
10+
export { withStatesWrapper } from "./states.js";
11+
export { withVariantsWrapper } from "./variants.js";
12+
13+
export { withActions } from "@storybook/addon-actions/decorator";

.storybook/decorators/language.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { html } from "lit";
2+
3+
import { makeDecorator, useEffect } from "@storybook/preview-api";
4+
5+
/**
6+
* @type import('@storybook/csf').DecoratorFunction<import('@storybook/web-components').WebComponentsFramework>
7+
**/
8+
export const withLanguageWrapper = makeDecorator({
9+
name: "withLanguageWrapper",
10+
parameterName: "lang",
11+
wrapper: (StoryFn, context) => {
12+
const { parameters, globals } = context;
13+
const lang = globals.lang ?? parameters.lang;
14+
15+
useEffect(() => {
16+
document.documentElement.lang = lang;
17+
}, [lang]);
18+
19+
return html`${StoryFn(context)}`;
20+
},
21+
});

0 commit comments

Comments
 (0)