material-ui - 使用ClojureScript,如何自定义material-ui滑块组件中的ValueLabel?
问题描述
在这里,有一个例子展示了如何使用 javascript 自定义 ValueLabel。
import React from "react";
import { withStyles, makeStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import Slider from "@material-ui/core/Slider";
import ValueLabel from "@material-ui/core/Slider/ValueLabel";
const StyledValueLabel = withStyles({
offset: {
top: -28,
left: props => props.index === 0 ? "calc(-50% + -20px)" : "calc(-50% + 12px)"
},
circle: {
transform: props => props.index === 0 ? "rotate(-90deg)" : "rotate(0deg)"
},
label: {
transform: props => props.index === 0 ? "rotate(90deg)" : "rotate(0deg)"
}
})(ValueLabel);
const useStyles = makeStyles({
root: {
width: 300
}
});
const MySlider = withStyles({
root: {
color: "#3880ff",
height: 2,
padding: "15px 0"
},
track: {
height: 4
},
thumb: {
background: "transparent",
"&:focus,&:hover,&$active": {
boxShadow: "inherit"
}
},
rail: {
height: 4,
opacity: 0.5,
backgroundColor: "#bfbfbf"
},
mark: {
backgroundColor: "#bfbfbf",
height: 8,
width: 1,
marginTop: -2
}
})(Slider);
function valuetext(value) {
return `${value}°C`;
}
export default function RangeSlider() {
const classes = useStyles();
const [value] = React.useState([31, 37]);
return (
<div className={classes.root}>
<Typography id="range-slider" gutterBottom>
Temperature range
</Typography>
<MySlider
defaultValue={value}
valueLabelDisplay="on"
ValueLabelComponent={StyledValueLabel}
aria-labelledby="range-slider"
getAriaValueText={valuetext}
/>
</div>
);
}
我尝试将其更改为 ClojureScript 版本,但它不起作用。
(ns XXXX
(:require [reagent-material-ui.components :as mui]
[reagent.core :as reagent]
[reagent-material-ui.styles :as styles]
["@material-ui/core/Slider/ValueLabel" :as js-vl]))
...
(let [vlb (styles/with-styles {:circle {:width 40 :height 40}}
(reagent/adapt-react-class (.-default js-vl)))]
[mui/slider
{:valuelabelcomponent vlb}])
我收到控制台错误,例如:
Warning: Invalid value for prop `valuelabelcomponent` on <span> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://reactjs.org/link/attribute-behavior
at span
at eval (http://localhost:5555/ui/cljs-runtime/module$node_modules$$material_ui$core$esm$Slider$Slider.js:16:209)
at WithStyles(ForwardRef) (http://localhost:5555/ui/cljs-runtime/module$node_modules$$material_ui$styles$withStyles$withStyles.js:4:435)
at div
解决方案
首先,我认为此类问题更适合Clojureverse论坛,因为您有更好的机会接触到 Clojure 社区。另外,我认为有办法改善你原来的问题。例如:解释一下你在你的例子中到底想做什么但没有奏效?(很抱歉我选择了这个,但期望 30 行 JSX 和 4 行 Clojure 以相同的方式工作对我来说真的没有意义。它们一定是不同的。)
问题
要获得完整的答案,让我们从我在 Clojure 代码段中注意到的问题开始:
(警告不是错误。但是它们可能与错误密切相关。)
道具的大小写。
ValueLabelComponent
props的正确关键字是:ValueLabelComponet
. Reagent 是 React 的一个瘦包装器,它直接将 react 名称转换为 Clojure 关键字,而无需修改名称。的用法
reagent-material-ui.styles/with-styles
。从它的文档字符串:
采用样式生成函数或样式对象。
:classes
返回包装另一个组件并向其添加道具的高阶组件。注意:输入组件必须将其所有道具(包括孩子)放在一个地图中。
- React 组件和 Reagent 组件的区别。这是从试剂文档中大量阅读的内容。尽管它们的相似程度有点令人难以置信,但事实并非如此。尤其是当您与外部 React 库进行大量互操作时。
在 ClojureScript 中为 MaterialUI Slider 自定义 ValueLabel 的示例
我将这个示例放在一起,说明如何在不为您解决所有问题的情况下将各个部分组合在一起,假设您的目标是翻译上面 JSX 片段的每一部分。我希望这足以让你解决剩下的问题。
特别注意 React 组件和 Reagent 组件的区别。
(ns example.core
(:require
[reagent-material-ui.core.slider :refer [slider]]
[reagent-material-ui.styles :as styles]
[reagent.core :as r]
[reagent.dom :as rdom]
["@material-ui/core/Slider/ValueLabel" :as MuiValueLabel]))
(def mui-value-label
(r/adapt-react-class (or (.-default MuiValueLabel)
(.-ValueLabel MuiValueLabel))))
(def with-my-styles
(styles/with-styles {:offset {:top 50 :left 50}}))
(defn styled-value-label
[props]
[(with-my-styles mui-value-label) props])
(defn main []
[slider
{:defaultValue [31 37]
:valueLabelDisplay "on"
:ValueLabelComponent (r/reactify-component styled-value-label)}])
;; Something that renders the component like:
;; (rdom/render [main] (js/document.getElementById "app"))
结果
值标签向下偏移 50px,向右偏移 50px:
随时评论我的答案,以便我对其进行编辑。干杯!
推荐阅读
- java - 为什么背景颜色不会用 repaint(e) 填充?
- python - 求解多个参数的方程/表达式
- javascript - 如何选择要显示的特定数量的过滤项目?
- python - tkinter 无法从自身获取属性
- java - 我的解决方案的时间复杂度是多少?
- android - Android:布局的任何视图上的 androidx.test.espresso.AmbiguousViewMatcherException
- python - 如何将两个数组保存为文本文件,并以制表符作为列分隔符?
- r - 使用 Raster 包中的 getData 提取高程数据
- python - 设置字符串输入以接受来自可接受答案数组的答案(Python 3.8.4)
- javascript - 尝试将事件处理程序附加到动态创建的 JavaScript 元素