Forms/Switch: Simplifies and adjusts CSS/Markup (#22129)

- Fixes CSS so switch dot is symmetrical when checked/unchecked
- Fixes CSS so hover styles are applied
This commit is contained in:
kay delaney 2020-02-12 18:05:56 +00:00 committed by GitHub
parent 003fb4a3d0
commit ef36276584
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,7 +1,8 @@
import React, { HTMLProps } from 'react'; import React, { HTMLProps } from 'react';
import { stylesFactory, useTheme } from '../../themes';
import { GrafanaTheme } from '@grafana/data';
import { css, cx } from 'emotion'; import { css, cx } from 'emotion';
import uniqueId from 'lodash/uniqueId';
import { GrafanaTheme } from '@grafana/data';
import { stylesFactory, useTheme } from '../../themes';
import { getFocusCss } from './commonStyles'; import { getFocusCss } from './commonStyles';
export interface SwitchProps extends Omit<HTMLProps<HTMLInputElement>, 'value'> { export interface SwitchProps extends Omit<HTMLProps<HTMLInputElement>, 'value'> {
@ -17,68 +18,68 @@ export const getSwitchStyles = stylesFactory((theme: GrafanaTheme) => {
input { input {
opacity: 0; opacity: 0;
width: 100% !important; left: -100vw;
height: 100%; z-index: -1000;
position: relative; position: absolute;
z-index: 1;
cursor: pointer;
&:focus ~ div { &:disabled + label {
${getFocusCss(theme)};
}
&[disabled] {
background: ${theme.colors.formSwitchBgDisabled}; background: ${theme.colors.formSwitchBgDisabled};
cursor: not-allowed;
}
&:checked + label {
background: ${theme.colors.formSwitchBgActive};
&:hover {
background: ${theme.colors.formSwitchBgActiveHover};
}
&::after {
transform: translate3d(18px, -50%, 0);
}
}
&:focus + label {
${getFocusCss(theme)};
} }
} }
input ~ div { label {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: red; cursor: pointer;
z-index: 0; border: none;
position: absolute; border-radius: 50px;
top: 0;
left: 0;
background: ${theme.colors.formSwitchBg}; background: ${theme.colors.formSwitchBg};
transition: all 0.3s ease; transition: all 0.3s ease;
border-radius: 50px;
border: none;
display: block;
padding: 0;
&:hover { &:hover {
background: ${theme.colors.formSwitchBgHover}; background: ${theme.colors.formSwitchBgHover};
} }
&:after {
content: ''; &::after {
transition: transform 0.2s cubic-bezier(0.19, 1, 0.22, 1);
position: absolute; position: absolute;
z-index: 0;
top: 50%;
display: block; display: block;
content: '';
width: 12px; width: 12px;
height: 12px; height: 12px;
background: ${theme.colors.formSwitchDot};
border-radius: 6px; border-radius: 6px;
background: ${theme.colors.formSwitchDot};
top: 50%;
transform: translate3d(2px, -50%, 0); transform: translate3d(2px, -50%, 0);
transition: transform 0.2s cubic-bezier(0.19, 1, 0.22, 1);
} }
} }
input:checked ~ div { }
background: ${theme.colors.formSwitchBgActive};
&:hover {
background: ${theme.colors.formSwitchBgActiveHover};
}
&:after {
transform: translate3d(16px, -50%, 0);
}
}
`, `,
}; };
}); });
export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>( export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
({ value, checked, disabled = false, onChange, ...inputProps }, ref) => { ({ value, checked, disabled = false, onChange, ...inputProps }, ref) => {
const theme = useTheme(); const theme = useTheme();
const styles = getSwitchStyles(theme); const styles = getSwitchStyles(theme);
const switchId = uniqueId('switch-');
return ( return (
<div className={cx(styles.switch)}> <div className={cx(styles.switch)}>
@ -87,14 +88,13 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
disabled={disabled} disabled={disabled}
checked={value} checked={value}
onChange={event => { onChange={event => {
if (onChange) { onChange?.(event);
onChange(event);
}
}} }}
id={switchId}
{...inputProps} {...inputProps}
ref={ref} ref={ref}
/> />
<div></div> <label htmlFor={switchId} />
</div> </div>
); );
} }