-
-
Notifications
You must be signed in to change notification settings - Fork 46
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
Conversation
There was a problem hiding this comment.
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
There was a problem hiding this 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;
All right, let's extract these styles to a reusable function as they will be used in many places. EDIT: {
border: 0,
clip: 'rect(0 0 0 0)',
height: '1px',
margin: -1,
overflow: 'hidden',
padding: 0,
position: 'absolute',
whiteSpace: 'nowrap',
width: '1px',
} |
Yep that looks good @michaldudak. I assume you'll copy this across to the base ui repo? |
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. |
803aa39
to
a9e6d54
Compare
efef3a6
to
eb167be
Compare
const getButtonProps: UseSwitchReturnValue['getButtonProps'] = (otherProps = {}) => ({ | ||
...otherProps, | ||
type: 'button', | ||
role: 'switch', | ||
'aria-checked': checked, | ||
'aria-disabled': disabled, | ||
'aria-readonly': readOnly, | ||
onClick: createHandleClick(otherProps), | ||
}); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
f13f363
to
ad79a8d
Compare
ad79a8d
to
ad569ba
Compare
ad569ba
to
e44c27d
Compare
e44c27d
to
83b67c0
Compare
@colmtuite, @atomiks, I think this is ready for the final review. |
export const Switch = combineComponentExports(SwitchRoot, { | ||
Thumb: SwitchThumb, | ||
}); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
d057ce1
to
9ffee33
Compare
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. |
Closes #4