iT邦幫忙

2021 iThome 鐵人賽

DAY 9
0
自我挑戰組

Material UI in React系列 第 9

Material UI in React [Day9] Inputs (Radio) 單選 & (Switch) 開關

  • 分享至 

  • xImage
  •  

Radio

當用戶需要查看所有可用選項時使用單選按鈕,如果可用選項可以折疊,請考慮使用下拉菜單(Select),因為它佔用的空間更少,官方文件

RadioGroup

和Checkbox的用法不一樣的地方大概就屬這個了,原本是用FormGroup,但在單選的情況下建議使用RadioGroup來包裝
對Radio組件進行分組。

<FormControl component="fieldset">
  <FormLabel component="legend">Gender</FormLabel>
  <RadioGroup aria-label="gender" name="gender1" value={value} onChange={handleChange}>
    <FormControlLabel value="female" control={<Radio />} label="Female" />
    <FormControlLabel value="male" control={<Radio />} label="Male" />
    <FormControlLabel value="other" control={<Radio />} label="Other" />
    <FormControlLabel value="disabled" disabled control={<Radio />} label="(Disabled option)" />
  </RadioGroup>
</FormControl>

其餘部分跟一般在處理 input type="radio" 一樣:

<FormControl component="fieldset">
  <FormLabel component="legend">labelPlacement</FormLabel>
  <RadioGroup row aria-label="position" name="position" defaultValue="top">
    <FormControlLabel
      value="top"
      control={<Radio color="primary" />}
      label="Top"
      labelPlacement="top"
    />
    <FormControlLabel
      value="start"
      control={<Radio color="primary" />}
      label="Start"
      labelPlacement="start"
    />
    <FormControlLabel
      value="bottom"
      control={<Radio color="primary" />}
      label="Bottom"
      labelPlacement="bottom"
    />
    <FormControlLabel
      value="end"
      control={<Radio color="primary" />}
      label="End"
    />
  </RadioGroup>
</FormControl>

Switch

這個組件和前面介紹過的checkbox用法都是一樣的,簡單來說就是換了skin的checkbox:

import React from 'react';
import Switch from '@material-ui/core/Switch';
import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';

export default function Switches() {
  const [state, setState] = React.useState({
    checkedA: true,
    checkedB: true,
    checkedC: true,
    checkedD: true,
  });

  const handleChange = (event) => {
    setState({ ...state, [event.target.name]: event.target.checked });
  };

  return (
    <div>
      <Switch
        checked={state.checkedA}
        onChange={handleChange}
        name="checkedA"
        inputProps={{ 'aria-label': 'secondary checkbox' }}
      />
      <Switch
        checked={state.checkedB}
        onChange={handleChange}
        color="primary"
        name="checkedB"
        inputProps={{ 'aria-label': 'primary checkbox' }}
      />
      <Switch inputProps={{ 'aria-label': 'primary checkbox' }} />
      <Switch disabled inputProps={{ 'aria-label': 'disabled checkbox' }} />
      <Switch disabled checked inputProps={{ 'aria-label': 'primary checkbox' }} />
      <Switch
        defaultChecked
        color="default"
        inputProps={{ 'aria-label': 'checkbox with default color' }}
      />
      <FormGroup row>
        <FormControlLabel
            control={
              <Switch
                checked={state.checkedC}
                onChange={handleChange}
                name="checkedC" />
            }
          label="Secondary"
        />
        <FormControlLabel
          control={
            <Switch
              checked={state.checkedD}
              onChange={handleChange}
              name="checkedD"
              color="primary"
            />
          }
          label="Primary"
        />
      </FormGroup>
    </div>
  );
}

自定義的部分可以參考之前所介紹的那三種方式更換樣式,或著像官方文件那樣的方式進行更改:

// 第一種是比較輕量直接引入顏色的方式修改
const PurpleSwitch = withStyles({
  switchBase: {
    color: purple[300],
    '&$checked': {
      color: purple[500],
    },
    '&$checked + $track': {
      backgroundColor: purple[500],
    },
  },
  checked: {},
  track: {},
})(Switch);
// 這邊用到的css name可以參考(https://material-ui.com/api/switch/#css)

// 第二種是塞入callback的方式來修改
const IOSSwitch = withStyles((theme) => ({
  root: {
    width: 42,
    height: 26,
    padding: 0,
    margin: theme.spacing(1),
  },
  switchBase: {
    padding: 1,
    '&$checked': {
      transform: 'translateX(16px)',
      color: theme.palette.common.white,
      '& + $track': {
        backgroundColor: '#52d869',
        opacity: 1,
        border: 'none',
      },
    },
    '&$focusVisible $thumb': {
      color: '#52d869',
      border: '6px solid #fff',
    },
  },
  thumb: {
    width: 24,
    height: 24,
  },
  track: {
    borderRadius: 26 / 2,
    border: `1px solid ${theme.palette.grey[400]}`,
    backgroundColor: theme.palette.grey[50],
    opacity: 1,
    transition: theme.transitions.create(['background-color', 'border']),
  },
  checked: {},
  focusVisible: {},
}))(({ classes, ...props }) => {
  return (
    <Switch
      focusVisibleClassName={classes.focusVisible}
      disableRipple
      classes={{
        root: classes.root,
        switchBase: classes.switchBase,
        thumb: classes.thumb,
        track: classes.track,
        checked: classes.checked,
      }}
      {...props}
    />
  );
});

// 第三種用到的css name可以參考(https://material-ui.com/api/switch/#css)
const AntSwitch = withStyles((theme) => ({
  root: {
    width: 28,
    height: 16,
    padding: 0,
    display: 'flex',
  },
  switchBase: {
    padding: 2,
    color: theme.palette.grey[500],
    '&$checked': {
      transform: 'translateX(12px)',
      color: theme.palette.common.white,
      '& + $track': {
        opacity: 1,
        backgroundColor: theme.palette.primary.main,
        borderColor: theme.palette.primary.main,
      },
    },
  },
  thumb: {
    width: 12,
    height: 12,
    boxShadow: 'none',
  },
  track: {
    border: `1px solid ${theme.palette.grey[500]}`,
    borderRadius: 16 / 2,
    opacity: 1,
    backgroundColor: theme.palette.common.white,
  },
  checked: {},
}))(Switch);

關於什麼時候該用checkbox,而什麼時候該用switch? 可以參考這篇
以上就是今天的全部內容了,明天會接續講解TextField的部分


上一篇
Material UI in React [ Day 8 ] Inputs(Checkbox) 多選
下一篇
Material UI in React [Day 10] Inputs (Text Field) 文本輸入框
系列文
Material UI in React30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言