簡體   English   中英

如何設計 Rebass Switch 的樣式

[英]How to style Rebass Switch

在反應中使用 Rebass/Forms,我無法正確使用 styles 正確調整 Switch 組件的大小。 (我也在使用@emotion/styled

我曾嘗試使用size屬性,但這並沒有提供簡單更改開關比例的預期效果。

我試過使用sx屬性並給它一個width和一個height ,但這只會調整按鈕元素的大小,而不是“滑動點”的內部 div

我知道我可以編寫一些針對內部 div 本身的樣式,但我想找到一種方法來一次性給它一個高度和寬度,並且它適用於按鈕和內部 div。

<Switch
  sx={{ width: "30px", height: "15px" }}
/>

https://codesandbox.io/s/styling-rebass-switch-uu7wg

因為高度和寬度在源代碼中是硬編碼的,所以不可能做你想要的“開箱即用”

幸運的是, 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 中編寫的組件沒有固定規則。 一些組件確實得到了propssx 但是有一些組件,比如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" />

https://codesandbox.io/s/styling-rebass-switch-o0j8t

您可以使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM