diff --git a/code/addons/a11y/src/components/VisionSimulator.tsx b/code/addons/a11y/src/components/VisionSimulator.tsx
index 2acc66b21c71..096230ee293d 100644
--- a/code/addons/a11y/src/components/VisionSimulator.tsx
+++ b/code/addons/a11y/src/components/VisionSimulator.tsx
@@ -1,14 +1,13 @@
import type { ReactNode } from 'react';
-import React, { useState } from 'react';
-
+import React, { useState, useEffect } from 'react';
+import ReactDOMServer from 'react-dom/server';
import { IconButton, TooltipLinkList, WithTooltip } from 'storybook/internal/components';
import { Global, styled } from 'storybook/internal/theming';
-
import { AccessibilityIcon } from '@storybook/icons';
-
import { Filters } from './ColorFilters';
const iframeId = 'storybook-preview-iframe';
+const iframeContents = 'storybook-root';
interface Option {
name: string;
@@ -42,14 +41,6 @@ const getFilter = (filterName: string) => {
return `url('#${filterName}')`;
};
-const Hidden = styled.div(() => ({
- '&, & svg': {
- position: 'absolute',
- width: 0,
- height: 0,
- },
-}));
-
const ColorIcon = styled.span<{ filter: string }>(
{
background: 'linear-gradient(to right, #F44336, #FF9800, #FFEB3B, #8BC34A, #2196F3, #9C27B0)',
@@ -121,19 +112,39 @@ const getColorList = (active: Filter, set: (i: Filter) => void): Link[] => [
}),
];
+const hiddenStyles = {
+ position: 'absolute',
+ width: '0',
+ height: '0',
+};
+
+const injectFilters = (iframeDocument: Document) => {
+ if (!iframeDocument.getElementById('color-filters')) {
+ const filtersContainer = iframeDocument.createElement('div');
+ filtersContainer.id = 'color-filters';
+ Object.assign(filtersContainer.style, hiddenStyles);
+ iframeDocument.body.appendChild(filtersContainer);
+ const filtersSvgString = ReactDOMServer.renderToStaticMarkup();
+ filtersContainer.innerHTML = filtersSvgString;
+ }
+};
+
export const VisionSimulator = () => {
const [filter, setFilter] = useState(null);
+
+ useEffect(() => {
+ const iframe = document.getElementById(iframeId) as HTMLIFrameElement;
+ if (iframe && iframe.contentDocument) {
+ injectFilters(iframe.contentDocument);
+ const storyRoot = iframe.contentDocument.getElementById(iframeContents);
+ if (storyRoot) {
+ storyRoot.style.filter = filter ? getFilter(filter.name) : 'none';
+ }
+ }
+ }, [filter]);
+
return (
<>
- {filter && (
-
- )}
{
@@ -150,9 +161,6 @@ export const VisionSimulator = () => {
-
-
-
>
);
};