mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
003fb4a3d0
commit
ef36276584
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user