Css 如何始终在聚焦材质UI按钮组件上应用focusVisible样式?
对于材质UI按钮组件,我希望“焦点”样式与“焦点可见”样式相同。这意味着我希望它具有相同的涟漪效应,如果按钮通过编程或鼠标聚焦,就像按钮通过tab键聚焦一样 我发现的一种解决方法是在元素聚焦之前调用Css 如何始终在聚焦材质UI按钮组件上应用focusVisible样式?,css,reactjs,button,material-ui,focus,Css,Reactjs,Button,Material Ui,Focus,对于材质UI按钮组件,我希望“焦点”样式与“焦点可见”样式相同。这意味着我希望它具有相同的涟漪效应,如果按钮通过编程或鼠标聚焦,就像按钮通过tab键聚焦一样 我发现的一种解决方法是在元素聚焦之前调用dispatchEvent(newwindow.Event(“keydown”)),从而使键盘成为最后使用的输入类型。这将使按钮看起来像我想要的那样,直到onMouseLeave事件(来自MUI)或另一个鼠标事件被触发,导致可见焦点消失 我已经知道如何更改组件的焦点样式,如下所示: import Re
dispatchEvent(newwindow.Event(“keydown”))
,从而使键盘成为最后使用的输入类型。这将使按钮看起来像我想要的那样,直到onMouseLeave事件(来自MUI)或另一个鼠标事件被触发,导致可见焦点消失
我已经知道如何更改组件的焦点样式,如下所示:
import React from "react"
import { withStyles } from "@material-ui/core/styles"
import Button from "@material-ui/core/Button"
const styles = {
root: {
'&:focus': {
border: "3px solid #000000"
}
}
}
const CustomButtonRaw = React.forwardRef((props, ref) => {
const { classes, ...rest } = props
return <Button classes={{root: classes.root}} {...rest} ref={ref}/>
}
const CustomButton = withStyles(styles, { name: "CustomButton" })(CustomButtonRaw)
export default CustomButton
从“React”导入React
从“@material ui/core/styles”导入{withStyles}”
从“@material ui/core/Button”导入按钮
常量样式={
根目录:{
“&:焦点”:{
边框:“3px固体#000000”
}
}
}
const CustomButtonRaw=React.forwardRef((props,ref)=>{
常量{classes,…rest}=props
返回
}
const CustomButton=with样式(样式,{name:“CustomButton”})(CustomButtonRaw)
导出默认自定义按钮
因此,当按钮处于“焦点”状态时,我可以对其应用一些样式。(例如,我应用了边框)。但我不知道如何应用样式。我尝试将类名“Mui visibleFocus”放在按钮上,但似乎没有效果。是否有某种方法可以获取按钮处于visibleFocus状态时将应用的样式?按钮库
(哪个按钮
)具有提供以下功能的
ButtonBase
为此利用了。要利用它,请将ref传递到操作
属性,然后可以稍后调用actionRef.current.focusVisible()
但是,这本身是不够的,因为有几个鼠标和触摸事件可用于启动/停止ripple。如果使用disableTouchRipple
道具,它将被禁用
不幸的是,disableTouchRipple
阻止了按钮上的点击和触摸动画。可以通过添加另一个明确由您控制的TouchRipple
元素来恢复这些动画。下面的示例显示了如何处理onMouseDown
和onMouseUp
作为概念证明,但理想的解决方案是处理all按钮库
处理的不同事件
下面是一个工作示例:
import React from "react";
import Button from "@material-ui/core/Button";
import TouchRipple from "@material-ui/core/ButtonBase/TouchRipple";
const FocusRippleButton = React.forwardRef(function FocusRippleButton(
{ onFocus, onMouseDown, onMouseUp, children, ...other },
ref
) {
const actionRef = React.useRef();
const rippleRef = React.useRef();
const handleFocus = (event) => {
actionRef.current.focusVisible();
if (onFocus) {
onFocus(event);
}
};
const handleMouseUp = (event) => {
rippleRef.current.stop(event);
if (onMouseUp) {
onMouseUp(event);
}
};
const handleMouseDown = (event) => {
rippleRef.current.start(event);
if (onMouseDown) {
onMouseDown(event);
}
};
return (
<Button
ref={ref}
action={actionRef}
disableTouchRipple
onFocus={handleFocus}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
{...other}
>
{children}
<TouchRipple ref={rippleRef} />
</Button>
);
});
export default function App() {
return (
<div className="App">
<FocusRippleButton variant="contained" color="primary">
Button 1
</FocusRippleButton>
<br />
<br />
<FocusRippleButton
variant="contained"
color="primary"
onFocus={() => console.log("Some extra onFocus functionality")}
>
Button 2
</FocusRippleButton>
</div>
);
}
从“React”导入React;
从“@物料界面/核心/按钮”导入按钮;
从“@material ui/core/ButtonBase/TouchRipple”导入TouchRipple;
const FocusRippleButton=React.forwardRef(函数FocusRippleButton(
{onFocus,onMouseDown,onmousedup,children,…other},
裁判
) {
const actionRef=React.useRef();
常量rippleRef=React.useRef();
const handleFocus=(事件)=>{
actionRef.current.focusVisible();
if(onFocus){
聚焦(事件);
}
};
const handleMouseUp=(事件)=>{
rippleRef.current.stop(事件);
如果(onMouseUp){
onMouseUp(事件);
}
};
常量handleMouseDown=(事件)=>{
rippleRef.current.start(事件);
if(onMouseDown){
onMouseDown(事件);
}
};
返回(
{儿童}
);
});
导出默认函数App(){
返回(
按钮1
log(“一些额外的onFocus功能”)}
>
按钮2
);
}
我们可以创建对物料ui
按钮的操作的引用,并使用useLayoutEffect
中的操作引用来实现连锁反应
import React, { createRef, useLayoutEffect } from "react";
import Button from "@material-ui/core/Button";
function FocusButton(props) {
const { handleClose } = props;
const actionRef = createRef();
useLayoutEffect(() => {
if (actionRef.current) {
actionRef.current.focusVisible();
}
}, []);
return (
<Button action={actionRef} onClick={handleClose}>
Ok
</Button>
);
}
你可以在这个中找到演示。嗨,Ryan,这很好,而且正是我要求的。但是使用这个应用“disableTouchRipple”道具的解决方案有一个问题:现在按钮不再有点击动画。你知道我如何从按钮库访问“rippleRef”,以便我自己触发涟漪吗?或者有没有一种方法可以让点击动画再次工作?点击动画的意思是,当你点击时,焦点涟漪会立即开始;尽管我意识到这是不同的——点击一个已经有焦点的按钮不会提供任何反馈。我找不到一种方法让焦点涟漪在没有di的情况下为点击工作sableTouchRipple
(我尝试了几种方法).Material UI不公开任何访问rippleRef
的方法。如果您试图通过触摸Ripplereprops
传递它,那么它会断开按钮库,因为它无法访问rippleRef
。如果不更改Material-UI,我看不到任何方法。似乎您是对的。我一直在尝试找到访问它的方法他rippleRef
但我认为没有一个…这很不幸。现在我想知道,是否可以使用一个单独的
元素自己创建动画?@user3044553是的,可以为点击动画添加一个单独的
元素。我已经更新了我的答案,以包含一个过于简单的元素(不处理ButtonBase
处理的所有事件)此版本。我面临同样的问题,遗憾的是仍然不起作用,发布了一条谚语“尝试了此方法,并使用ButtonBase的action ref提出了解决方案”
const buttonRef = createRef();
const handleButton2Click = () => {
buttonRef.current.focusVisible();
};
.
.
.
.
<Button action={buttonRef} variant="outlined">
Button 1
</Button>
<Button variant="outlined" color="primary" onClick={handleButton2Click}>
Button 2
</Button>