-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React Typescript - Controls Addon enum control not rendering consistently #79
Comments
Thanks for the report. I believe the control types are extracted as part of the docgen generation, which doesn't work in this builder as it's coupled to the webpack loader used in storybook. There's an effort underway to decouple them, but as far as I know it's not ready yet. #46 (comment). |
Note: there's an experiment underway in #190, to add support for react-docgen. If you would like to try it out in your own project, you can replace the react vite plugin in your
There are also some good notes in #2 (comment), if you'd like a more flexible approach. Please provide feedback on whether the approach above meets your needs. We're also considering the use of react-docgen-typescript, but there are some tradeoffs, and it's currently implemented in storybook as a webpack loader, so there'd be some work needed to adapt it for vite (for which there is a commit in a branch: joshwooding@675506f). |
Related to #103 #2 #79 This PR adds doc-gen via react-docgen-typescript. | | Before | After| | --- | --- | --- | | Sidebar | ![localhost_52700__path=_story_example-introduction--page](https://user-images.githubusercontent.com/12938082/152376764-b5fa8048-8e7a-47fa-b15f-c10d1b0a3feb.png) | ![localhost_55358__path=_story_example-introduction--page](https://user-images.githubusercontent.com/12938082/152375596-eed09e52-03bf-4e6d-9ce0-b8ef28bfdbee.png) | Docs | ![image](https://user-images.githubusercontent.com/12938082/152377428-ffaa0b12-d453-4540-a0d3-b66d27371a1b.png) | ![image](https://user-images.githubusercontent.com/12938082/152378055-7d65504e-621f-48d6-a0d4-879171086832.png) I haven't noticed any significant impact to speed. 🎉 It's hooked up to the storybook config so it should act as a drop-in for the webpack functionality for typescript types.
@chrislegault We've just released https://github.com/eirslett/storybook-builder-vite/releases/tag/v0.1.15, which I think will address this issue. Could you please check and close this issue if your problem is resolved? |
@IanVS I'm using This is the one that generate the docs from args only import { ComponentMeta, ComponentStory } from "@storybook/react";
import { FiTrash } from "react-icons/fi";
import Button from "./BaseButton";
export default {
title: "Button",
component: Button,
} as ComponentMeta<typeof Button>;
const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />;
export const Base = Template.bind({});
Base.args = {
children: "Button",
color: "brand",
size: "md",
variant: "primary",
}; This is the output I expected. You can see that the props control rendered correctly as radio button when using an enum and not rendered as textbox. import { ComponentMeta, ComponentStory } from "@storybook/react";
import { FiMoon } from "react-icons/fi";
import IconButton from "./IconButton";
export default {
title: "Button/Icon Only",
component: IconButton,
} as ComponentMeta<typeof IconButton>;
const Template: ComponentStory<typeof IconButton> = (args) => (
<IconButton {...args} />
);
export const IconOnly = Template.bind({});
IconOnly.args = {
color: "brand",
icon: FiMoon,
size: "md",
variant: "primary",
}; The
export type ButtonColors = "brand" | "gray" | "green" | "red" | "yellow";
export type ButtonVariants = "primary" | "secondary" | "ghost";
export type ButtonSizes = "sm" | "md" | "lg";
interface ButtonBaseProps {
/** Choose between normal or full-width button */
block?: boolean;
/** Button colors */
color?: ButtonColors;
/** React element children */
children?: React.ReactNode;
/** Disabled state */
disabled?: boolean;
/** Set icon to be rendered in the button */
icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>;
/** Position of the icon to be rendered */
iconPosition?: "left" | "right";
/** Show loading indicator if set to `true` */
isLoading?: boolean;
/** Set loading text */
loadingText?: string;
/** Button sizes */
size?: ButtonSizes;
/** Button variants */
variant?: ButtonVariants;
}
export type ButtonProps = ButtonBaseProps &
React.ComponentPropsWithRef<"button">;
// For the sake of simplicity and example, I make it same as `ButtonProps` to see which one
// can generated the docs correctly.
export type IconButtonProps = ButtonBaseProps &
React.ComponentPropsWithRef<"button">; Might it useful to include the component file: import React from "react";
import { FiLoader } from "react-icons/fi";
import twClsx from "~/utils/tw-clsx";
import { ButtonProps } from "../types";
import {
buttonSizing,
buttonColorVariant,
createButtonIcon,
} from "../Button.helpers";
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
(
{
block,
color = "brand",
children,
className,
disabled,
isLoading,
icon,
iconPosition = "left",
loadingText = "Loading . . .",
size = "md",
variant = "primary",
...rest
},
ref
) => {
return (
<button
className={twClsx(
"inline-flex justify-center items-center gap-2 font-semibold rounded-md transition ease-in-out duration-200 focus:outline-none focus:ring",
buttonColorVariant(color, variant),
buttonSizing(size),
[isLoading && "disabled:cursor-progress"],
[block && "w-full"],
[iconPosition === "left" ? "flex-row" : "flex-row-reverse"],
className
)}
disabled={isLoading ?? disabled}
ref={ref}
{...rest}
>
{isLoading ? (
<>
<FiLoader className="animate-spin motion-reduce:hidden" />
{loadingText}
</>
) : (
<>
{createButtonIcon(icon)}
{children}
</>
)}
</button>
);
}
);
export default Button;
import React from "react";
import { FiLoader } from "react-icons/fi";
import twClsx from "~/utils/tw-clsx";
import { IconButtonProps } from "../types";
import {
buttonIconSizing,
buttonColorVariant,
createButtonIcon,
} from "../Button.helpers";
const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
(
{
color = "brand",
className,
disabled,
isLoading,
icon,
size = "md",
variant = "primary",
...rest
},
ref
) => {
return (
<button
className={twClsx(
"inline-flex justify-center items-center font-semibold rounded-md transition ease-in-out duration-200 focus:outline-none focus:ring",
buttonColorVariant(color, variant),
buttonIconSizing(size),
[isLoading && "disabled:cursor-progress"],
className
)}
disabled={isLoading ?? disabled}
ref={ref}
{...rest}
>
{isLoading ? (
<FiLoader className="animate-spin motion-reduce:animate-none" />
) : (
createButtonIcon(icon)
)}
</button>
);
}
);
export default IconButton; And here my storybook config file: const path = require("path");
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: "@storybook/react",
core: {
builder: "@storybook/builder-vite",
},
async viteFinal(config) {
return {
...config,
/**
* Import alias support
* @see https://github.com/storybookjs/builder-vite/issues/85#issuecomment-900831050
*/
resolve: {
alias: [{ find: "~", replacement: path.resolve(__dirname, "../src") }],
},
};
},
};
import "../src/styles/global.css";
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
expanded: true,
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}; Thanks! |
Thanks for the report. The best way for us to look into this is with a minimal reproduction. Do you think you could create a new vite storybook project that reproduces this issue? My guess is that the type definition for the icon prop is crashing typescript-react-docgen, but it would help us a ton to have a repo to poke around in. Thanks! |
Here I create a minimal reproduction for you to tinker around. For additional behavior notes, the first time I create the Thank you! |
Thanks for reporting this, and for the reproduction, @mupinnn. @joshwooding, you'll be interested in this one. I opened joshwooding/vite-plugin-react-docgen-typescript#2, since I think it's an issue in the react-docgen-typescript plugin. |
Hey, I tried it out to change the component name to be the same as the filename and it solved my issue right now. Probably the best workaround until joshwooding/vite-plugin-react-docgen-typescript#2 got an update. Thanks again @IanVS , I really appreciate it! |
Created a vite app and corresponding storybook using commands:
Firing up the storybook and looking at the Button -> Large story the control for the size prop renders as a text input. If you disable the vite builder in the main.js and use default webpack core it will render the size prop as radio buttons which is the documented control in Controls Docs
The control for the primary boolean property and the onClick are also missing. Manually providing the control config via argTypes will render the size control correctly.
Vite:
Webpack:
The text was updated successfully, but these errors were encountered: