|
| 1 | +import { HIGHLIGHT, REMOVE_HIGHLIGHT } from 'storybook/highlight'; |
| 2 | +import { useChannel, useEffect } from 'storybook/preview-api'; |
| 3 | + |
| 4 | +import { |
| 5 | + HIGHLIGHT_IGNORED_COUNT, |
| 6 | + HIGHLIGHT_IGNORED_ID, |
| 7 | + HIGHLIGHT_IGNORED_PARAM, |
| 8 | +} from './constants'; |
| 9 | +import { getIgnoreHighlightOptions } from './utils/ignoreHighlight'; |
| 10 | + |
| 11 | +const WithIgnoreHighlight = (Story: any, { globals, parameters, id }: any) => { |
| 12 | + const enabled = !!globals[HIGHLIGHT_IGNORED_PARAM]; |
| 13 | + const emit = useChannel({}); |
| 14 | + const highlightOptions = getIgnoreHighlightOptions(parameters.chromatic); |
| 15 | + const selectorKey = highlightOptions?.selectors.join('\n') ?? ''; |
| 16 | + |
| 17 | + useEffect(() => { |
| 18 | + emit(REMOVE_HIGHLIGHT, HIGHLIGHT_IGNORED_ID); |
| 19 | + if (!highlightOptions?.selectors.length) { |
| 20 | + emit(HIGHLIGHT_IGNORED_COUNT, 0); |
| 21 | + return; |
| 22 | + } |
| 23 | + if (enabled) { |
| 24 | + emit(HIGHLIGHT, highlightOptions); |
| 25 | + } |
| 26 | + |
| 27 | + const root = document.getElementById('storybook-root'); |
| 28 | + const elements = highlightOptions.selectors.reduce((acc, selector) => { |
| 29 | + // Elements matching the selector, excluding storybook elements and their descendants. |
| 30 | + // Necessary to find portaled elements (e.g. children of `body`). |
| 31 | + document |
| 32 | + .querySelectorAll( |
| 33 | + `:is(${selector}):not([id^="storybook-"], [id^="storybook-"] *, [class^="sb-"], [class^="sb-"] *)` |
| 34 | + ) |
| 35 | + .forEach((element) => acc.add(element)); |
| 36 | + |
| 37 | + // Elements matching the selector inside the storybook root, as these were excluded above. |
| 38 | + (root?.querySelectorAll(selector) ?? []).forEach((element) => acc.add(element)); |
| 39 | + |
| 40 | + return acc; |
| 41 | + }, new Set()); |
| 42 | + emit(HIGHLIGHT_IGNORED_COUNT, elements.size); |
| 43 | + |
| 44 | + return () => emit(REMOVE_HIGHLIGHT, HIGHLIGHT_IGNORED_ID); |
| 45 | + }, [emit, highlightOptions, id, selectorKey, enabled]); |
| 46 | + |
| 47 | + return Story(); |
| 48 | +}; |
| 49 | + |
| 50 | +export const decorators = [WithIgnoreHighlight]; |
| 51 | + |
| 52 | +export const initialGlobals = { |
| 53 | + [HIGHLIGHT_IGNORED_PARAM]: false, |
| 54 | +}; |
0 commit comments