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

Provide a way to control UI states #6403

Open
unional opened this issue May 17, 2024 · 4 comments
Open

Provide a way to control UI states #6403

unional opened this issue May 17, 2024 · 4 comments

Comments

@unional
Copy link

unional commented May 17, 2024

Provide a general summary of the feature here

When creating component documentation, e.g. using storybook,
I want to create a story that show the component in various states.

For example, creating a story for a button, and showing how it looks like normally, when pressed, when hover, when focused, etc.

I couldn't do that write now because using css selector doesn't change the state object in:

<Button className={(state) => ...}/>

And the ButtonContext doesn't seem to work with UI states:

<ButtonContext.Provider value={{ isPressed: true, isDisabled: true }}>
  <Button
    className={(state) => {
      console.log('state', state)
      return ''
    }}
  >
    Click me
  </Button>
</ButtonContext.Provider>

It prints isDisabled: true but isPressed: false. Also it does not have other states (like isFocusVisible).

I can do it if I break it down to one story per component per state, and use user.event() to cause the state change.

But the number of stories will explode and it is very hard to navigate.

🤔 Expected Behavior?

Have a way to do that.

😯 Current Behavior

No good way to do that statically.

💁 Possible Solution

Maybe provide a <UIStateContext.Provider/>

🔦 Context

Creating a nice documentation

💻 Examples

No response

🧢 Your Company/Team

Palo Alto Networks

🕷 Tracking Issue

No response

@snowystinger
Copy link
Member

Duplicate of #6198

@snowystinger snowystinger marked this as a duplicate of #6198 May 17, 2024
@unional
Copy link
Author

unional commented May 17, 2024

Argh, thanks. I tried to search for isPressed and focusVisible so couldn't find that issue.

btw I just think of a better alternative.
The key is to extract the className handler out and apply it early in the story:

export function MyButton(props: MyButtonProps) {
  // ...
  return <Button className={state => getMyButtonClassName(props, state)} .../>
}

export function getMyButtonClassName(props, state) { ... }

// my_button.stories.tsx

export const Showcase = {
  render() {
    return <MyButton className={getMyButtonClassName({ ... }, { isPressed: true })} ... />
  }
}

@snowystinger
Copy link
Member

Ah, that's a great approach. Thanks for sharing!
And no worries. I'm in here all the time, much easier for me to find a duplicate.

@unional
Copy link
Author

unional commented May 17, 2024

Amend to the solution I have, some mocking function is needed to promote the mocked state classes to regular classes.

For example using Tailwind, hover:... needs to be promoted to ... and use tailwind-merge to enforce class order.

As I looked into these states, it seems like the <Link> component is missing the isVisited state, and isTargeted state is missing from components in general.

Reopening this for now to address the issues.

@unional unional reopened this May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants