diff --git a/packages/grafana-data/src/types/theme.ts b/packages/grafana-data/src/types/theme.ts
index 8efa746a7f6..fced5a9b0c5 100644
--- a/packages/grafana-data/src/types/theme.ts
+++ b/packages/grafana-data/src/types/theme.ts
@@ -223,13 +223,19 @@ export interface GrafanaTheme extends GrafanaThemeCommons {
formInputBorderHover: string;
formInputBorderActive: string;
formInputBorderInvalid: string;
- formInputFocusOutline: string;
+ formFocusOutline: string;
formInputText: string;
formInputDisabledText: string;
formInputTextStrong: string;
formInputTextWhite: string;
formValidationMessageText: string;
formValidationMessageBg: string;
+ formSwitchBg: string;
+ formSwitchBgActive: string;
+ formSwitchBgActiveHover: string;
+ formSwitchBgHover: string;
+ formSwitchBgDisabled: string;
+ formSwitchDot: string;
};
shadow: {
pageHeader: string;
diff --git a/packages/grafana-ui/src/components/Forms/Switch.mdx b/packages/grafana-ui/src/components/Forms/Switch.mdx
new file mode 100644
index 00000000000..5a8cf5e3d46
--- /dev/null
+++ b/packages/grafana-ui/src/components/Forms/Switch.mdx
@@ -0,0 +1,20 @@
+import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks';
+import { Switch } from './Switch';
+
+
+
+# Switch
+
+Used to represent binary values
+
+### Usage
+
+```jsx
+import { Forms } from '@grafana/ui';
+
+
+```
+
+### Props
+
+
diff --git a/packages/grafana-ui/src/components/Forms/Switch.story.tsx b/packages/grafana-ui/src/components/Forms/Switch.story.tsx
new file mode 100644
index 00000000000..c9cab1879b4
--- /dev/null
+++ b/packages/grafana-ui/src/components/Forms/Switch.story.tsx
@@ -0,0 +1,31 @@
+import React, { useState } from 'react';
+import { boolean } from '@storybook/addon-knobs';
+import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory';
+import { Switch } from './Switch';
+import mdx from './Switch.mdx';
+
+export default {
+ title: 'UI/Forms/Switch',
+ component: Switch,
+ decorators: [withCenteredStory, withHorizontallyCenteredStory],
+ parameters: {
+ docs: {
+ page: mdx,
+ },
+ },
+};
+
+export const simple = () => {
+ const [checked, setChecked] = useState(false);
+ const BEHAVIOUR_GROUP = 'Behaviour props';
+ const disabled = boolean('Disabled', false, BEHAVIOUR_GROUP);
+ return (
+ {
+ setChecked(checked);
+ }}
+ />
+ );
+};
diff --git a/packages/grafana-ui/src/components/Forms/Switch.tsx b/packages/grafana-ui/src/components/Forms/Switch.tsx
new file mode 100644
index 00000000000..e809fffce05
--- /dev/null
+++ b/packages/grafana-ui/src/components/Forms/Switch.tsx
@@ -0,0 +1,79 @@
+import React from 'react';
+import { stylesFactory, useTheme } from '../../themes';
+import { GrafanaTheme } from '@grafana/data';
+import { css, cx } from 'emotion';
+import { getFocusStyle } from './commonStyles';
+
+export interface SwitchProps {
+ checked?: boolean;
+ disabled?: boolean;
+ onChange?: (e: React.SyntheticEvent, checked: boolean) => void;
+}
+
+export const getSwitchStyles = stylesFactory((theme: GrafanaTheme) => {
+ return {
+ slider: cx(
+ css`
+ width: 32px;
+ height: 16px;
+ background: ${theme.colors.formSwitchBg};
+ transition: all 0.30s ease;
+ border-radius: 50px;
+ position: relative;
+ border: none;
+ display: block;
+ padding: 0;
+ &:hover {
+ background: ${theme.colors.formSwitchBgHover};
+ }
+ &:after {
+ content: '';
+ transition: transform 0.2s cubic-bezier(0.19, 1, 0.22, 1);
+ position: absolute;
+ top: 50%;
+ display: block;
+ width: 12px;
+ height: 12px;
+ background: ${theme.colors.formSwitchDot};
+ border-radius: 6px;
+ transform: translate3d(2px, -50%, 0);
+ }
+ &:focus {
+ /* border: 1px solid ${theme.colors.formSwitchDot}; */
+ }
+ &[disabled] {
+ background: ${theme.colors.formSwitchBgDisabled};
+ }
+ `,
+ getFocusStyle(theme)
+ ),
+ sliderActive: css`
+ background: ${theme.colors.formSwitchBgActive};
+ &:hover {
+ background: ${theme.colors.formSwitchBgActiveHover};
+ }
+ &:after {
+ transform: translate3d(16px, -50%, 0);
+ }
+ `,
+ };
+});
+export const Switch: React.FC = ({ checked = false, disabled = false, onChange }) => {
+ const theme = useTheme();
+ const styles = getSwitchStyles(theme);
+
+ return (
+