Skip to content
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

Core: Restore useParameter behaviour for Docs entries #22071

Closed
wants to merge 10 commits into from

Conversation

tmeasday
Copy link
Member

@tmeasday tmeasday commented Apr 13, 2023

Closes #21798

What I did

  • Added two new events PROJECT_PREPARED and COMPONENT_PREPARED, analogous to STORY_PREPARED.
  • They transmit annotations (specifically argTypes and parameters) at appropriate times for components and the project.
  • Collect this information on the manager side:
    • Component annotations get stored in the index (both for local + refs), similar to the story annotations
    • Project annotations get stored at the top-level (both for local + ref)
  • Update getParameter (useParameter) to fall back to the component then the project if parameters are not available.

This means attached docs use the component's parameters -- in particular it means certain toolbars (backgrounds in essentials) appear again:

image

And unattached docs use the project's:

image

What I didn't do, but could in future:

  1. Also store globals+globalTypes in the state.projectAnnotations and ref.projectAnnotations. This, plus an update to getGlobals[Types] would address Composite Storybook does not show toolbars for the other storybooks #17759.
    A. Additional to this we should probably refactor the SET_GLOBALS event to just be part of PROJECT_PREPARED.
  2. Send over (initial) args (or other annotations) at the component or project level (I'm not sure if we should?). Then again, are argTypes useful without initial args?
  3. Refactor this code to read options from the project parameter rather than the first story, which seems like a good move!:
    if (!ref) {
    if (!store.getState().hasCalledSetOptions) {
    const { options } = update.parameters;
    fullAPI.setOptions(removeRemovedOptions(options));
    store.setState({ hasCalledSetOptions: true });
    }
    }

How to test

  • Run a sandbox, check toolbar behaviour
  • Check the same for composition!
  • See tests

Checklist

  • Make sure your changes are tested (stories and/or unit, integration, or end-to-end tests)
  • Make sure to add/update documentation regarding your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Maintainers

  • If this PR should be tested against many or all sandboxes,
    make sure to add the ci:merged or ci:daily GH label to it.
  • Make sure this PR contains one of the labels below.

["cleanup", "BREAKING CHANGE", "feature request", "bug", "documentation", "maintenance", "dependencies", "other"]

@tmeasday tmeasday added bug patch:yes Bugfix & documentation PR that need to be picked to main branch core labels Apr 13, 2023
@tmeasday tmeasday marked this pull request as ready for review April 13, 2023 11:54
Copy link
Member

@shilman shilman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work. I have questions though...

@@ -113,6 +119,10 @@ function removeRemovedOptions<T extends Record<string, any> = Record<string, any
return result;
}

function toComponentId(storyId: StoryId): ComponentId {
return storyId.split('--')[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a little surprised we don't have a utility in @storybok/csf for this. no big deal.

Copy link
Member Author

@tmeasday tmeasday Apr 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Me too. I didn't want to mess around with new CSF packages at this moment in time, but can if you disagree.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open a PR for this against the CSF package, but don't merge

}
}

// If not prepared, or a unattached doc, get the project's parameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens in the case it's not prepared? is there a race condition here? or is it handled somewhere else?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok read more of the PR and it looks like COMPONENT_PREPARED is emitted in the story render or the CSF Docs render. Are there other cases that need to be accounted for?

@@ -745,6 +790,13 @@ describe('PreviewWeb', () => {
expect(importFn).toHaveBeenCalledWith('./src/ComponentTwo.stories.js');
});

it('DOES NOT emit COMPONENT_PREPARED', async () => {
document.location.search = '?id=introduction--docs&viewMode=docs';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the component parameters wouldn't show in this case? Seems inconsistent?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no "component parameters" in this case as it is a MDX file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should emit the project parameters here.

@@ -29,6 +29,8 @@ import { DocsContext } from '../docs-context/DocsContext';
export class MdxDocsRender<TRenderer extends Renderer> implements Render<TRenderer> {
public readonly type: RenderType = 'docs';

public readonly subtype = 'mdx';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I guess in this case, it would not emit a COMPONENT_PREPARED .. but does that mean that the store is in a perpetually unprepared state?

@@ -45,6 +45,7 @@ const Main: FC<{ provider: Provider }> = ({ provider }) => {
docsOptions={global?.DOCS_OPTIONS || {}}
>
{({ state, api }: Combo) => {
console.log(useParameter('backgrounds'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
console.log(useParameter('backgrounds'));

Copy link
Contributor

@JReinhold JReinhold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! only a few minor requests

@quantizor
Copy link

@tmeasday thanks for working on this!

@tmeasday
Copy link
Member Author

Closing in favour of #22118, a simpler solution.

Some of the advantages of this PR we can explore in 7.1 under #22119

@tmeasday tmeasday closed this Apr 19, 2023
@stof stof deleted the tom/21798-fix-useParameter branch August 2, 2023 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug core patch:yes Bugfix & documentation PR that need to be picked to main branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: useParameter() returns nothing for a docs page
5 participants