Storybook Navigation System - storybook

Is it possible to call different stories into different left sidebar menu groupings? For example: I have a Button story that I would like to call in two different navigation places.

You can reimport a story from another files. A story is "just" a named exported function.
For example:
// component1.stories.js
...
export const MyStory = ...
then:
// component2.stories.js
export { MyStory } from './component1.stories.js';

Related

Tailwind colors from API call

I've had a look around and there doesn't really seem to be an answer to this.
I have an CMS API that provides things like branding colors etc... for a React app that can "reskin" it's self using a mix of colors and images etc...
I'm working on a V2 of this app and want to switch from sass/scss to tailwind. With sass and scss we kind of just overwrote colors with CSS in JS and it worked pretty well.
In tailwind if you want to add a custom color pallet you need to create a config file etc... This will not work for my indented use as the colors will be changing on the fly.
Imagine a component:
import { FC } from 'react';
const MyComponent: FC = () => {
return <div className='bg-blue-500'></div>;
};
This works great however if I want to change the color as a one off I could use a classname like bg-[#f1f1f1] and this also works great!
However the issue seems to come if I get React to put this color as a template string, like so:
import { FC } from 'react';
import { useBranding } from '../some_path';
const MyComponent: FC = () => {
const [branding] = useBranding(); // custom hook, all you need to know is it has colours that it spits out colors
return <div className={`bg-[${branding.colours.primary}]`}></div>;
};
At this point if I inspect the page I can see the color code goes in and should work. However I'm assuming that Tailwind has some preprocessing that get skipped if I do this?
Any ideas on how I can use colors in this way with tailwind?
Tailwind doesn't detect classes after build.
I might be wrong as you're not showing how your hook works, but I'd say you can use style tag instead:
import { FC } from 'react';
import { useBranding } from '../some_path';
const MyComponent: FC = () => {
const [branding] = useBranding(); // custom hook, all you need to know is it has colours that it spits out colors
return <div style={{backgroundColor: branding.colours.primary}}></div>;
};

Using global props in my component with storybook doesn't work

I'm having an issue with storybook. It seems that when I try to pass props from the component to my stories.js it doesn't find my global variable. Everything seems to work correctly, except for the props not showing, sending an error that my prop is undefined.
This is my Component.stories.js code
import Component from './Component';
export default {
title: "Component",
component: Component,
}
// prop1 and prop2 are gathered globally from a .json-file in my project
// prop1 and prop2 are lists
const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { Component },
template: '<Component :prop1="prop1" :prop2="prop2" />',
});
// Here I want to chose which props I want to show to be able to see it in storybook
export const allProps = Template.bind({});
allProps.args = {
prop1: ['prop1'],
prop2: ['prop2']
}
Is this even possible or how can I reach a global variable in stories? If there is a possible way to do this I'd love to hear it. I have googled for two days and didn't find anything that worked.
I did try to import the global variable inside my peview.js file but that didn't seem to help either.
I've tried changing globalTypes, argTypes, preview.js. And googled for 2 days. I want storybook to show all fields in my Component. Feel free to ask any questions.

How to use react-jss within react class Components?

In react-jss documentation, the authors have written:
'HOC based API is deprecated as of v10 and will be removed in v11.'
This means, as far as I understand, that such HOC functionality as injectSheet and withStyles will no longer be available in V11.
The new react-based stylesheet generating functions seem to be all based on react hooks. The function createUseStyles seemed very promising to myself and my team, until upon looking further into the source code we realised that it was only available within functional components, as it makes use of hooks.
The Problem
As a team we still make heavy use of React Class components and have no plans to move completely to hooks, not because hooks aren't useful, but because sometimes functional components aren't the best or most organised solution to writing a component.
Perhaps I'm missing something-- but it seems like there is now no solution left for React Class based components, other than writing our own manual implementation from core jss.
What solutions are there for a developer to make use of react-jss in a way similar to that achieved by createUseStyles, keeping up with the latest version of react-jss, being able to pass dynamic props, and etc. without writing a manual implementation?
While not specific to JSS, keep in mind that you can always use a tiny wrapper to convert any Hook to render prop or a HOC.
Converting Hook to a render prop is described here: https://reacttraining.com/blog/using-hooks-in-classes/
You can use a similar approach to convert any Hook to a HOC.
import { Classes } from 'jss';
import { createUseStyles } from 'react-jss';
First, lets create a more type safe function for creating styles.
export function createStyles(classes: { [name: string]: Partial<CSSStyleDeclaration> }) {
return createUseStyles(classes as any);
}
Secondly, we'll create a simple wrapper to allow hooks for our components.
function Styles<T extends string | number | symbol>(props: { styles: () => Classes<T>, children: (classes: Classes<T>) => ReactElement }) {
const classes = props.styles();
return props.children(classes);
}
Example
const styles = createStyles({
title: {
fontSize: '25px',
textTransform: 'uppercase'
},
message: {
color: 'red'
}
});
export const App = () => (
<Styles styles={styles}>
{classes => (
<Fragment>
<h1 className={classes.title}>Title</h1>
<p className={classes.message}>message</p>
</Fragment>
)}
</Styles>
);
Output

Need to pass prop(header_title) to layout.vue from news.vue

The project is built on Vue.js on top of Meteor.js. I need to pass a dynamic value from news.vue to layout.vue header_title area (refer layout.vue png).
I have set layout.vue file as the main layout of the app with navigation menu of the app and routing is also handling from layout.vue.
Related screenshots:
index.js
layout.vue
Use props in your Layout.vue
Layout.vue
export default {
props: ['headerTitle'],
// your other stuff here
}
News.vue
<layout :headerTitle="header_title"></layout>

Theme customization lost when rendering to string on client

I'm using material-ui-next and have customized the theme to use my color styles and a custom font. eg. Typography subheading
I'm now attempting to render a component to string for use in a google maps info window. The default material-ui theme is available in the callback styles object passed to withStyles, but none of my customizations are available on the theme argument in the styles callback nor are they applied. The rendered string renders otherwise correctly (albeit w/o events which I sorta expected).
More concisely, when rendering normally, customizations apply. When rendering to string, they do not.
A simple example would be a component that runs withStyles correctly, but return the div instead of the target component ala:
let output = ReactDOMServer.renderToString(component);
return <div dangerouslySetInnerHTML={{__html: output}} />
Any tips how I can get my theme customizations to be passed into the withStyles callback theme argument?
The solution was to make a parent component that renders the target component as a child of the ThemeProvider. There are still no event handlers (as expected), but the theme customizations apply.
Here's the solution:
MyThemeProvider.js (component can also easily be reused for SSR)
export default function MyThemeProvider({children}) {
const muiTheme = createMuiTheme({
typography: {
fontFamily: '"Bryant", "Helvetica", "Arial", sans-serif',
},
palette: {
primary: customBluePalette,
},
// ...
});
return (<MuiThemeProvider theme={muiTheme}>{ children }</MuiThemeProvider>);
}
MapInfoWindowContent.js (here, this only really exists to wrap VenueRenderer with our theme provider)
import MyThemeProvider from '../MyThemeProvider';
import VenueRenderer from '../VenueRenderer';
export default function MapInfoWindowContent({resource}) {
return (<MyThemeProvider><VenueRenderer resource={resource} /></MyThemeProvider>);
}
VenueRenderer (the styled class - can be used independently of MapInfoWindowContent too)
const styles = (theme) => {
// theme.palette.primary['500'] comes from customBluePalette so the injection worked.
}
// ...
export default withStyles(styles, { withTheme: true })(VenueRenderer);
In some other component that needs the HTML str
import ReactDOMServer from 'react-dom/server'
import MapInfoWindowContent from '../MapInfoWindowContent';
let infoWindowComponent = (<MapInfoWindowContent resource={ ... }/>);
let output = ReactDOMServer.renderToString(infoWindowComponent);
// output will have correctly injected classNames that contain customizations

Resources