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

Missing button group style injections when updating children className (React) #1926

Closed
Bielousov opened this issue Mar 15, 2024 · 5 comments · Fixed by #1928
Closed

Missing button group style injections when updating children className (React) #1926

Bielousov opened this issue Mar 15, 2024 · 5 comments · Fixed by #1928
Labels
bug Things that aren't working right in the library.

Comments

@Bielousov
Copy link

Bielousov commented Mar 15, 2024

Describe the bug

The Button Group component injected class names are lost after updating child component's className.

To Reproduce

  1. create a button group
  2. update any button className property after it is mounted

e.g.:

  const [className, setClassName] = useState('test1');
  useEffect(() => {
    setTimeout(() => setClassName('test2'), 2000);
  }, []);

  return (
    <SlButtonGroup>
      <SlButton className={className}>One</SlButton>
      <SlButton className={className}>Two</SlButton>
    </SlButtonGroup>
  );

Expected: the updated Button className should should have both className and injected Shoelace class names
Actual: only default className classes are set to the button inside the ButtonGroup

Presumably for the same reason, internal button group class names are also often reset after a hot refresh in dev.

Screenshots

Before the className changed After the className changed
Screenshot 2024-03-15 at 11 55 10 AM Screenshot 2024-03-15 at 11 54 59 AM
class="test1 sl-button-group__button sl-button-group__button--first" class="test2"
class="test1 sl-button-group__button sl-button-group__button--last" class="test2"
@Bielousov Bielousov added the bug Things that aren't working right in the library. label Mar 15, 2024
@claviska
Copy link
Member

Thanks for posting this. We'll probably need to switch to data attributes. I don't think we can avoid React replacing the entire class when using className.

@Bielousov
Copy link
Author

Bielousov commented Mar 15, 2024

Thanks for posting this. We'll probably need to switch to data attributes. I don't think we can avoid React replacing the entire class when using className.

Makes sense, I'm in fact working around this issue by using attributes.
Unless you find a reliable solution with pseudo-selectors, as in :first-child, :last-child, this should allow dynamic appending and deletion of children too. E.g.:

const [withDelete, setWithDelete] = useState(false);
useEffect(() => {
  setTimeout(() => setWithDelete(true), 2000);
}, []);

return (
  <SlButtonGroup>
    <SlButton>Action</SlButton>
    {withDelete && <SlButton>Delete</SlButton>}
  </SlButtonGroup>
);

This one is harder to work around with hidden attribute, for a different button should become --last.
If there was a method to re-initialize internal class names to call on re-render, that would probably do the job too.

@KonnorRogers
Copy link
Collaborator

@Bielousov There actually is. I had forgotten about this issue, but im 99% positive I can fix this. Let me see what I can do.

@KonnorRogers
Copy link
Collaborator

@KonnorRogers
Copy link
Collaborator

Since its hard to test the React version, heres the bare HTML version:

https://codepen.io/paramagicdev/pen/PogbZNb?editors=1000 <- Broken
https://codepen.io/paramagicdev/pen/XWQNXdo?editors=1000 <- Fixed

And heres the same codepen with the PR here: #1928

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Things that aren't working right in the library.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants