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

UI: Improve controls addon #23635

Merged
merged 34 commits into from Aug 2, 2023
Merged

UI: Improve controls addon #23635

merged 34 commits into from Aug 2, 2023

Conversation

cdedreuille
Copy link
Contributor

@cdedreuille cdedreuille commented Jul 27, 2023

What I did

In this PR I am improve how controls look when the story is loading and when the story doesn't have args set up. Today we are showing a yellow warning banner in both cases. This is not ideal and could be considered as a bug even though you sometimes don't need args. We are turning the narrative to make the message more descriptive of what controls are with clear links on how to get started.

  • Add a new Empty state when controls are not setup
  • Add a new Skeleton component when the story is loading
  • Added a link to setup controls on the controls column when there's no controls

This PR also includes:

  • Fix export for Select, Input in the experimental component library
  • Added a new Icon component (used in the empty state of the ArgsTable
  • Added a new Link component (Used in the Args Table)
  • Replace FakeIcon with the new Icon component
  • Fix experimental misspelling

How to test

  1. Fetch this branch locally
  2. Run Storybook UI locally using yarn storybook:ui
  3. To test the loading state, access any story and reload the page
  4. To test the empty state, go to http://localhost:6006/?path=/story/blocks-components-emptyblock--error&globals=theme:light
  5. To test the "setup controls" link in the args table, go to https://635781f3500dd2c49e189caf-csejcfbxls.chromatic.com/?path=/story/components-scrollarea--vertical and hover any rows

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

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli/src/sandbox-templates.ts
  • Make sure this PR contains one of the labels below.

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

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>

@cdedreuille cdedreuille added maintenance User-facing maintenance tasks ci:normal patch:no labels Jul 27, 2023
@socket-security
Copy link

socket-security bot commented Jul 31, 2023

No top level dependency changes detected. Learn more about Socket for GitHub ↗︎

@socket-security
Copy link

socket-security bot commented Jul 31, 2023

👍 Dependency issues cleared. Learn more about Socket for GitHub ↗︎

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

@cdedreuille cdedreuille marked this pull request as ready for review August 1, 2023 07:36
@cdedreuille cdedreuille self-assigned this Aug 1, 2023
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.

I'm experiencing some buggy behavior, as demonstrated here:

Area.mp4
  1. On page load (reload), the panel is in a loading state. ✅
  2. When switching to another addon panel and back to controls, the controls will be forever loading. ❌
  3. When switching to new stories that have never been rendered before, it won't show the loading state but briefly flash the empty state. ❌
  4. Navigating to previously rendered stories will show the controls right away without loading or empty-state ✅
  5. Non-ready controls will have the "Setup controls" link on hover. ✅

Number 2 is a deal breaker here, but I think 3 is okay for now.

@cdedreuille
Copy link
Contributor Author

Thanks @JReinhold. I'll look at these 2 use cases.

@JReinhold
Copy link
Contributor

As I side note, I'm pretty sure there are some research on the topic of loading states, suggesting that there are ideal timings for when to show them or not.

Eg. in the first 0.3 seconds, a loading indicator is not necessary and will distract more than it does good, because of the brief flash.
It would be great to incorporate that into this design to give it the last polish.

Unfortunately I can't find said research, or figure out what this ideal timing is.

@cdedreuille
Copy link
Contributor Author

@JReinhold That's not the issue. We don't want to show the loading state when switching stories as it is indeed too short but today if the story is cached the switch will be instantaneous which is nice but for stories not cached you see briefly the empty state instead. But I might have an idea on how to solve this one.

@cdedreuille
Copy link
Contributor Author

cdedreuille commented Aug 2, 2023

Controls.mp4

@JReinhold I found a way to make 2 and 3 work so we never see the empty state if we don't need it. I added a delay to render the empty state. For now this is the only solution I believe without doing more refactoring or creating new states.

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.

Minor feedback regarding your last changes

hideNoControlsWarning?: boolean;
}

export const ControlsPanel: FC = () => {
const [isLoading, setIsLoading] = useState(true);
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor suggestion here:

Suggested change
const [isLoading, setIsLoading] = useState(true);
const [isLoading, setIsLoading] = useState(!previewInitiated);

It requires that you move this below useStorybookState().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I made the change.

Comment on lines +34 to +36
useEffect(() => {
if (previewInitialized) setIsLoading(false);
}, [previewInitialized]);
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm honestly not sure what happens if you call setState with the same state that it already has.

Suggested change
useEffect(() => {
if (previewInitialized) setIsLoading(false);
}, [previewInitialized]);
useEffect(() => {
if (previewInitialized && isLoading) setIsLoading(false);
}, [previewInitialized]);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As agreed let's not do that as we are at risk of creating an infinite loop in the useEffect.

Copy link
Member

Choose a reason for hiding this comment

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

make sure to add isLoading and setIsLoading to the hook dependencies array too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We agreed not to do that @yannbf. It's working without it.

@JReinhold JReinhold merged commit 0005430 into next Aug 2, 2023
59 checks passed
@JReinhold JReinhold deleted the charles-update-controls-addon branch August 2, 2023 09:02
@github-actions github-actions bot mentioned this pull request Aug 2, 2023
14 tasks
@TrySound
Copy link

TrySound commented Aug 3, 2023

@cdedreuille @JReinhold icons packages depends on very old svgr and svgo versions with many vulnerable or deprecated packages. And why it even depends on svgr? Isn't it a collection of prebuilt icons?

@TrySound
Copy link

TrySound commented Aug 3, 2023

@cdedreuille
Copy link
Contributor Author

@TrySound it should not depend on svgr. We are only using it to generate icons from Figma.

@TrySound
Copy link

TrySound commented Aug 3, 2023

So none of these dependencies are really needed?
https://github.com/storybookjs/icons/blob/main/package.json#L99-L106

@cdedreuille
Copy link
Contributor Author

You’re right. We need to move them into devDependencies.

TrySound added a commit to TrySound/icons that referenced this pull request Aug 3, 2023
Ref storybookjs/storybook#23635 (comment)

Looks like all dependencies are build only and should not bloat user
installation with deprecated and vulnerable packages.
@TrySound
Copy link

TrySound commented Aug 3, 2023

storybookjs/icons#14

ndelangen added a commit that referenced this pull request Aug 21, 2023
…trols-addon"

This reverts commit 0005430, reversing
changes made to a70dcab.
Comment on lines +68 to +77
if (!control || control.disable)
return isHovered ? (
<Link
href="https://storybook.js.org/docs/react/essentials/controls"
target="_blank"
withArrow
>
Setup controls
</Link>
) : (
Copy link

@MWhite-22 MWhite-22 Sep 19, 2023

Choose a reason for hiding this comment

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

@cdedreuille @JReinhold Can we find a way to make this Link optional? When rendering action props (aka: onChange, onClick, etc.) they have no control, but they're handled by the actions addon. With this change, even though their control should be empty, we render the link on hover.

I have other examples beyond just action props, but ideally I would like to globally disable any "Setup controls" links with a parameter or something similar.

Copy link

@MWhite-22 MWhite-22 Sep 19, 2023

Choose a reason for hiding this comment

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

For example, the only reason I need control: { type: null } on the below argTypes is to prevent the link from rendering on hover in the ArgsTable.

image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@MWhite-22 Thanks for your feedback. I see what you mean but I'm not sure why this links is a problem. Are you using the controls as a tool or as a way to show what props you can edit?

Choose a reason for hiding this comment

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

We use storybook as public interactive docs for our component library.

The default behavior of rendering the link on hover makes it look like our docs are not completed, and we like to be incredibly thorough.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a link I can look at? Generally speaking, I think there's a clear distinction between docs and controls. Docs are specifically meant to document your components where controls is more about testing. But I can understand that some users like you can use controls as a way to document your stories. I'll try to think if there's a way to achieve what you need without docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ci:normal maintenance User-facing maintenance tasks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants