diff --git a/packages/grafana-ui/src/components/Input/Input.story.tsx b/packages/grafana-ui/src/components/Input/Input.story.tsx
new file mode 100644
index 00000000000..bed23c10bc7
--- /dev/null
+++ b/packages/grafana-ui/src/components/Input/Input.story.tsx
@@ -0,0 +1,40 @@
+import React, { useState } from 'react';
+import { zip, fromPairs } from 'lodash';
+
+import { storiesOf } from '@storybook/react';
+import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
+import { Input } from './Input';
+import { text, select } from '@storybook/addon-knobs';
+import { EventsWithValidation } from '../../utils';
+
+const getKnobs = () => {
+ return {
+ validation: text('Validation regex (will do a partial match if you do not anchor it)', ''),
+ validationErrorMessage: text('Validation error message', 'Input not valid'),
+ validationEvent: select(
+ 'Validation event',
+ fromPairs(zip(Object.keys(EventsWithValidation), Object.values(EventsWithValidation))),
+ EventsWithValidation.onBlur
+ ),
+ };
+};
+
+const Wrapper = () => {
+ const { validation, validationErrorMessage, validationEvent } = getKnobs();
+ const [value, setValue] = useState('');
+ const validations = {
+ [validationEvent]: [
+ {
+ rule: (value: string) => {
+ return !!value.match(validation);
+ },
+ errorMessage: validationErrorMessage,
+ },
+ ],
+ };
+ return setValue(e.currentTarget.value)} validationEvents={validations} />;
+};
+
+const story = storiesOf('UI/Input', module);
+story.addDecorator(withCenteredStory);
+story.add('input', () => );
diff --git a/packages/grafana-ui/src/components/Input/Input.tsx b/packages/grafana-ui/src/components/Input/Input.tsx
index b75a8c17760..b8165c48dca 100644
--- a/packages/grafana-ui/src/components/Input/Input.tsx
+++ b/packages/grafana-ui/src/components/Input/Input.tsx
@@ -18,7 +18,11 @@ interface Props extends React.HTMLProps {
onChange?: (event: React.ChangeEvent, status?: InputStatus) => void;
}
-export class Input extends PureComponent {
+interface State {
+ error: string | null;
+}
+
+export class Input extends PureComponent {
static defaultProps = {
className: '',
};
diff --git a/packages/grafana-ui/src/components/Switch/Switch.story.tsx b/packages/grafana-ui/src/components/Switch/Switch.story.tsx
new file mode 100644
index 00000000000..c3cb6fef76d
--- /dev/null
+++ b/packages/grafana-ui/src/components/Switch/Switch.story.tsx
@@ -0,0 +1,22 @@
+import React, { useState } from 'react';
+
+import { storiesOf } from '@storybook/react';
+import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
+import { Switch } from './Switch';
+import { text } from '@storybook/addon-knobs';
+
+const getKnobs = () => {
+ return {
+ label: text('Label Text', 'Label'),
+ };
+};
+
+const SwitchWrapper = () => {
+ const { label } = getKnobs();
+ const [checked, setChecked] = useState(false);
+ return setChecked(!checked)} />;
+};
+
+const story = storiesOf('UI/Switch', module);
+story.addDecorator(withCenteredStory);
+story.add('switch', () => );
diff --git a/packages/grafana-ui/src/components/Switch/Switch.tsx b/packages/grafana-ui/src/components/Switch/Switch.tsx
index e2a25682519..470ca3f118d 100644
--- a/packages/grafana-ui/src/components/Switch/Switch.tsx
+++ b/packages/grafana-ui/src/components/Switch/Switch.tsx
@@ -12,7 +12,7 @@ export interface Props {
}
export interface State {
- id: any;
+ id: string;
}
export class Switch extends PureComponent {
diff --git a/packages/grafana-ui/src/types/input.ts b/packages/grafana-ui/src/types/input.ts
index 95026c30be9..d3522e77b35 100644
--- a/packages/grafana-ui/src/types/input.ts
+++ b/packages/grafana-ui/src/types/input.ts
@@ -4,5 +4,6 @@
}
export interface ValidationEvents {
+ // Event name should be one of EventsWithValidation enum
[eventName: string]: ValidationRule[];
}