Commit 314865dd by Torkel Ödegaard Committed by GitHub

InlineSwitch: Added missing InlineSwitch component and fixed two places that…

InlineSwitch: Added missing InlineSwitch component and fixed two places that used unaligned inline switch (#30162)

* InlineSwitch: Added missing InlineSwitch component and fixed two places that used unaligned inline switch

* Fixed e2e tests
parent 549587a3
......@@ -66,27 +66,11 @@ describe('Variables - Add variable', () => {
.within(select => {
e2e.components.Select.singleValue().should('have.text', 'Disabled');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsMultiSwitch()
.should('be.visible')
.within(select => {
e2e()
.get('input')
.should('not.be.checked');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsIncludeAllSwitch()
.should('be.visible')
.within(select => {
e2e()
.get('input')
.should('not.be.checked');
});
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.valueGroupsTagsEnabledSwitch()
.should('be.visible')
.within(select => {
e2e()
.get('input')
.should('not.be.checked');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsMultiSwitch().should('not.be.checked');
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsIncludeAllSwitch().should('not.be.checked');
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.valueGroupsTagsEnabledSwitch().should('not.be.checked');
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().should('not.exist');
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsCustomAllInput().should('not.exist');
});
......@@ -190,7 +174,7 @@ describe('Variables - Add variable', () => {
.blur();
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsMultiSwitch()
.click()
.click({ force: true })
.within(() => {
e2e()
.get('input')
......@@ -198,7 +182,7 @@ describe('Variables - Add variable', () => {
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsIncludeAllSwitch()
.click()
.click({ force: true })
.within(() => {
e2e()
.get('input')
......
......@@ -6,7 +6,6 @@ import { getFieldValidationMessageStyles } from './FieldValidationMessage';
import { getButtonStyles, ButtonVariant } from '../Button';
import { ComponentSize } from '../../types/size';
import { getInputStyles } from '../Input/Input';
import { getSwitchStyles } from '../Switch/Switch';
import { getCheckboxStyles } from './Checkbox';
export const getFormStyles = stylesFactory(
......@@ -23,7 +22,6 @@ export const getFormStyles = stylesFactory(
hasText: true,
}),
input: getInputStyles({ theme, invalid: options.invalid }),
switch: getSwitchStyles(theme),
checkbox: getCheckboxStyles(theme),
};
}
......
......@@ -22,3 +22,9 @@ import { Switch } from '@grafana/ui';
### Props
<Props of={Switch} />
# InlineSwitch
### When to use
Same as for Switch but for inline forms.
import React, { useState, useCallback } from 'react';
import { boolean } from '@storybook/addon-knobs';
import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory';
import { Switch } from '@grafana/ui';
import { InlineField, Switch, InlineSwitch } from '@grafana/ui';
import mdx from './Switch.mdx';
import { InlineFieldRow } from '../Forms/InlineFieldRow';
import { Field } from '../Forms/Field';
export default {
title: 'Forms/Switch',
......@@ -20,7 +22,23 @@ export const Controlled = () => {
const onChange = useCallback(e => setChecked(e.currentTarget.checked), [setChecked]);
const BEHAVIOUR_GROUP = 'Behaviour props';
const disabled = boolean('Disabled', false, BEHAVIOUR_GROUP);
return <Switch value={checked} disabled={disabled} onChange={onChange} />;
return (
<div>
<p>
<Field label="Normal switch" description="For horizontal forms">
<Switch value={checked} disabled={disabled} onChange={onChange} />
</Field>
</p>
<p>
<InlineFieldRow>
<InlineField label="My switch">
<InlineSwitch value={checked} disabled={disabled} onChange={onChange} />
</InlineField>
</InlineFieldRow>
</p>
</div>
);
};
export const Uncontrolled = () => {
......
......@@ -5,11 +5,55 @@ import { GrafanaTheme, deprecationWarning } from '@grafana/data';
import { stylesFactory, useTheme } from '../../themes';
import { focusCss } from '../../themes/mixins';
export interface SwitchProps extends Omit<HTMLProps<HTMLInputElement>, 'value'> {
export interface Props extends Omit<HTMLProps<HTMLInputElement>, 'value'> {
value?: boolean;
}
export const getSwitchStyles = stylesFactory((theme: GrafanaTheme) => {
export const Switch = React.forwardRef<HTMLInputElement, Props>(
({ value, checked, disabled = false, onChange, id, ...inputProps }, ref) => {
if (checked) {
deprecationWarning('Switch', 'checked prop', 'value');
}
const theme = useTheme();
const styles = getSwitchStyles(theme);
const switchIdRef = useRef(id ? id : uniqueId('switch-'));
return (
<div className={cx(styles.switch)}>
<input
type="checkbox"
disabled={disabled}
checked={value}
onChange={event => {
onChange?.(event);
}}
id={switchIdRef.current}
{...inputProps}
ref={ref}
/>
<label htmlFor={switchIdRef.current} />
</div>
);
}
);
Switch.displayName = 'Switch';
export const InlineSwitch = React.forwardRef<HTMLInputElement, Props>((props, ref) => {
const theme = useTheme();
const styles = getSwitchStyles(theme);
return (
<div className={styles.inlineContainer}>
<Switch {...props} ref={ref} />
</div>
);
});
InlineSwitch.displayName = 'Switch';
const getSwitchStyles = stylesFactory((theme: GrafanaTheme) => {
return {
switch: css`
width: 32px;
......@@ -71,36 +115,14 @@ export const getSwitchStyles = stylesFactory((theme: GrafanaTheme) => {
}
}
`,
inlineContainer: css`
padding: 0 ${theme.spacing.sm};
height: ${theme.spacing.formInputHeight}px;
display: flex;
align-items: center;
background: ${theme.colors.formInputBg};
border: 1px solid ${theme.colors.formInputBorder};
border-radius: ${theme.border.radius.md};
`,
};
});
export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
({ value, checked, disabled = false, onChange, id, ...inputProps }, ref) => {
if (checked) {
deprecationWarning('Switch', 'checked prop', 'value');
}
const theme = useTheme();
const styles = getSwitchStyles(theme);
const switchIdRef = useRef(id ? id : uniqueId('switch-'));
return (
<div className={cx(styles.switch)}>
<input
type="checkbox"
disabled={disabled}
checked={value}
onChange={event => {
onChange?.(event);
}}
id={switchIdRef.current}
{...inputProps}
ref={ref}
/>
<label htmlFor={switchIdRef.current} />
</div>
);
}
);
Switch.displayName = 'Switch';
......@@ -168,7 +168,7 @@ export { RadioButtonGroup } from './Forms/RadioButtonGroup/RadioButtonGroup';
export { Input } from './Input/Input';
export { FormInputSize } from './Forms/types';
export { Switch } from './Switch/Switch';
export { Switch, InlineSwitch } from './Switch/Switch';
export { Checkbox } from './Forms/Checkbox';
export { TextArea } from './TextArea/TextArea';
......
import React, { ChangeEvent, PropsWithChildren, ReactElement } from 'react';
import { InlineField, Switch, useStyles } from '@grafana/ui';
import { GrafanaTheme } from '@grafana/data';
import { css } from 'emotion';
import { InlineField, InlineSwitch } from '@grafana/ui';
interface VariableSwitchFieldProps {
value: boolean;
name: string;
......@@ -18,22 +15,9 @@ export function VariableSwitchField({
onChange,
ariaLabel,
}: PropsWithChildren<VariableSwitchFieldProps>): ReactElement {
const styles = useStyles(getStyles);
return (
<InlineField label={name} labelWidth={20} tooltip={tooltip}>
<div aria-label={ariaLabel} className={styles.switchContainer}>
<Switch label={name} value={value} onChange={onChange} />
</div>
<InlineSwitch label={name} value={value} onChange={onChange} aria-label={ariaLabel} />
</InlineField>
);
}
function getStyles(theme: GrafanaTheme) {
return {
switchContainer: css`
margin-left: ${theme.spacing.sm};
margin-right: ${theme.spacing.sm};
`,
};
}
import { InlineField, Input, Switch } from '@grafana/ui';
import { InlineField, Input, InlineSwitch } from '@grafana/ui';
import React, { FunctionComponent, ComponentProps, useState } from 'react';
import { extendedStats } from '../../../../query_def';
import { useDispatch } from '../../../../hooks/useStatelessReducer';
......@@ -132,7 +132,11 @@ const ExtendedStatSetting: FunctionComponent<ExtendedStatSettingProps> = ({ stat
return (
<InlineField label={stat.label} {...inlineFieldProps} key={stat.value}>
<Switch id={id} onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange(e.target.checked)} value={value} />
<InlineSwitch
id={id}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange(e.target.checked)}
value={value}
/>
</InlineField>
);
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment