[英]How to style Rebass Switch
在反應中使用 Rebass/Forms,我無法正確使用 styles 正確調整 Switch 組件的大小。 (我也在使用@emotion/styled
)
我曾嘗試使用size
屬性,但這並沒有提供簡單更改開關比例的預期效果。
我試過使用sx
屬性並給它一個width
和一個height
,但這只會調整按鈕元素的大小,而不是“滑動點”的內部 div
我知道我可以編寫一些針對內部 div 本身的樣式,但我想找到一種方法來一次性給它一個高度和寬度,並且它適用於按鈕和內部 div。
<Switch
sx={{ width: "30px", height: "15px" }}
/>
因為高度和寬度在源代碼中是硬編碼的,所以不可能做你想要的“開箱即用”
幸運的是, rebass
的內部結構非常好,因此可以使用 rebass 源代碼中的一些復制粘貼來創建自己的。
import React from "react";
import { Box } from "reflexbox";
export const ResizableSwitch = ({
checked,
height = 24,
width = 40,
...props
}) => (
<Box
as="button"
type="button"
role="switch"
tx="forms"
variant="switch"
aria-checked={checked}
{...props}
__css={{
appearance: "none",
m: 0,
p: 0,
width,
height,
color: "primary",
bg: "transparent",
border: "1px solid",
borderColor: "primary",
borderRadius: 9999,
"&[aria-checked=true]": {
bg: "primary"
},
":focus": {
outline: "none",
boxShadow: "0 0 0 2px"
}
}}
>
<Box
aria-hidden
style={{
transform: checked ? `translateX(${width - height}px)` : "translateX(0)"
}}
sx={{
mt: "-1px",
ml: "-1px",
width: height,
height,
borderRadius: 9999,
border: "1px solid",
borderColor: "primary",
bg: "background",
transitionProperty: "transform",
transitionTimingFunction: "ease-out",
transitionDuration: "0.1s",
variant: "forms.switch.thumb"
}}
/>
</Box>
);
https://codesandbox.io/s/styling-rebass-switch-r6tmx?file=/src/App.js
不幸的是,你不能。 我對 package 本身進行了深入研究,似乎在 package 中編寫的組件沒有固定規則。 一些組件確實得到了props
和sx
。 但是有一些組件,比如switch
將另一個組件作為子組件托管,並且沒有傳遞給它的 prop。
如果您在這里查看此頁面中switch
的實現:
export const Switch = forwardRef(({
checked,
...props
}, ref) =>
<Box
ref={ref}
as='button'
type='button'
role='switch'
tx='forms'
variant='switch'
aria-checked={checked}
{...props}
__css={{
appearance: 'none',
m: 0,
p: 0,
width: 40,
height: 24,
color: 'primary',
bg: 'transparent',
border: '1px solid',
borderColor: 'primary',
borderRadius: 9999,
'&[aria-checked=true]': {
bg: 'primary',
},
':focus': {
outline: 'none',
boxShadow: '0 0 0 2px'
},
}}>
<Box
aria-hidden
style={{
transform: checked ? 'translateX(16px)' : 'translateX(0)',
}}
sx={{
mt: '-1px',
ml: '-1px',
width: 24,
height: 24,
borderRadius: 9999,
border: '1px solid',
borderColor: 'primary',
bg: 'background',
transitionProperty: 'transform',
transitionTimingFunction: 'ease-out',
transitionDuration: '0.1s',
variant: 'forms.switch.thumb',
}}
/>
</Box>
)
有 2 個Box
組件(它們是包的基礎組件),一個是另一個的子組件。 第一個Box
是開關的區域,子Box
是你要找的圓圈/按鈕,如果你看一下這個組件,你會看到沒有傳遞給它的外部變量,所以什么都不能改變 - 樣式已經寫好了。
這是 Button/Circle 組件:
<Box
aria-hidden
style={{
transform: checked ? 'translateX(16px)' : 'translateX(0)',
}}
sx={{
mt: '-1px',
ml: '-1px',
width: 24,
height: 24,
borderRadius: 9999,
border: '1px solid',
borderColor: 'primary',
bg: 'background',
transitionProperty: 'transform',
transitionTimingFunction: 'ease-out',
transitionDuration: '0.1s',
variant: 'forms.switch.thumb',
}}
/>
如果你仍然願意使用 package,你可以通過覆蓋 css 來克服這個問題,給組件一個 className 並對其子應用樣式。
另外,您可以在 package github 存儲庫上打開問題或提出修復建議。
查看Switch 源代碼,似乎沒有屬性傳播到內部<div>
...您會打開一個問題嗎?
同時,您可以為子級和/或基於屬性設置 css 屬性:
.myswitch {
width: 30px !important;
height: 15px !important;
background: gray !important;
}
.myswitch[aria-checked="true"] {
background: red !important;
}
.myswitch div {
width: 15px;
height: 15px;
background: red;
}
然后:
<Switch className="myswitch" />
您可以使用 CSS 變換比例來縮小/放大元素及其子元素。 因為,你正在使用情感,這里有一些與之相伴的東西。
代碼沙盒: https://codesandbox.io/s/styling-rebass-switch-5fqku?file=/src/App.js
import React, { useState } from "react";
import styled from "@emotion/styled";
import { Label, Checkbox, Switch } from "@rebass/forms";
const Title = styled.h1`
text-align: center;
`;
const FormLabel = styled(Label)`
align-items: center;
`;
const Control = styled.div`
width: 40px;
`;
const Toggle = styled(Switch)`
transform: scale(.7)
`;
export default function App() {
const [switched, setSwitched] = useState(false);
const toggleSwitch = () => {
setSwitched(!switched);
};
return (
<div className="App">
<Title>How to Style Rebass/Forms Switch</Title>
<FormLabel sx={{ padding: "10px" }}>
<Control>
<Checkbox size="16px" sx={{ marginLeft: "10px" }} />
</Control>
CheckBox
</FormLabel>
<FormLabel sx={{ padding: "10px" }}>
<Control>
<Toggle
checked={switched}
onClick={() => toggleSwitch()}
/>
</Control>
Switch
</FormLabel>
</div>
);
}
https://codesandbox.io/s/styling-rebass-switch-zto4z?file=/src/styles.css:37-1020
button.switch,
button.switch:hover,
button.switch:focus {
outline: none;
border: 1px solid grey;
box-shadow: none;
}
button.switch > div {
content: "";
width: 14px;
height: 14px;
background-color: #9fa2ab;
}
button.switch > div:after {
content: "";
position: absolute;
width: 20px;
height: 20px;
border-radius: 50%;
left: -2px;
top: -3px;
transition: left 0.3s ease, background-color 0.3s ease, box-shadow 0.1s ease,
transform 0.1s ease;
background-color: #5b5c60;
-webkit-box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2),
0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2),
0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
}
button.switch[aria-checked="true"] {
background-color: #d0f35e;
}
button.switch[aria-checked="true"] > div:after {
background-color: #86af00;
}
button.switch[aria-checked="false"] {
background-color: #ffffff;
left: 18px;
}
添加class開關
<Switch
className="switch"
sx={{ width: "30px", height: "15px" }}
checked={switched}
onClick={() => toggleSwitch()}
/>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.