Storybook/HTML for Addon-Docs - storybook

How can I add docs in 'mdx' format for my storie in Storybook/HTML? How can i connect my example.stories.js with example.stories.mdx, how example.stories.mdx should look like? On official documentation there is an example for React but I can`t find some guide dedicated for Storybook/HTML.

The key is to write the stories and docs separately, embedding the stories in the docs using their IDs (an ID of a story can be found in the URL, something like stories--story).
Let's say you have this index.stories.js file:
import docs from './docs.mdx'; // this import is important
export default {
title: 'Demo',
parameters: { // specify the docs MDX content here
docs: {
page: docs,
}
}
};
export const Heading = () => '<h1>Hello World</h1>';
export const Button = () => {
const btn = document.createElement('button');
btn.type = 'button';
btn.innerText = 'Hello Button';
btn.addEventListener('click', e => console.log(e));
return btn;
};
And the corresponding docs.mdx file would contain embedded stories:
import { Story, Preview } from '#storybook/addon-docs/blocks';
# Index
Writing `Markdown` here:
<Preview>
<Story id="demo--heading" />
<Story id="demo--button" />
</Preview>
And an individual story:
<Story id="demo--heading" />
Learn more:
MDX reference on embedding stories
Installation requirements for MDX

Related

Next.js 13 routing params

Hi folks first of all i am new to react and nextjs. So i am sorry if my question is stupid.
I am currently building a navigation with nextjs 13 within new the app folder. Here is my navigation component where i am building the category links with the component:
import React from 'react'
import fetchMainNavigation from '../lib/fetchMainNavigation'
import Link from 'next/link'
const DesktopNavigation = async () => {
const categories = await fetchMainNavigation
return (
<nav className={'hidden md:flex'}>
<ul className={'flex flex-row gap-4'}>
{categories.map((category) => (
<li key={category.id}>
<Link
href={`${category.id}`}
className={
'hover:underline hover:text-gold hover:scale-110 transition-transform duration-200'
}
>
{category.name}
</Link>
</li>
))}
</ul>
</nav>
)
}
export default DesktopNavigation
export async function generateStaticParams() {
const categories = await fetchMainNavigation
return categories.map((category) => ({
categoryId: category.id.toString(),
}))
}
I have also created a dynamic route "/app/[categoryId]/page.jsx". The routing works fine but now i have a not readable URL like "www.mypage.com/46asdfg56as8g" but i want something like "www.mypage.com/food". I know i could use the category name for routing but i need the categoryId as param within "/app/[categoryId]/page.jsx" to fetch information about the current active category. Is there a way to achieve this?
I have already searched the Next.js 13 documentation and also searched stackoverflow and other sources, but can't find anything about this problem yet.
It is in the beta documentation here. Also, under the very first category of the docs here
To utilize the next13 beta slugs, simply pass them in as the params property, as outlined in the official documentation.
const DesktopNavigation = async ({ params }) => {
const category = params['category'];
...
}

How can I create a layout that applies to all subfolders in a Next.js app?

I am trying to use .mdx files to easily create custom articles with Next.js.
I currently have this structure:
When going over a category, for example: /articles/math, I am able to show a gallery by using this code in my articles/[category]/index.tsx file:
const Category = () => {
const router = useRouter()
const category: string = router.query.category as string
return (
<Gallery type={category} />
)
}
Would there be a way to specify a layout for all my articles? Additionally, where should the index.tsx file be placed in this case, under articles/[category]/[article]? For example, I would like to achieve something like this:
const Article = () => {
return (
<article className="content-panel">
<div className="article-content">
// The current article information goes here
</div>
</article>
);
}

How to update MongoDB with added tags in Meteor

I'm working with my classmate on a project (https://github.com/samrent/tagCurator) where everyone could assign tags to random memes. This kind of folksonomy must help find relative-content over tags using a searchbar.
We are actually stuck at the input step as we cannot find a way for MangoDB to update the database when a new tags is putted, as you can see in the code below. Thank you for your help.
import { Template } from 'meteor/templating';
import { ImgCollection } from '../api/ImgCollection';
import './imageModule.html';
Template.imageModule.helpers({
Image() {
return ImgCollection.find();
},
});
Template.imageModule.events({
"submit .addTag"(event) {
// Prevent default browser form submit
event.preventDefault();
// Get value from form element
const target = event.target;
const text = target.text.value;
// Insert a task into the collection
ImgCollection.update({
tag: text,
});
// Clear form
target.text.value = '';
}
})```

next.js how to pass data to a page

Hi guys I'm learning some next.js and I'm trying to pass data from a data.js file to a page in the pages folder. I tried using getStaticProps but that needs an absolute URL. Below ill show an example of what I'm trying to do. Firstly is the page itself.
const page = ({ data }) => {
return (
<>
<p>{data.name}</p>
</>
);
};
export default page;
Then the data.js file looks like such.
export const user = [
{
id: 'Banana1',
password: 'Apple123',
name: 'Banana',
surname: 'Orange',
birthday: '10 March 2077',
cellNumber: '011 111 1111',
email: 'Banana#apple.com',
}
]
I know there is probably better methods of keeping the data but I'm just looking for something really simple for what I'm trying to do.
With help from #trash_dev I added the import { user } from '../path/to/datafile' in the page.js and also in the page.js removed the ({ data }) as that wasn't needed.
Then with help from #juliomalves when trying to use the data the array position had to be used so in my example it would be as follows:
const page = () => {
return (
<>
<p>{user[0].name}</p>
</>
);
};

How to Manage a Navigation Menu in NextJS with WordPress

I'm building a NextJS app using headless WordPress with GraphQL. It's not clear from the documentation where I should be calling the query to create the site navigation.
https://github.com/lfades/next.js/tree/examples/cms-wordpress/examples/cms-wordpress
The navigation is controlled dynamically by WordPress Menus (Appearance > Menus) on the backend and I can successfully access these menuItems via GraphQL without any issue on the index.js and posts/[slug].js page templates in Next JS.
// index.js
export default function Index({ primaryMenu = [] }) {
return (
<Layout>
<Header>
{primaryMenu.map((item, index) => {
return (<a href={item.url}>{item.label}</a>)
)}
</Header>
</Layout>
);
}
export async function getStaticProps() {
const primaryMenu = await getPrimaryMenu(); // Get menu via GraphQL
return {
props: { primaryMenu },
};
}
The issue I'm having with this is I am repeating the getStaticProps function on each template and I should be able to use some sort of global query for this, either in the <header/> component itself or another method. I'm unable to find documentation on how to do this and it doesn't work in components.
Any guidance (or examples) on where a global query such as a dynamic Navigation query would live in a NextJS app is appreciated.
There are a couple of ways you can do it:
You can menuItems query with useQuery() from #apollo/client inside the Layout component so that its available to all pages which are wrapped inside the Layout. However the problem with this is that, there will be a load time and the data won't be prefetched and readily available like we can do with getServerSideProps() ( at page level ). Because this will be at component level.
import { useQuery } from "#apollo/client";
export default function Layout () {
const { loading, data } = useQuery( GET_MENU_QUERY )
return {...}
}
You can use swr that uses caching strategy. There is blog that explains how to use it
I battled this for a while (for JD site) with redux and wp rest, but I think theory should be the same for gql + apollo client.
You need to override Next App _app with a custom class that extends App.
And you might need to inject an instance of apollo client into AppContext using a HOC. I used this wrapper for Redux. Would need to be modelled after that.
Edit: (Looks like someone has made it already)
// export default withRedux(makeStore)(MyApp);
export default withApollo(apolloClient)(MyApp); ???
Then in your App getInitialProps, you can make query to get menu. By default apollo client query will grab cached value if it's in the cache store already I believe.
static async getInitialProps(appContext) {
const { isServer, pathname, apollo? } = appContext.ctx;
// do menu query
const menu = apollo.query???
// Redux version
// const state = store.getState();
// let main_menu = state.menu;
// if (!state.menu) {
// const menu = await apiService().getMenu("main");
// main_menu = menu;
// store.dispatch({ type: "SET_MENU", payload: menu });
// }
...
// call the page's `getInitialProps` and fills `appProps.pageProps`
const initialProps = await App.getInitialProps(appContext);
const appProps: any = {
...initialProps,
menu: main_menu
};
return appProps;
}
Now menu is in the page props of the App Component, which can be passed down.
Or you can use apollo client to make the query again in a child component. So when you make the query again, in header or whatever, it will take the cached response provided it's the same query.
I made an endpoint for menus that included the template name + post slug along with the menu items and mapped the wp templates to next routes.
const menu = useSelector((state: any) => state.menu);
const menuItems = menu.map((item: any) => {
const path = getTemplatePath(item.template);
return (
<Link key={item.slug} href={`/${path}`} as={`/${item.slug}`} scroll={false}>
<a>{item.title}</a>
</Link>
);
});

Resources