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

[Switch] Implement the component-per-node API #135

Merged
merged 32 commits into from
Mar 25, 2024

Conversation

michaldudak
Copy link
Member

Closes #4

@michaldudak michaldudak added the component: switch This is the name of the generic UI component, not the React module! label Feb 29, 2024
Copy link
Member Author

Choose a reason for hiding this comment

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

ClassNameConfigurator will be removed, so it doesn't make sense to update its tests

@atomiks atomiks mentioned this pull request Mar 6, 2024
1 task
Copy link
Contributor

@colmtuite colmtuite left a comment

Choose a reason for hiding this comment

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

Tested it locally. All looks good except the inline <input> styles. Currently, it's not removed from document flow and is taking up screen space. We also need to block pointer events.

Suggested inline CSS:

height: 1px;
margin: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
transform: translateX(-100%);
width: 1px;

Edit: James is handling this differently in his Checkbox PR, so I guess let's just go with that CSS.

    border: 0px;
    clip: rect(0px, 0px, 0px, 0px);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0px;
    position: fixed;
    white-space: nowrap;
    width: 1px;
    top: 0px;
    left: 0px;

@michaldudak
Copy link
Member Author

michaldudak commented Mar 12, 2024

All right, let's extract these styles to a reusable function as they will be used in many places.

EDIT:
Actually, we already have an utility for this in @mui/utils. It's slightly different, though. @atomiks, @colmtuite, do you think this will work as well?

{
  border: 0,
  clip: 'rect(0 0 0 0)',
  height: '1px',
  margin: -1,
  overflow: 'hidden',
  padding: 0,
  position: 'absolute',
  whiteSpace: 'nowrap',
  width: '1px',
}

@colmtuite
Copy link
Contributor

Yep that looks good @michaldudak. margin value should be -1px though.

I assume you'll copy this across to the base ui repo?

@michaldudak
Copy link
Member Author

I'll fix it in the utils, then. I don't plan to copy it - we depend on @mui/utils anyway, so we can just import it.

@michaldudak michaldudak force-pushed the api-redesign/switch branch 5 times, most recently from efef3a6 to eb167be Compare March 14, 2024 15:44
Comment on lines 65 to 73
const getButtonProps: UseSwitchReturnValue['getButtonProps'] = (otherProps = {}) => ({
...otherProps,
type: 'button',
role: 'switch',
'aria-checked': checked,
'aria-disabled': disabled,
'aria-readonly': readOnly,
onClick: createHandleClick(otherProps),
});
Copy link
Contributor

Choose a reason for hiding this comment

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

The prop getters here should likely be memoized, so they can be passed to a memo'd component via the render prop where necessary. I also think it's cleaner to inline the event handlers inside the props themselves?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done. As for inlining - I'm not entirely convinced. I don't like too many levels of indentation. I moved the event handlers closer to these functions so it's easier to see both at the same time

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 mostly fine with either, but I do think inlining is simpler and the better option:

  • You don't need to specify types for the parameters, and there's less indirection
  • It's easier to read compared to the double function
  • It's colocated with the other props
  • The indentation is the same (8 spaces):

Separate

  const createHandleButtonClick = React.useCallback(
    (otherProps: React.ButtonHTMLAttributes<HTMLButtonElement>) =>
      (event: React.MouseEvent<HTMLButtonElement>) => {
        inputRef.current?.click();
12345678^
      },
    [readOnly],
  );

  const getButtonProps: UseSwitchReturnValue['getButtonProps'] = React.useCallback(
    (otherProps = {}) => ({
      onClick: createHandleButtonClick(otherProps),
    }),
    [checked, disabled, readOnly, createHandleButtonClick],
  );

Inline

  const getButtonProps: UseSwitchReturnValue['getButtonProps'] = React.useCallback(
    (otherProps = {}) => ({
      onClick(event) {
        inputRef.current?.click();
12345678^
      },
    }),
    [checked, disabled, readOnly],
  );

Overall, I'm not that concerned and think either is fine, but I feel inlining is easier to read and write.

@michaldudak michaldudak force-pushed the api-redesign/switch branch 3 times, most recently from f13f363 to ad79a8d Compare March 15, 2024 12:26
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 17, 2024
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 18, 2024
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 20, 2024
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 20, 2024
@michaldudak michaldudak marked this pull request as ready for review March 20, 2024 13:18
@michaldudak
Copy link
Member Author

@colmtuite, @atomiks, I think this is ready for the final review.

Comment on lines +8 to +10
export const Switch = combineComponentExports(SwitchRoot, {
Thumb: SwitchThumb,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

The API docs show import { SwitchThumb } from '@mui/base/SwitchThumb' being possible. Should this be the case, or just have the generator updated to show Switch.Thumb usage?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's an issue with the API docs generator I haven't fixed yet, but we can do this in a separate PR.

@michaldudak michaldudak merged commit fe6814c into mui:master Mar 25, 2024
16 checks passed
@michaldudak michaldudak deleted the api-redesign/switch branch March 25, 2024 14:19
@colmtuite
Copy link
Contributor

Being able to focus a disabled Switch is bothering me, but the same goes for all disabled components. We can chat about this elsewhere, just wanted to mention it here in case we loop back around later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: switch This is the name of the generic UI component, not the React module!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Switch] Implement new API
3 participants