|
|
|
@ -4,7 +4,7 @@ import React, { HTMLProps, useRef } from 'react'; |
|
|
|
|
|
|
|
|
|
import { GrafanaTheme2, deprecationWarning } from '@grafana/data'; |
|
|
|
|
|
|
|
|
|
import { stylesFactory, useTheme2 } from '../../themes'; |
|
|
|
|
import { useStyles2 } from '../../themes'; |
|
|
|
|
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; |
|
|
|
|
|
|
|
|
|
export interface Props extends Omit<HTMLProps<HTMLInputElement>, 'value'> { |
|
|
|
@ -21,8 +21,7 @@ export const Switch = React.forwardRef<HTMLInputElement, Props>( |
|
|
|
|
deprecationWarning('Switch', 'checked prop', 'value'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const theme = useTheme2(); |
|
|
|
|
const styles = getSwitchStyles(theme); |
|
|
|
|
const styles = useStyles2(getSwitchStyles); |
|
|
|
|
const switchIdRef = useRef(id ? id : uniqueId('switch-')); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
@ -52,8 +51,7 @@ export interface InlineSwitchProps extends Props { |
|
|
|
|
|
|
|
|
|
export const InlineSwitch = React.forwardRef<HTMLInputElement, InlineSwitchProps>( |
|
|
|
|
({ transparent, className, showLabel, label, value, id, invalid, ...props }, ref) => { |
|
|
|
|
const theme = useTheme2(); |
|
|
|
|
const styles = getSwitchStyles(theme, transparent); |
|
|
|
|
const styles = useStyles2(getSwitchStyles, transparent); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div |
|
|
|
@ -75,110 +73,108 @@ export const InlineSwitch = React.forwardRef<HTMLInputElement, InlineSwitchProps |
|
|
|
|
|
|
|
|
|
InlineSwitch.displayName = 'Switch'; |
|
|
|
|
|
|
|
|
|
const getSwitchStyles = stylesFactory((theme: GrafanaTheme2, transparent?: boolean) => { |
|
|
|
|
return { |
|
|
|
|
switch: css({ |
|
|
|
|
width: '32px', |
|
|
|
|
height: '16px', |
|
|
|
|
position: 'relative', |
|
|
|
|
|
|
|
|
|
input: { |
|
|
|
|
opacity: 0, |
|
|
|
|
left: '-100vw', |
|
|
|
|
zIndex: -1000, |
|
|
|
|
position: 'absolute', |
|
|
|
|
|
|
|
|
|
'&:disabled + label': { |
|
|
|
|
background: theme.colors.action.disabledBackground, |
|
|
|
|
cursor: 'not-allowed', |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
'&:checked + label': { |
|
|
|
|
background: theme.colors.primary.main, |
|
|
|
|
borderColor: theme.colors.primary.main, |
|
|
|
|
|
|
|
|
|
'&:hover': { |
|
|
|
|
background: theme.colors.primary.shade, |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
'&::after': { |
|
|
|
|
transform: 'translate3d(18px, -50%, 0)', |
|
|
|
|
background: theme.colors.primary.contrastText, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
'&:focus + label, &:focus-visible + label': getFocusStyles(theme), |
|
|
|
|
|
|
|
|
|
'&:focus:not(:focus-visible) + label': getMouseFocusStyles(theme), |
|
|
|
|
const getSwitchStyles = (theme: GrafanaTheme2, transparent?: boolean) => ({ |
|
|
|
|
switch: css({ |
|
|
|
|
width: '32px', |
|
|
|
|
height: '16px', |
|
|
|
|
position: 'relative', |
|
|
|
|
|
|
|
|
|
input: { |
|
|
|
|
opacity: 0, |
|
|
|
|
left: '-100vw', |
|
|
|
|
zIndex: -1000, |
|
|
|
|
position: 'absolute', |
|
|
|
|
|
|
|
|
|
'&:disabled + label': { |
|
|
|
|
background: theme.colors.action.disabledBackground, |
|
|
|
|
cursor: 'not-allowed', |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
label: { |
|
|
|
|
width: '100%', |
|
|
|
|
height: '100%', |
|
|
|
|
cursor: 'pointer', |
|
|
|
|
borderRadius: theme.shape.radius.pill, |
|
|
|
|
background: theme.components.input.background, |
|
|
|
|
border: `1px solid ${theme.components.input.borderColor}`, |
|
|
|
|
transition: 'all 0.3s ease', |
|
|
|
|
'&:checked + label': { |
|
|
|
|
background: theme.colors.primary.main, |
|
|
|
|
borderColor: theme.colors.primary.main, |
|
|
|
|
|
|
|
|
|
'&:hover': { |
|
|
|
|
borderColor: theme.components.input.borderHover, |
|
|
|
|
background: theme.colors.primary.shade, |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
'&::after': { |
|
|
|
|
position: 'absolute', |
|
|
|
|
display: 'block', |
|
|
|
|
content: '""', |
|
|
|
|
width: '12px', |
|
|
|
|
height: '12px', |
|
|
|
|
borderRadius: theme.shape.radius.circle, |
|
|
|
|
background: theme.colors.text.secondary, |
|
|
|
|
boxShadow: theme.shadows.z1, |
|
|
|
|
top: '50%', |
|
|
|
|
transform: 'translate3d(2px, -50%, 0)', |
|
|
|
|
transition: 'transform 0.2s cubic-bezier(0.19, 1, 0.22, 1)', |
|
|
|
|
|
|
|
|
|
'@media (forced-colors: active)': { |
|
|
|
|
border: '1px solid transparent', |
|
|
|
|
}, |
|
|
|
|
transform: 'translate3d(18px, -50%, 0)', |
|
|
|
|
background: theme.colors.primary.contrastText, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
inlineContainer: css({ |
|
|
|
|
padding: theme.spacing(0, 1), |
|
|
|
|
height: theme.spacing(theme.components.height.md), |
|
|
|
|
display: 'inline-flex', |
|
|
|
|
alignItems: 'center', |
|
|
|
|
background: transparent ? 'transparent' : theme.components.input.background, |
|
|
|
|
border: `1px solid ${transparent ? 'transparent' : theme.components.input.borderColor}`, |
|
|
|
|
borderRadius: theme.shape.radius.default, |
|
|
|
|
|
|
|
|
|
'&:focus + label, &:focus-visible + label': getFocusStyles(theme), |
|
|
|
|
|
|
|
|
|
'&:focus:not(:focus-visible) + label': getMouseFocusStyles(theme), |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
label: { |
|
|
|
|
width: '100%', |
|
|
|
|
height: '100%', |
|
|
|
|
cursor: 'pointer', |
|
|
|
|
borderRadius: theme.shape.radius.pill, |
|
|
|
|
background: theme.components.input.background, |
|
|
|
|
border: `1px solid ${theme.components.input.borderColor}`, |
|
|
|
|
transition: 'all 0.3s ease', |
|
|
|
|
|
|
|
|
|
'&:hover': { |
|
|
|
|
border: `1px solid ${transparent ? 'transparent' : theme.components.input.borderHover}`, |
|
|
|
|
borderColor: theme.components.input.borderHover, |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
'.inline-switch-label': { |
|
|
|
|
color: theme.colors.text.primary, |
|
|
|
|
'&::after': { |
|
|
|
|
position: 'absolute', |
|
|
|
|
display: 'block', |
|
|
|
|
content: '""', |
|
|
|
|
width: '12px', |
|
|
|
|
height: '12px', |
|
|
|
|
borderRadius: theme.shape.radius.circle, |
|
|
|
|
background: theme.colors.text.secondary, |
|
|
|
|
boxShadow: theme.shadows.z1, |
|
|
|
|
top: '50%', |
|
|
|
|
transform: 'translate3d(2px, -50%, 0)', |
|
|
|
|
transition: 'transform 0.2s cubic-bezier(0.19, 1, 0.22, 1)', |
|
|
|
|
|
|
|
|
|
'@media (forced-colors: active)': { |
|
|
|
|
border: '1px solid transparent', |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
disabled: css({ |
|
|
|
|
backgroundColor: 'rgba(204, 204, 220, 0.04)', |
|
|
|
|
color: 'rgba(204, 204, 220, 0.6)', |
|
|
|
|
border: '1px solid rgba(204, 204, 220, 0.04)', |
|
|
|
|
}), |
|
|
|
|
inlineLabel: css({ |
|
|
|
|
cursor: 'pointer', |
|
|
|
|
paddingRight: theme.spacing(1), |
|
|
|
|
color: theme.colors.text.secondary, |
|
|
|
|
whiteSpace: 'nowrap', |
|
|
|
|
}), |
|
|
|
|
inlineLabelEnabled: css({ |
|
|
|
|
color: theme.colors.text.primary, |
|
|
|
|
}), |
|
|
|
|
invalid: css({ |
|
|
|
|
'input + label, input:checked + label, input:hover + label': { |
|
|
|
|
border: `1px solid ${theme.colors.error.border}`, |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
inlineContainer: css({ |
|
|
|
|
padding: theme.spacing(0, 1), |
|
|
|
|
height: theme.spacing(theme.components.height.md), |
|
|
|
|
display: 'inline-flex', |
|
|
|
|
alignItems: 'center', |
|
|
|
|
background: transparent ? 'transparent' : theme.components.input.background, |
|
|
|
|
border: `1px solid ${transparent ? 'transparent' : theme.components.input.borderColor}`, |
|
|
|
|
borderRadius: theme.shape.radius.default, |
|
|
|
|
|
|
|
|
|
'&:hover': { |
|
|
|
|
border: `1px solid ${transparent ? 'transparent' : theme.components.input.borderHover}`, |
|
|
|
|
|
|
|
|
|
'.inline-switch-label': { |
|
|
|
|
color: theme.colors.text.primary, |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
}; |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
disabled: css({ |
|
|
|
|
backgroundColor: 'rgba(204, 204, 220, 0.04)', |
|
|
|
|
color: 'rgba(204, 204, 220, 0.6)', |
|
|
|
|
border: '1px solid rgba(204, 204, 220, 0.04)', |
|
|
|
|
}), |
|
|
|
|
inlineLabel: css({ |
|
|
|
|
cursor: 'pointer', |
|
|
|
|
paddingRight: theme.spacing(1), |
|
|
|
|
color: theme.colors.text.secondary, |
|
|
|
|
whiteSpace: 'nowrap', |
|
|
|
|
}), |
|
|
|
|
inlineLabelEnabled: css({ |
|
|
|
|
color: theme.colors.text.primary, |
|
|
|
|
}), |
|
|
|
|
invalid: css({ |
|
|
|
|
'input + label, input:checked + label, input:hover + label': { |
|
|
|
|
border: `1px solid ${theme.colors.error.border}`, |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
}); |
|
|
|
|