From 6808c85295d472286c0a52e28d2279b2b5a16f92 Mon Sep 17 00:00:00 2001 From: "[ Cassondra ]" Date: Wed, 15 Jan 2025 09:43:44 -0500 Subject: [PATCH] chore(storybook): fix code loading on docs pages [CSS-1070] (#3440) Fix an issue where "show code" was blocking loading in Storybook docs pages [CSS-1070] --- .changeset/famous-comics-run.md | 5 + .storybook/decorators/context.js | 33 +- .storybook/decorators/helpers.js | 2 +- .storybook/decorators/language.js | 74 +- .storybook/decorators/testing-preview.js | 39 +- .storybook/decorators/underlay.js | 16 +- .storybook/decorators/utilities.js | 87 +- .storybook/main.js | 51 +- .storybook/package.json | 3 +- .storybook/preview-head.html | 60 +- .storybook/preview.js | 30 +- .../actionbar/stories/actionbar.test.js | 1 - components/actionbutton/stories/template.js | 1 + components/avatar/stories/avatar.test.js | 1 - components/calendar/stories/template.js | 10 +- .../stories/coachindicator.test.js | 11 +- .../coachmark/stories/coachmark.test.js | 1 - .../combobox/stories/combobox.stories.js | 7 + .../datepicker/stories/datepicker.stories.js | 7 + .../datepicker/stories/datepicker.test.js | 3 + components/dialog/stories/dialog.test.js | 66 +- .../stories/dropindicator.test.js | 1 - components/icon/stories/template.js | 19 +- components/menu/stories/template.js | 2 + components/miller/stories/miller.test.js | 1 - components/modal/stories/modal.test.js | 1 - .../stories/opacitycheckerboard.test.js | 1 - components/popover/stories/popover.test.js | 3 +- .../statuslight/stories/statuslight.test.js | 1 - components/swatch/stories/template.js | 2 + components/treeview/stories/template.js | 2 +- components/treeview/stories/treeview.test.js | 1 - yarn.lock | 2667 +++++++++++++++-- 33 files changed, 2736 insertions(+), 473 deletions(-) create mode 100644 .changeset/famous-comics-run.md diff --git a/.changeset/famous-comics-run.md b/.changeset/famous-comics-run.md new file mode 100644 index 00000000000..d6d4b92f4a4 --- /dev/null +++ b/.changeset/famous-comics-run.md @@ -0,0 +1,5 @@ +--- +"@spectrum-css/preview": patch +--- + +Fix an issue where "show code" was blocking loading in Storybook docs pages [CSS-1070] diff --git a/.storybook/decorators/context.js b/.storybook/decorators/context.js index 6acabde48bb..26e6d076e36 100644 --- a/.storybook/decorators/context.js +++ b/.storybook/decorators/context.js @@ -20,7 +20,9 @@ export const withContextWrapper = makeDecorator({ color = "light", context = "legacy", scale = "medium", - testingPreview = false, + } = {}, + parameters: { + showTestingGrid = false, } = {}, id, viewMode, @@ -45,7 +47,7 @@ export const withContextWrapper = makeDecorator({ useEffect(() => { const isDocs = viewMode === "docs"; - const isTesting = testingPreview; + const isTesting = showTestingGrid; const isRaw = Boolean(context === "raw"); const isModern = Boolean(context === "spectrum"); const isExpress = Boolean(context === "express"); @@ -59,16 +61,18 @@ export const withContextWrapper = makeDecorator({ } for (const container of fetchContainers(id, isDocs, isTesting)) { + // Check if the container is a testing wrapper to prevent applying colors around the testing grid + const isTestingWrapper = isTesting ? container.matches("body:has([data-testing-preview]),[data-testing-preview]") : false; + // Check if the container has a static color element + let hasStaticElement = container.matches(`:has([data-html-preview])`) ? container.matches(`:has([data-html-preview] .${rootClass}--staticWhite, [data-html-preview] .${rootClass}--staticBlack)`) : container.matches(`:has(.${rootClass}--staticWhite, .${rootClass}--staticBlack)`); + // Reset the context to the original values color = original.color; context = original.context; scale = original.scale; - // Check if the container has a static color element - let hasStaticElement = container.matches(`:has([data-html-preview])`) ? container.matches(`:has([data-html-preview] .${rootClass}--staticWhite, [data-html-preview] .${rootClass}--staticBlack)`) : container.matches(`:has(.${rootClass}--staticWhite, .${rootClass}--staticBlack)`); - let staticKey = staticColor; - if (!staticKey && hasStaticElement) { + if (!isTestingWrapper && !staticKey && hasStaticElement) { staticKey = ( container.querySelector(`.${rootClass}--staticWhite`) && "white" || container.querySelector(`.${rootClass}--staticBlack`) && "black" @@ -95,13 +99,13 @@ export const withContextWrapper = makeDecorator({ } // Let the static color override the color if it's set - if (hasStaticElement && staticColorSettings[staticKey]?.color) { + if (!isTestingWrapper && hasStaticElement && staticColorSettings[staticKey]?.color) { color = staticColorSettings[staticKey].color; } // Force a light theme for the body wrapper in testing preview mode // because the individual containers will bring in the correct theme - if (isTesting && container.matches("body:has([data-testing-preview]")) { + if (isTestingWrapper) { color = "light"; } @@ -113,14 +117,17 @@ export const withContextWrapper = makeDecorator({ container.classList.toggle(`spectrum--${s}`, s === scale && !isRaw); } - // Start by removing the background color from the container and then add it back if needed - container.style.removeProperty("background"); - if (hasStaticElement && staticKey && staticColorSettings[staticKey]) { - container.style.background = staticColorSettings[staticKey].background; + if (!isTestingWrapper) { + if (hasStaticElement && staticKey && staticColorSettings[staticKey]) { + container.style.background = staticColorSettings[staticKey].background; + } + } else { + // Testing background is stark white to highlight the gray-ish background color on light theme + container.style.background = "Canvas"; } } - }, [context, viewMode, original, staticColor, color, scale, rootClass, tokens, staticColorSettings, testingPreview]); + }, [context, viewMode, original, staticColor, color, scale, rootClass, tokens, staticColorSettings, showTestingGrid]); return StoryFn(data); }, diff --git a/.storybook/decorators/helpers.js b/.storybook/decorators/helpers.js index 746df02ed47..1538f683ba1 100644 --- a/.storybook/decorators/helpers.js +++ b/.storybook/decorators/helpers.js @@ -68,7 +68,7 @@ export function fetchContainers(id, isDocs = false, isTesting = false) { } else if (isTesting) { // Only capture the top-level container for testing previews - containers.push(...document.querySelectorAll("[data-inner-container]")); + containers.push(...document.querySelectorAll("body,[data-testing-preview],[data-testing-preview] [data-inner-container]")); } if (containers.length === 0) containers = [document.body]; diff --git a/.storybook/decorators/language.js b/.storybook/decorators/language.js index a49621d0563..89ea3516dcf 100644 --- a/.storybook/decorators/language.js +++ b/.storybook/decorators/language.js @@ -1,6 +1,5 @@ import { makeDecorator, useEffect } from "@storybook/preview-api"; import { fetchContainers } from "./helpers.js"; -/* global Typekit */ /** * @type import('@storybook/csf').DecoratorFunction @@ -17,48 +16,51 @@ export const withLanguageWrapper = makeDecorator({ viewMode, } = context; + const currentKitId = window.currentKitId; + useEffect(() => { - const isNotEnglish = lang && lang !== "en-US"; + // Set the language on all containers and track if it has changed + let hasChanged = false; + for (const container of fetchContainers(id, viewMode === "docs")) { + if (container.lang !== lang) { + container.lang = lang; + hasChanged = true; + } + } + + // If the fonts are actively loading, do not re-trigger the load + if (window.FontsLoading === true) return; + // If the language has not changed, do not re-trigger the load + if (!hasChanged) return; // If it is US-language or unset use the rok6rmo Adobe font web project id (smaller size), // otherwise use the mge7bvf kit with all the language settings (larger size) - const kitId = isNotEnglish ? "mge7bvf" : "rok6rmo"; - const config = { - kitId, - async: true, - scriptTimeout: 3000, - // https://github.com/typekit/webfontloader?tab=readme-ov-file#configuration - loading: function() {}, - fontactive: function(familyName) { - console.log(`Font ${familyName} active`); - }, - fontinactive: function(familyName) { - console.log(`Font ${familyName} inactive`); - }, - active: function() { - console.log(`Font loaded [id: ${kitId}]`); + const kitId = lang && lang !== "en-US" ? "mge7bvf" : "rok6rmo"; - // Fire a custom event to indicate the Adobe Fonts have loaded - document.dispatchEvent(new CustomEvent("typekit-loaded", { detail: { kitId } })); - }, - } + // If the current kit is the same as the new kit, do not re-trigger the load + if (currentKitId === kitId) return; - if (typeof window.Typekit !== "undefined") { - // If the kitId is the same as the one already loaded, do nothing - if (window.Typekit.config?.kitId !== kitId) { - window.Typekit.load(config); - } - } - else { - try { - window.Typekit = Typekit.load(config); - } catch (e) {/* empty */} - } + try { + window.Typekit.load({ + kitId, + async: true, + scriptTimeout: 3000, + // https://github.com/typekit/webfontloader?tab=readme-ov-file#configuration + loading: function() { + window.FontsLoading = true; + }, + active: function() { + window.FontsLoading = false; + window.currentKitId = this.kitId; + console.log(`Font loaded [id: ${this.kitId}]`); - for (const container of fetchContainers(id, viewMode === "docs")) { - container.lang = lang; - } - }, [lang]); + // Fire a custom event to indicate the Adobe Fonts have loaded + document.dispatchEvent(new CustomEvent("typekit-loaded", { detail: { kitId: this.kitId } })); + + }, + }); + } catch (e) {/* empty */} + }, [lang, currentKitId, window]); return StoryFn(context); }, diff --git a/.storybook/decorators/testing-preview.js b/.storybook/decorators/testing-preview.js index 53480f94b40..31c2ac71ce2 100644 --- a/.storybook/decorators/testing-preview.js +++ b/.storybook/decorators/testing-preview.js @@ -1,5 +1,4 @@ -import { FORCE_RE_RENDER } from '@storybook/core-events'; -import { addons, makeDecorator, useCallback } from "@storybook/preview-api"; +import { makeDecorator } from "@storybook/preview-api"; import isChromatic from "chromatic/isChromatic"; /** @@ -11,27 +10,33 @@ export const withTestingPreviewWrapper = makeDecorator({ parameterName: "testingPreview", wrapper: (StoryFn, context) => { const { + // Testing preview reflects the state of the user-selected global value globals: { testingPreview = false, } = {}, - viewMode, + // Show testing grid reflects whether the testing grid is currently visible in the UI + parameters: { + showTestingGrid, + } = {}, + viewMode } = context; - const init = () => { - window.isChromatic = typeof isChromatic === "function" && isChromatic() === true ? isChromatic : () => testingPreview && viewMode !== "docs"; - }; - - // Function that will update the global value and trigger a UI refresh. - const refreshAndUpdateGlobal = () => { - init(); - - // Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh - addons.getChannel().emit(FORCE_RE_RENDER); - }; - - init(); + // Below we're setting a new parameter "showTestingGrid" to reflect whether the testing grid should be visible + // This is done to ensure that the testing grid is always visible in the Chromatic testing view + // and that the user-selected global value is respected in the Storybook UI - useCallback(() => refreshAndUpdateGlobal(), [testingPreview]); + // If isChromatic() is true, we should update the global value to always show the testing grid + if (typeof isChromatic === "function" && isChromatic() === true) { + context.parameters.showTestingGrid = true; + } else if (viewMode === "docs") { + // If we're in the docs view, we should disable the testing grid + context.parameters.showTestingGrid = false; + } else if (typeof showTestingGrid === "undefined") { + // If the global value is undefined, we should set it to the testing preview value + context.parameters.showTestingGrid = testingPreview; + } else if (showTestingGrid !== testingPreview) { + context.parameters.showTestingGrid = testingPreview; + } return StoryFn(context); }, diff --git a/.storybook/decorators/underlay.js b/.storybook/decorators/underlay.js index 6c4fdb51fd6..003c3ecf429 100644 --- a/.storybook/decorators/underlay.js +++ b/.storybook/decorators/underlay.js @@ -1,6 +1,5 @@ import { Template as Underlay } from "@spectrum-css/underlay/stories/template.js"; import { makeDecorator } from "@storybook/preview-api"; -import isChromatic from "chromatic/isChromatic"; import { html } from "lit"; import { when } from "lit/directives/when.js"; import { getRandomId } from "./utilities.js"; @@ -14,22 +13,15 @@ export const withUnderlayWrapper = makeDecorator({ parameterName: "withUnderlay", wrapper: (StoryFn, context) => { const { - globals: { - testingPreview = false, - } = {}, - args: { - isOpen = false, - } = {}, - parameters: { - withUnderlay = true, - } = {}, + args: { isOpen = false } = {}, + parameters: { withUnderlay = true, showTestingGrid = false } = {}, } = context; const id = getRandomId("underlay"); // In the chromatic testing view, the underlay should be forced // to the height of the #storybook-root element to ensure it is visible - if (testingPreview || isChromatic()) { + if (showTestingGrid) { document.addEventListener("DOMContentLoaded", () => { setTimeout(() => { const container = document.getElementById("storybook-root"); @@ -47,6 +39,6 @@ export const withUnderlayWrapper = makeDecorator({ return html` ${when(withUnderlay, () => Underlay({ isOpen, id }, context))} ${StoryFn(context)} - `; + `; }, }); diff --git a/.storybook/decorators/utilities.js b/.storybook/decorators/utilities.js index 50d10413368..eb51fd9a917 100644 --- a/.storybook/decorators/utilities.js +++ b/.storybook/decorators/utilities.js @@ -1,3 +1,4 @@ +import isChromatic from "chromatic/isChromatic"; import { html, nothing } from "lit"; import { styleMap } from "lit/directives/style-map.js"; import { when } from "lit/directives/when.js"; @@ -52,7 +53,10 @@ const Heading = ({ headingStyles["color"] = context?.args?.staticColor ?? "white"; } else if (typeof context?.args?.staticColor !== "undefined") { - headingStyles["color"] = context?.args?.staticColor; + headingStyles["color"] = context?.args?.staticColor ?? "CanvasText"; + } + else { + headingStyles["color"] = "CanvasText"; } @@ -337,7 +341,6 @@ export const Sizes = ({ } = {}, context = {}) => { return ArgGrid({ withBorder, - heading: withHeading ? "Sizing" : undefined, argKey: "size", labels: { xxs: "Extra-extra-small", @@ -349,7 +352,8 @@ export const Sizes = ({ xxl: "Extra-extra-large", xxxl: "Extra-extra-extra-large", }, - ...args + ...args, + heading: withHeading ? "Sizing" : undefined, }, context); }; @@ -360,10 +364,9 @@ export const Sizes = ({ * @param {Function} props.TestTemplate - The template to render for each test case. * @param {Object[]} props.testData - The data for each test case to render. * @param {Object[]} props.stateData - The data for each state to render. + * @param {boolean} props.withSizes - Whether to render sizes for the component. * @param {string} props.sizeDirection - The direction of the size content. * @param {string} props.stateDirection - The direction of the state content. - * @param {boolean} props.skipBorders - Whether to skip rendering borders around tests. - * @param {boolean} props.withSizes - Whether to render sizes for the component. * @param {Object} props.containerStyles - Additional styles to apply to the container. * @param {Object} props.wrapperStyles - Additional styles to apply to the content wrapper. */ @@ -374,10 +377,9 @@ export const Variants = ({ // Test data defaults to an empty array so that we at least get the base component testData = [{}], stateData = [], + withSizes = true, sizeDirection, stateDirection, - skipBorders = false, - withSizes = true, containerStyles = {}, wrapperStyles = {}, } = {}) => { @@ -394,43 +396,47 @@ export const Variants = ({ SizeTemplate = TestTemplate; } - const staticColor = { - black: "var(--spectrum-docs-static-black-background-color)", - white: "var(--spectrum-docs-static-white-background-color)", - }; - return (args, context) => { // Fetch any docs configurations from the context to use for VRT - const { argTypes = {}, parameters = {} } = context; - - const height = parameters?.docs?.story?.height; - const width = parameters?.docs?.story?.width; - - // Check if the staticColor property exists in this story - const hasStaticColor = Object.keys(argTypes).includes("staticColor"); + const { + parameters: { + docs = {}, + showTestingGrid = false, + } = {}, + viewMode + } = context; + + const height = docs?.story?.height; + const width = docs?.story?.width; + + if ( + viewMode === "docs" || + ( + !showTestingGrid && + (typeof isChromatic === "function" && !isChromatic()) + ) + ) { + return html` + +
${Template(args, context)}
+ `; + } return html` - -
- ${Template(args, context)} -
-
1); + const withBorder = withStates || testData.length > 1; // Merge the test data with the args to pass to the template const data = { ...args, ...item }; @@ -472,14 +478,7 @@ export const Variants = ({ testHeading = "Default"; } - // Check if the staticColor property is being used in this story - let backgroundColor; - if (hasStaticColor && data.staticColor) { - backgroundColor = staticColor[data.staticColor]; - } - const combinedStyles = { - backgroundColor, ...wrapperStyles, ...testWrapperStyles, }; @@ -493,7 +492,7 @@ export const Variants = ({ ...containerStyles, }, // if the test has multiple states, pass the wrapper styles to that container, otherwise use it here - wrapperStyles: withStates ? { backgroundColor, ...containerStyles } : combinedStyles, + wrapperStyles: withStates ? containerStyles : combinedStyles, content: html` ${when(withStates, () => States({ diff --git a/.storybook/main.js b/.storybook/main.js index f00db7dcac4..7d6689bf63f 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -29,16 +29,20 @@ export default { staticDirs: ["./assets", "./assets/images"], addons: [ { - name: "@storybook/addon-essentials", - // Supported booleans: actions, controls, docs, toolbars, measure, outline. - options: { - // Don't need viewports b/c the medium/large contexts are used to support scaling. - viewport: false, - // Don't need backgrounds b/c this is handled by the color contexts. - backgrounds: false, - // Configure separately - docs: false, - }, + name: "@storybook/addon-controls", + options: {}, + }, + { + name: "@storybook/addon-toolbars", + options: {}, + }, + { + name: "@storybook/addon-measure", + options: {}, + }, + { + name: "@storybook/addon-outline", + options: {}, }, { name: "@storybook/addon-docs", @@ -49,10 +53,14 @@ export default { transcludeMarkdown: true, }, }, - // https://github.com/storybookjs/storybook/tree/next/code/addons/a11y - "@storybook/addon-a11y", + { + name: "@storybook/addon-actions", + options: {}, + }, // https://www.npmjs.com/package/@whitespace/storybook-addon-html "@whitespace/storybook-addon-html", + // https://github.com/storybookjs/storybook/tree/next/code/addons/a11y + "@storybook/addon-a11y", // https://storybook.js.org/addons/@etchteam/storybook-addon-status "@etchteam/storybook-addon-status", // https://github.com/storybookjs/storybook/tree/next/code/addons/interactions @@ -72,6 +80,15 @@ export default { return mergeConfig(config, { publicDir: "./assets", + // Add dependencies to pre-optimization + optimizeDeps: { + include: [ + "@whitespace/storybook-addon-html", + "@storybook/blocks", + "@storybook/theming", + "@storybook/components", + ], + }, build: { sourcemap: configType === "DEVELOPMENT", manifest: true, @@ -85,8 +102,11 @@ export default { } }); }, - framework: { - name: "@storybook/web-components-vite", + framework: "@storybook/web-components-vite", + typescript: { + reactDocgen: 'react-docgen', + // Not using typescript so disable the check + check: false, }, features: { /* Code splitting flag; load stories on-demand */ @@ -94,9 +114,6 @@ export default { /* Builds stories.json to help with on-demand loading */ buildStoriesJson: true, }, - docs: { - defaultName: "Docs", - }, refs: { "web-components": { title: "Spectrum web components", diff --git a/.storybook/package.json b/.storybook/package.json index e8e8ae324ed..159e7c07d73 100644 --- a/.storybook/package.json +++ b/.storybook/package.json @@ -39,7 +39,6 @@ "@etchteam/storybook-addon-status": "^5.0.0", "@storybook/addon-a11y": "^8.4.7", "@storybook/addon-actions": "^8.4.7", - "@storybook/addon-console": "^3.0.0", "@storybook/addon-designs": "^8.0.4", "@storybook/addon-docs": "^8.4.7", "@storybook/addon-essentials": "^8.4.7", @@ -50,7 +49,7 @@ "@storybook/core-events": "^8.4.7", "@storybook/manager-api": "^8.4.7", "@storybook/preview-api": "^8.4.7", - "@storybook/testing-library": "^0.2.2", + "@storybook/test-runner": "^0.21.0", "@storybook/theming": "^8.4.7", "@storybook/web-components-vite": "^8.4.7", "@whitespace/storybook-addon-html": "^6.1.1", diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html index 73194fd52ed..5dd7ec4053e 100644 --- a/.storybook/preview-head.html +++ b/.storybook/preview-head.html @@ -2,27 +2,43 @@ - - diff --git a/.storybook/preview.js b/.storybook/preview.js index 9c7d46c3534..24679a07822 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,4 +1,4 @@ -import { setConsoleOptions } from "@storybook/addon-console"; + import { withActions, withArgEvents, @@ -26,19 +26,6 @@ import "@spectrum-css/bundle/dist/index.min.css"; // Import the custom base styles import "./assets/base.css"; -window.global = window; - -const panelExclude = setConsoleOptions({}).panelExclude || []; -setConsoleOptions({ - panelExclude: [ - ...panelExclude, - /deprecated/, - /TypeError/, - /postcss/, - /stylelint/, - ], -}); - /** @type import('@storybook/types').StorybookParameters & import('@storybook/types').API_Layout */ export const parameters = { layout: "centered", @@ -76,33 +63,28 @@ export const parameters = { sort: "requiredFirst", }, html: { - root: "[data-html-preview]:first-of-type", + root: "[data-html-preview]:first-of-type > *", removeComments: true, prettier: { - tabWidth: 4, + tabWidth: 2, useTabs: false, htmlWhitespaceSensitivity: "ignore", }, highlighter: { - showLineNumbers: true, wrapLines: true, }, }, docs: { + defaultName: "Docs", page: DocumentationTemplate, story: { inline: true }, source: { - type: "dynamic", - language: "html", + format: "html", + excludeDecorators: true, }, }, status: { statuses: { - migrated: { - background: "#f0f0f0", - color: "#444", - description: "Migrated to the latest tokens.", - }, deprecated: { background: "rgb(211,21,16)", color: "#fff", diff --git a/components/actionbar/stories/actionbar.test.js b/components/actionbar/stories/actionbar.test.js index 79b9ddfeb83..043a0727fd7 100644 --- a/components/actionbar/stories/actionbar.test.js +++ b/components/actionbar/stories/actionbar.test.js @@ -3,7 +3,6 @@ import { Template } from "./template.js"; export const ActionBarGroup = Variants({ Template, - skipBorders: true, testData: [ { testHeading: "Default", diff --git a/components/actionbutton/stories/template.js b/components/actionbutton/stories/template.js index 2a9f4672831..23cf2a1dfa0 100644 --- a/components/actionbutton/stories/template.js +++ b/components/actionbutton/stories/template.js @@ -118,6 +118,7 @@ export const Template = ({ size, iconName, setName: iconSet, + useRef: iconSet === "workflow", customClasses: [`${rootClass}-icon`, ...customIconClasses], }, context) )} diff --git a/components/avatar/stories/avatar.test.js b/components/avatar/stories/avatar.test.js index 870ea74c0d0..4d18b20d445 100644 --- a/components/avatar/stories/avatar.test.js +++ b/components/avatar/stories/avatar.test.js @@ -3,7 +3,6 @@ import { Template } from "./template.js"; export const AvatarGroup = Variants({ Template, - skipBorders: true, stateData: [{ testHeading: "Not linked", hasLink: false, diff --git a/components/calendar/stories/template.js b/components/calendar/stories/template.js index 2a739d64bcf..a0819285906 100644 --- a/components/calendar/stories/template.js +++ b/components/calendar/stories/template.js @@ -27,9 +27,11 @@ export const Template = ({ nextHandler, id = getRandomId("calendar"), } = {}, context = {}) => { - const { globals = {}, updateArgs } = context; - - const lang = globals.lang ?? "en-US"; + const { + parameters: { showTestingGrid = false } = {}, + globals: { lang = "en-US" } = {}, + updateArgs + } = context; const DOW = [ "Sunday", @@ -67,7 +69,7 @@ export const Template = ({ }; let today = new Date(); - if (window.isChromatic()) { + if (showTestingGrid) { today = new Date(`${month ?? "January"} 1, ${year ?? "2021"}`); } diff --git a/components/coachindicator/stories/coachindicator.test.js b/components/coachindicator/stories/coachindicator.test.js index b1e10ea89b5..619215be7fd 100644 --- a/components/coachindicator/stories/coachindicator.test.js +++ b/components/coachindicator/stories/coachindicator.test.js @@ -3,7 +3,12 @@ import { Template } from "./template.js"; export const CoachIndicatorGroup = Variants({ Template, - skipBorders: false, + wrapperStyles: { + "align-items": "center", + "justify-content": "center", + "border-radius": "4px", + "min-inline-size": "60px", + }, testData: [ { testHeading: "Default", @@ -13,8 +18,7 @@ export const CoachIndicatorGroup = Variants({ testHeading: "Dark", variant: "dark", wrapperStyles: { - "background-color": "rgba(248 248 248 / 80%)", - "border-radius": "4px", + "background-color": "rgba(255 255 255 / 80%)", }, }, { @@ -22,7 +26,6 @@ export const CoachIndicatorGroup = Variants({ variant: "light", wrapperStyles: { "background-color": "rgba(0 0 0 / 80%)", - "border-radius": "4px", }, }, { diff --git a/components/coachmark/stories/coachmark.test.js b/components/coachmark/stories/coachmark.test.js index b5b17d3d6ed..af59f1bd0e1 100644 --- a/components/coachmark/stories/coachmark.test.js +++ b/components/coachmark/stories/coachmark.test.js @@ -19,7 +19,6 @@ export const TestTemplate = (args, context) => { export const CoachMarkGroup = Variants({ Template, TestTemplate, - skipBorders: false, wrapperStyles: { "z-index": "1", "min-block-size": "auto", diff --git a/components/combobox/stories/combobox.stories.js b/components/combobox/stories/combobox.stories.js index 11e8123be01..c8b35df2f3f 100644 --- a/components/combobox/stories/combobox.stories.js +++ b/components/combobox/stories/combobox.stories.js @@ -1,6 +1,7 @@ import { Template as Menu } from "@spectrum-css/menu/stories/template.js"; import { disableDefaultModes } from "@spectrum-css/preview/modes"; import { isDisabled, isFocused, isInvalid, isKeyboardFocused, isLoading, isOpen, isQuiet, isReadOnly, size } from "@spectrum-css/preview/types"; +import { within } from "@storybook/test"; import metadata from "../metadata/metadata.json"; import packageJson from "../package.json"; import { ComboBoxGroup } from "./combobox.test.js"; @@ -140,6 +141,12 @@ export default { packageJson, metadata, }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + // Wait for the popover to load + await canvas.findAllByRole("presentation"); + }, }; export const Default = ComboBoxGroup.bind({}); diff --git a/components/datepicker/stories/datepicker.stories.js b/components/datepicker/stories/datepicker.stories.js index 5b60505789f..bed5800f2c1 100644 --- a/components/datepicker/stories/datepicker.stories.js +++ b/components/datepicker/stories/datepicker.stories.js @@ -1,6 +1,7 @@ import { default as CalendarStories } from "@spectrum-css/calendar/stories/calendar.stories.js"; import { disableDefaultModes } from "@spectrum-css/preview/modes"; import { isDisabled, isInvalid, isOpen, isQuiet, isReadOnly, isRequired, isValid } from "@spectrum-css/preview/types"; +import { within } from "@storybook/test"; import metadata from "../metadata/metadata.json"; import packageJson from "../package.json"; import { DatePickerGroup } from "./datepicker.test.js"; @@ -77,6 +78,12 @@ export default { packageJson, metadata, }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + // Wait for the popover to load + await canvas.findAllByRole("presentation"); + }, }; export const Default = DatePickerGroup.bind({}); diff --git a/components/datepicker/stories/datepicker.test.js b/components/datepicker/stories/datepicker.test.js index 351c5781e61..560e5717fe9 100644 --- a/components/datepicker/stories/datepicker.test.js +++ b/components/datepicker/stories/datepicker.test.js @@ -12,14 +12,17 @@ export const DatePickerGroup = Variants({ testData: [ { testHeading: "Default", + isOpen: true, }, { testHeading: "Quiet", isQuiet: true, + isOpen: true, }, { testHeading: "Range", isRange: true, + isOpen: true, lastDay: 3, } ], diff --git a/components/dialog/stories/dialog.test.js b/components/dialog/stories/dialog.test.js index a6686207675..f9b5acb6b2e 100644 --- a/components/dialog/stories/dialog.test.js +++ b/components/dialog/stories/dialog.test.js @@ -2,78 +2,68 @@ import { Variants } from "@spectrum-css/preview/decorators"; import { Template } from "./template.js"; export const DialogGroup = Variants({ - Template: (args, context) => ( + Template: (args, context) => { + const { parameters: { showTestingGrid = false } = {} } = context; /* - * This template forces each test case to showModal: false, and give a background + * This template forces each test case to showModal: false, and give a background * color to the dialog grid container when isChromatic() is true. * This should ensure that the Sizes within the Variants() template to display correctly. */ - Template({ + return Template({ ...args, - showModal: window.isChromatic() ? false : args.showModal, - // TODO: The dialog's heading arg is getting passed as the "Sizing" heading arg (instead of the + showModal: showTestingGrid ? false : args.showModal, + // TODO: The dialog's heading arg is getting passed as the "Sizing" heading arg (instead of the // TODO: word "Sizing"). We should be able to remove this arg once that no longers happens. - heading: window.isChromatic() ? "Lorem ipsum dolor sit amet, consectetur adipiscing elit" : args.heading, + heading: showTestingGrid ? "Lorem ipsum dolor sit amet, consectetur adipiscing elit" : args.heading, customStyles: { ...(args.customStyles ?? {}), - "background-color": window.isChromatic() ? "var(--spectrum-gray-100)" : undefined, + "background-color": showTestingGrid ? "var(--spectrum-gray-100)" : undefined, }, - }, context) - ), + }, context); + }, + sizeDirection: "column", + containerStyles: { + "background-color": "transparent", + }, + wrapperStyles: { + "border": "none", + "background-color": "transparent", + "padding": "0", + }, testData: [ { - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, + testHeading: "Standard", }, { testHeading: "Dismissible", isDismissible: true, hasFooter: false, - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, }, { testHeading: "With hero/cover image", heroImageUrl: "example-card-portrait.png", - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, }, { testHeading: "With hero/cover image, dismissible", heroImageUrl: "example-card-portrait.png", isDismissible: true, hasFooter: false, - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, }, { testHeading: "No divider", hasDivider: false, - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, }, { testHeading: "No divider, dismissible", hasDivider: false, isDismissible: true, hasFooter: false, - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, }, { testHeading: "With hero/cover image, no divider", hasDivider: false, heroImageUrl: "example-card-portrait.png", - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, }, { testHeading: "With hero/cover image, no divider, dismissible", @@ -81,9 +71,6 @@ export const DialogGroup = Variants({ isDismissible: true, hasFooter: false, heroImageUrl: "example-card-portrait.png", - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, }, ], }); @@ -91,13 +78,13 @@ export const DialogGroup = Variants({ export const DialogFullscreen = Variants({ Template, withSizes: false, + wrapperStyles: { + "background-color": "var(--spectrum-gray-50)" + }, testData: [ { showModal: false, layout: "fullscreen", - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, }, ], }); @@ -105,14 +92,13 @@ export const DialogFullscreen = Variants({ export const DialogFullscreenTakeover = Variants({ Template, withSizes: false, + wrapperStyles: { + "background-color": "var(--spectrum-gray-50)" + }, testData: [ { showModal: false, layout: "fullscreenTakeover", - wrapperStyles: { - "background-color": "var(--spectrum-gray-50)" - }, }, ], }); - diff --git a/components/dropindicator/stories/dropindicator.test.js b/components/dropindicator/stories/dropindicator.test.js index 50d5c1df65d..87a0ea00cca 100644 --- a/components/dropindicator/stories/dropindicator.test.js +++ b/components/dropindicator/stories/dropindicator.test.js @@ -3,7 +3,6 @@ import { Template } from "./template.js"; export const DropIndicatorGroup = Variants({ Template, - skipBorders: true, testData: [ { testHeading: "Horizontal", diff --git a/components/icon/stories/template.js b/components/icon/stories/template.js index cf4b2067091..413f7c03172 100644 --- a/components/icon/stories/template.js +++ b/components/icon/stories/template.js @@ -105,7 +105,7 @@ export const Template = ({ id = getRandomId("icon"), customClasses = [], icons, - useRef = false, + useRef = true, workflowIcons, uiIcons, uiIconSizes, @@ -163,6 +163,11 @@ export const Template = ({ } } + // Prefer full SVG for UI icons because sizing is more consistent. + if (setName === "ui" && uiIconName) { + useRef = false; + } + if (!setName) { console.warn( `Icon: Could not determine the icon set for the provided icon name: ${idKey}.` @@ -225,7 +230,7 @@ export const Template = ({ if (fill) inlineStyle = `color: ${fill}`; let svgString; - if (icons && icons[setName]?.[scale]?.[idKey]) { + if (!useRef && icons && icons[setName]?.[scale]?.[idKey]) { svgString = icons[setName][scale][idKey]; } @@ -244,12 +249,12 @@ export const Template = ({ ...customClasses.reduce((a, c) => ({ ...a, [c]: true }), {}), }; - const classesAsString = Object.entries(classList).reduce((acc, [key, value]) => { - if (value) acc += `${key} `; - return acc; - }, ""); + if (svgString) { + const classesAsString = Object.entries(classList).reduce((acc, [key, value]) => { + if (value) acc += `${key} `; + return acc; + }, ""); - if (!useRef && svgString) { return html`${unsafeSVG( svgString.replace(/