#Decorators in V7
20 messages · Page 1 of 1 (latest)
<@&486526431233310732>
Without digging into the code heres my understanding
I think of it more like multiple layers
initial args -> Decorators -> render
Render would override basically everything if you want
Decorator wraps the render and can override default args
args would be the default values / starting point
at least this is what I understand as someone who mostly just consumes this part of the code
But it also just depends how you're doing the decorator. Normally I wouldn't touch the args in a decorator.
theres also hierarchy of decorators global -> component -> story
theres a video on decorators btw https://youtu.be/4yi_yCTkgng
Decorators are the secret weapon of great Storybooks. They're used for theme and state providers, to handle logic, and wrap stories in required markup.
Let @chantastic take you on a whirlwind tour of Storybook Decorators — how to write, compose and share them!
Chapters:
0:00 Supercharge Storybook with Decorators
0:26 Decorators are used for e...
In this example the console log prints hello:1 but in the render I don't apply the args at all so I ignore both intial args and what args the decorator passed
export const Basic: ComponentStoryObj<typeof Ticket> = {
decorators: [
(Story, context) => {
return <Story args={{ hello: 1 }} />;
},
],
render: (args) => {
console.log(args);
return <Ticket />;
},
args: {
bla: "something",
},
};
- The Render Function:
The render function is responsible for rendering your story using your preferred renderer, such as React, Vue, or Angular. By default, if you don't define a render function, Storybook will render the component that you want to document. The render function accepts arguments (Args) which are bound to the component as props by default. However, if you define a custom render function, you can manipulate the arguments as needed. Here's an example:
export const MyStory = {
args: {
product: 1,
quantity: 30,
},
render: (args) => {
const time = new Date();
const price = calculatePrice(args.product, args.quantity);
return <Component price={price} date={time}/>;
}
}
- Applying Decorators:
Once you have your story defined, you can enhance it by wrapping it with decorators. Decorators are functions that take a story and return a wrapped version of it. The order in which you apply decorators matters. Here are a couple of examples:
const decorator_red = (Story, context) => <RedBorder><Story /></RedBorder>;
const decorator_blue = (Story, context) => <BlueBorder><Story /></BlueBorder>;
export const MyStory = {
decorators: [decorator_red, decorator_blue]
}
In the above example, the decorator_red adds a red border around the story component, while decorator_blue adds a blue border. These decorators can be stacked in the order you want them to be applied to your story.
By using the render function and decorators, you can customize the appearance and behavior of your stories in Storybook.
Thanks all !
thanks for such a comprehensive answer here @faint yoke 🥳
Note that decorator order can be confusing. The last ones are applied to the story first, with previous ones wrapping those, etc. see https://github.com/storybookjs/storybook/issues/18896
That has confused me as well. Any particular reason for that @grim orchid @solemn venture?
I think this is typical with decorators, it's just not intiutive
Right, like compose(f,g,h) being: x=> f(g(h(x)))
Only Mathematics just got it really wrong.
It looks not intuitive but what is happening is each decorator passes the same story to the next A -> B -> C , and wraps the decorator instead which give this A ( B ( C ( S ) ) )
but this only visually
still. the decorators run in this order A runs -> B ->. C
But in terms of UI rendering, the children render first
JSX works like this