Change a storybook arg without creating a custom hook component

Viewed 132

I'm trying to change the value of a story arg while using the standard (recommended) args pattern. I found this article that seems to show that it's possible, but it is out of date. I've got the following libraries installed:

    "@storybook/addon-essentials": "^6.4.9",
    "@storybook/addon-links": "^6.4.9",
    "@storybook/api": "^6.5.9",
    "@storybook/react": "^6.4.9",
    "@storybook/addons": "^6.5.9",

My story is:

import { useArgs } from '@storybook/api';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import React from 'react';

import { defaultSwatches, x1y4 } from './defaultSwatches';
import ColorPicker, { ColorPickerSwatch } from './index';

export default {
    title: 'Components/ColorPicker',
    component: ColorPicker,
    argTypes: {
        backgroundColor: { control: 'color' },
    },
    args: {
        swatches: defaultSwatches,
        title: 'Select a color',
        onClickSwatch: (swatch: ColorPickerSwatch) => {
            console.log(swatch);
        },
        onClickClose: () => console.log('Close it'),
        selected: x1y4.id,
    },
} as ComponentMeta<typeof ColorPicker>;


export const Template: ComponentStory<typeof ColorPicker> = ({
    onClickSwatch,
    ...args
}) => {
    const [, updateArgs] = useArgs();
    const handlePick = (swatch: any) => updateArgs({ selected: swatch.id });
    return <ColorPicker onClickSwatch={handlePick} {...args} />;

I've also tried this:

import { useArgs } from '@storybook/api';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import React from 'react';

import { defaultSwatches, x1y4 } from './defaultSwatches';
import ColorPicker, { ColorPickerSwatch } from './index';

export default {
    title: 'Components/ColorPicker',
    component: ColorPicker,
    argTypes: {
        backgroundColor: { control: 'color' },
    },
} as ComponentMeta<typeof ColorPicker>;

const Template: ComponentStory<typeof ColorPicker> = ({ onClickSwatch, ...args }) => {
    const [, updateArgs] = useArgs();
    const handlePick = (swatch: any) => updateArgs({ selected: swatch.id });
    return <ColorPicker onClickSwatch={handlePick} {...args} />;
};

export const Primary = Template.bind({});

Primary.args = {
    swatches: defaultSwatches,
    title: 'Select a color',
    onClickSwatch: (swatch: ColorPickerSwatch) => {
        console.log(swatch);
    },
    onClickClose: () => console.log('Close it, punk!'),
    selected: x1y4.id,
};

Both times when the story loads I get the following errors:

_useStorybookApi is undefined
The above error occurred in the <unboundStoryFn> component:
in unboundStoryFn
in ErrorBoundary
1 Answers

Faced with the same issue. Looks like useArgs works if imported from the @storybook/client-api (marked as deprecated) library instead of @storybook/api:

import { useArgs } from '@storybook/client-api';
Related