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

View File

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