Skip to content

Commit 52b8560

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

File tree

124 files changed

+2675
-3216
lines changed

Some content is hidden

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

124 files changed

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

.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)