Grafana UI: Add invalid state to Switch component (#68215)

This commit is contained in:
Laura Fernández 2023-05-12 16:30:23 +02:00 committed by GitHub
parent 8de16908a2
commit 3869d2f239
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 8 deletions

View File

@ -22,6 +22,7 @@ const meta: Meta<typeof Switch> = {
disabled: false,
value: false,
transparent: false,
invalid: false,
},
};
@ -29,13 +30,13 @@ export const Controlled: StoryFn<typeof Switch> = (args) => {
return (
<div>
<div style={{ marginBottom: '32px' }}>
<Field label="Normal switch" description="For horizontal forms">
<Field label="Normal switch" description="For horizontal forms" invalid={args.invalid}>
<Switch value={args.value} disabled={args.disabled} transparent={args.transparent} />
</Field>
</div>
<div style={{ marginBottom: '32px' }}>
<InlineFieldRow>
<InlineField label="My switch">
<InlineField label="My switch" invalid={args.invalid}>
<InlineSwitch value={args.value} disabled={args.disabled} transparent={args.transparent} />
</InlineField>
</InlineFieldRow>
@ -49,6 +50,7 @@ export const Controlled: StoryFn<typeof Switch> = (args) => {
value={args.value}
disabled={args.disabled}
transparent={args.transparent}
invalid={args.invalid}
/>
</span>
</div>
@ -62,7 +64,15 @@ export const Uncontrolled: StoryFn<typeof Switch> = (args) => {
(e: React.FormEvent<HTMLInputElement>) => setChecked(e.currentTarget.checked),
[setChecked]
);
return <Switch value={checked} disabled={args.disabled} transparent={args.transparent} onChange={onChange} />;
return (
<Switch
value={checked}
disabled={args.disabled}
transparent={args.transparent}
onChange={onChange}
invalid={args.invalid}
/>
);
};
export default meta;

View File

@ -9,12 +9,14 @@ import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
export interface Props extends Omit<HTMLProps<HTMLInputElement>, 'value'> {
value?: boolean;
/** Make switch's background and border transparent */
/** Make inline switch's background and border transparent */
transparent?: boolean;
/** Show an invalid state around the input */
invalid?: boolean;
}
export const Switch = React.forwardRef<HTMLInputElement, Props>(
({ value, checked, onChange, id, label, disabled, ...inputProps }, ref) => {
({ value, checked, onChange, id, label, disabled, invalid = false, ...inputProps }, ref) => {
if (checked) {
deprecationWarning('Switch', 'checked prop', 'value');
}
@ -24,7 +26,7 @@ export const Switch = React.forwardRef<HTMLInputElement, Props>(
const switchIdRef = useRef(id ? id : uniqueId('switch-'));
return (
<div className={cx(styles.switch)}>
<div className={cx(styles.switch, invalid && styles.invalid)}>
<input
type="checkbox"
disabled={disabled}
@ -49,12 +51,14 @@ export interface InlineSwitchProps extends Props {
}
export const InlineSwitch = React.forwardRef<HTMLInputElement, InlineSwitchProps>(
({ transparent, className, showLabel, label, value, id, ...props }, ref) => {
({ transparent, className, showLabel, label, value, id, invalid, ...props }, ref) => {
const theme = useTheme2();
const styles = getSwitchStyles(theme, transparent);
return (
<div className={cx(styles.inlineContainer, className, props.disabled && styles.disabled)}>
<div
className={cx(styles.inlineContainer, className, props.disabled && styles.disabled, invalid && styles.invalid)}
>
{showLabel && (
<label
htmlFor={id}
@ -173,5 +177,12 @@ const getSwitchStyles = stylesFactory((theme: GrafanaTheme2, transparent?: boole
inlineLabelEnabled: css`
color: ${theme.colors.text.primary};
`,
invalid: css`
input + label,
input:checked + label,
input:hover + label {
border: 1px solid ${theme.colors.error.border};
}
`,
};
});