After you've installed and configured bookemoji you'll need to know how to write a story.
Writing stories is intended to be fairly translatable to stories written in StoryBook.
For bookemoji, a story must:
.book.svelte
file extension...and that's it! And that's also by design.
To elevate a story file thoughβyou want to use the <Story>
component. Read on.
First,
npm run dev
if not alreadyExample.book.svelte
Then, type or paste the below code sample into the file.
Replace the MyComponent
reference with a real import of a component.
<script lang="ts">
import { Story, Controls, defineMeta } from "bookemoji/components/v4";
import MyComponent from "$lib/path/to/your/components/Component.svelte";
// if your components aren't in $lib, that's fine too!
</script>
<Story name="Default" of={MyComponent} />
Svelte 5 path
import { ... } from "bookemoji/components";
Svelte 4 path
import { ... } from "bookemoji/components/v4";
If your component requires more setup, you can use the slot of the Story
to do so. See below as an example.
...
<Story name="Default" of={Tab} let:args>
<Figure>
<Image {...args} />
</Figure>
</Story>
args
args
allow you to present variants distinctly.
They generally are your props, but you can use them creatively to make better stories.
<Story name="Default" of={MyComponent} />
<Story name="Red Variant" of={MyComponent} args={{ color: "red", }} />
<Story name="Green Variant" of={MyComponent} args={{ color: "green", }}>
<div class="wrapper">
<MyComponent {...args}>
</div>
</Story>
defineMeta
, argTypes
, and Controls
With the variants rendering, it'd be nice if you can present a component and manipulate it from the UIβa key feature of component workshops.
That's where argTypes
comes in. To establish argTypes
we use the defineMeta
function.
Here is the source of the example Button as an example
<script lang="ts">
import { Story, Controls } from "$lib/components/v4";
import Button from "$lib/Button.svelte";
import { defineMeta } from "book-emoji";
defineMeta<typeof Button>({
component: Button,
argTypes: {
variant: { type: "select", options: ["primary", "secondary", "tertiary"] },
size: { type: "select", options: ["small", "medium", "large"] },
disabled: { type: "boolean" },
loading: { type: "boolean" },
classes: { type: "text" },
type: { type: "select", options: ["button", "submit", "reset"] },
ariaLabel: { type: "text" },
text: { type: "text" },
},
});
</script>
<Story of={Button} name="Basic" args={{ variant: "primary", size: "medium", text: "Primary Button" }} />
<Controls of={Button} story="Basic" />
<Story of={Button} name="Secondary" args={{ variant: "secondary", size: "medium", text: "Secondary Button" }} />
<Controls of={Button} story="Secondary" />
<Story of={Button} name="Tertiary" args={{ variant: "tertiary", size: "medium", text: "Tertiary Button" }} />
<Controls of={Button} story="Tertiary" />
In the sample, the defineMeta
is what allows Controls
to know the types of args
of the components.
Controls
then is keyed by the name
/ story
properties.