Reading through the resource loading documentation from Chromatic, the Solution B: Check fonts have loaded in a decorator section.
Mainly would like to load our fonts before rendering the stories. The solution suggest to use addDecorator
where with a simple FC
we can preload the fonts and once they are loaded it can render the stories with story()
.
See the suggested decorator for preview.ts
:
import isChromatic from "chromatic/isChromatic";
if (isChromatic() && document.fonts) {
addDecorator((story) => {
const [isLoadingFonts, setIsLoadingFonts] = useState(true);
useEffect(() => {
Promise.all([document.fonts.load("1em Roboto")]).then(() =>
setIsLoadingFonts(false)
);
}, []);
return isLoadingFonts ? null : story();
});
}
For some reason this throws the usual error when violating the Rules of Hooks:
Rendered more hooks than during the previous render
What I've tried so far:
Mainly I tried to remove the useEffect
which renders the stories:
if (isChromatic() && document.fonts) {
addDecorator((story) => {
const [isLoadingFonts, setIsLoadingFonts] = useState(true);
return story();
});
}
Also the error disappeared but the fonts are causing inconsistent changes our screenshot tests as before.
Question:
I don't really see any issues which would violate the Rules of Hooks in the added FC
for the addDecorator
.
Is there anything what can make this error disappear? I'm open to any suggestions. Maybe I missed something here, thank you!
Mainly what solved the issue on our end is removing from main.ts
one of the addons
called @storybook/addon-knobs
.
Also renamed from preview.ts
to preview.tsx
and used the decorator a bit differently as the following:
export const decorators = [
Story => {
const [isLoadingFonts, setIsLoadingFonts] = useState(true)
useEffect(() => {
const call = async () => {
await document.fonts.load('1em Roboto')
setIsLoadingFonts(false)
}
call()
}, [])
return isLoadingFonts ? <>Fonts are loading...</> : <Story />
},
]
We dropped using the addDecorator
and used as the exported const decorators
as above.