mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Form migrations: Forms/switch move folders (#23430)
* Move legacy Switch * Move from Forms folder * Fix prettify issue * Fix prettify issue
This commit is contained in:
parent
ab98a8be3b
commit
da6056d5e1
@ -2,7 +2,7 @@ import React, { FunctionComponent } from 'react';
|
||||
|
||||
import { ColorPickerPopover, ColorPickerProps } from './ColorPickerPopover';
|
||||
import { PopoverContentProps } from '../Tooltip/Tooltip';
|
||||
import { Switch } from '../Switch/Switch';
|
||||
import { Switch } from '../Forms/Legacy/Switch/Switch';
|
||||
import { withTheme } from '../../themes/ThemeContext';
|
||||
|
||||
export interface SeriesColorPickerPopoverProps extends ColorPickerProps, PopoverContentProps {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ChangeEvent, useContext } from 'react';
|
||||
import { DataLink, VariableSuggestion, GrafanaTheme } from '@grafana/data';
|
||||
import { FormField } from '../index';
|
||||
import { Switch } from '../Switch/Switch';
|
||||
import { Switch } from '../Forms/Legacy/Switch/Switch';
|
||||
import { css } from 'emotion';
|
||||
import { ThemeContext, stylesFactory } from '../../themes/index';
|
||||
import { DataLinkInput } from './DataLinkInput';
|
||||
|
@ -13,7 +13,7 @@ import { Input } from '../Forms/Legacy/Input/Input';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { FormField } from '../FormField/FormField';
|
||||
import { FormLabel } from '../FormLabel/FormLabel';
|
||||
import { Switch } from '../Switch/Switch';
|
||||
import { Switch } from '../Forms/Legacy/Switch/Switch';
|
||||
import { TagsInput } from '../TagsInput/TagsInput';
|
||||
|
||||
const ACCESS_OPTIONS: Array<SelectableValue<string>> = [
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { HttpSettingsBaseProps } from './types';
|
||||
import { Switch } from '../Switch/Switch';
|
||||
import { Switch } from '../Forms/Legacy/Switch/Switch';
|
||||
|
||||
export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({ dataSourceConfig, onChange }) => {
|
||||
return (
|
||||
|
@ -2,7 +2,7 @@ import React, { useState, useCallback } from 'react';
|
||||
import { boolean, number, text } from '@storybook/addon-knobs';
|
||||
import { Field } from './Field';
|
||||
import { Input } from '../Input/Input';
|
||||
import { Switch } from './Switch';
|
||||
import { Switch } from '../Switch/Switch';
|
||||
import mdx from './Field.mdx';
|
||||
|
||||
export default {
|
||||
|
@ -7,7 +7,7 @@ import { Field } from './Field';
|
||||
import { Input } from '../Input/Input';
|
||||
import { Button } from '../Button';
|
||||
import { Form } from './Form';
|
||||
import { Switch } from './Switch';
|
||||
import { Switch } from '../Switch/Switch';
|
||||
import { Checkbox } from './Checkbox';
|
||||
|
||||
import { RadioButtonGroup } from './RadioButtonGroup/RadioButtonGroup';
|
||||
|
@ -0,0 +1,3 @@
|
||||
# Switch
|
||||
|
||||
A basic docs for Switch component
|
@ -0,0 +1,71 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import { Tooltip } from '../../../Tooltip/Tooltip';
|
||||
import * as PopperJS from 'popper.js';
|
||||
|
||||
export interface Props {
|
||||
label: string;
|
||||
checked: boolean;
|
||||
className?: string;
|
||||
labelClass?: string;
|
||||
switchClass?: string;
|
||||
tooltip?: string;
|
||||
tooltipPlacement?: PopperJS.Placement;
|
||||
transparent?: boolean;
|
||||
onChange: (event?: React.SyntheticEvent<HTMLInputElement>) => void;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export class Switch extends PureComponent<Props, State> {
|
||||
state = {
|
||||
id: uniqueId(),
|
||||
};
|
||||
|
||||
internalOnChange = (event: React.FormEvent<HTMLInputElement>) => {
|
||||
event.stopPropagation();
|
||||
this.props.onChange(event);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
labelClass = '',
|
||||
switchClass = '',
|
||||
label,
|
||||
checked,
|
||||
transparent,
|
||||
className,
|
||||
tooltip,
|
||||
tooltipPlacement,
|
||||
} = this.props;
|
||||
|
||||
const labelId = this.state.id;
|
||||
const labelClassName = `gf-form-label ${labelClass} ${transparent ? 'gf-form-label--transparent' : ''} pointer`;
|
||||
const switchClassName = `gf-form-switch ${switchClass} ${transparent ? 'gf-form-switch--transparent' : ''}`;
|
||||
|
||||
return (
|
||||
<div className="gf-form-switch-container-react">
|
||||
<label htmlFor={labelId} className={`gf-form gf-form-switch-container ${className || ''}`}>
|
||||
{label && (
|
||||
<div className={labelClassName}>
|
||||
{label}
|
||||
{tooltip && (
|
||||
<Tooltip placement={tooltipPlacement ? tooltipPlacement : 'auto'} content={tooltip} theme={'info'}>
|
||||
<div className="gf-form-help-icon gf-form-help-icon--right-normal">
|
||||
<i className="fa fa-info-circle" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className={switchClassName}>
|
||||
<input id={labelId} type="checkbox" checked={checked} onChange={this.internalOnChange} />
|
||||
<span className="gf-form-switch__slider" />
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import { Meta, Story, Preview, Props } from "@storybook/addon-docs/blocks";
|
||||
import { Switch } from "./Switch";
|
||||
|
||||
<Meta title="MDX|Switch" component={Switch} />
|
||||
|
||||
# Switch
|
||||
|
||||
### When to use
|
||||
|
||||
`Switch` is a representation of an on-off state – like a light switch. So you can use `Switch` to toggle binary states.
|
||||
|
||||
Switches trigger changes immediately. If your component should trigger a change only after sending a form, it's better to use either `RadioButtonGroup` or `Checkbox` instead. Furthermore, switches cannot be grouped – each `Switch` triggers an independent state. If you want multiple mutually exclusive choices, the `RadioButtonGroup` is the better option. To offer multiple choices within the same group or context which are not mutually exclusive, use `Checkbox` instead.
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
```jsx
|
||||
import { Switch } from '@grafana/ui';
|
||||
|
||||
<Switch disabled={...} checked={...} onChange={...} />
|
||||
```
|
||||
|
||||
### Props
|
||||
|
||||
<Props of={Switch} />
|
@ -1,101 +0,0 @@
|
||||
import React, { HTMLProps } from 'react';
|
||||
import { css, cx } from 'emotion';
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { stylesFactory, useTheme } from '../../themes';
|
||||
import { getFocusCss } from './commonStyles';
|
||||
|
||||
export interface SwitchProps extends Omit<HTMLProps<HTMLInputElement>, 'value'> {
|
||||
value?: boolean;
|
||||
}
|
||||
|
||||
export const getSwitchStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
return {
|
||||
switch: css`
|
||||
width: 32px;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
opacity: 0;
|
||||
left: -100vw;
|
||||
z-index: -1000;
|
||||
position: absolute;
|
||||
|
||||
&:disabled + label {
|
||||
background: ${theme.colors.formSwitchBgDisabled};
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&:checked + label {
|
||||
background: ${theme.colors.formSwitchBgActive};
|
||||
|
||||
&:hover {
|
||||
background: ${theme.colors.formSwitchBgActiveHover};
|
||||
}
|
||||
|
||||
&::after {
|
||||
transform: translate3d(18px, -50%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus + label {
|
||||
${getFocusCss(theme)};
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
border-radius: 50px;
|
||||
background: ${theme.colors.formSwitchBg};
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: ${theme.colors.formSwitchBgHover};
|
||||
}
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: '';
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 6px;
|
||||
background: ${theme.colors.formSwitchDot};
|
||||
top: 50%;
|
||||
transform: translate3d(2px, -50%, 0);
|
||||
transition: transform 0.2s cubic-bezier(0.19, 1, 0.22, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
|
||||
({ value, checked, disabled = false, onChange, ...inputProps }, ref) => {
|
||||
const theme = useTheme();
|
||||
const styles = getSwitchStyles(theme);
|
||||
const switchId = uniqueId('switch-');
|
||||
|
||||
return (
|
||||
<div className={cx(styles.switch)}>
|
||||
<input
|
||||
type="checkbox"
|
||||
disabled={disabled}
|
||||
checked={value}
|
||||
onChange={event => {
|
||||
onChange?.(event);
|
||||
}}
|
||||
id={switchId}
|
||||
{...inputProps}
|
||||
ref={ref}
|
||||
/>
|
||||
<label htmlFor={switchId} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
@ -6,7 +6,7 @@ import { getFieldValidationMessageStyles } from './FieldValidationMessage';
|
||||
import { getButtonStyles, ButtonVariant } from '../Button';
|
||||
import { ComponentSize } from '../../types/size';
|
||||
import { getInputStyles } from '../Input/Input';
|
||||
import { getSwitchStyles } from './Switch';
|
||||
import { getSwitchStyles } from '../Switch/Switch';
|
||||
import { getCheckboxStyles } from './Checkbox';
|
||||
|
||||
export const getFormStyles = stylesFactory(
|
||||
|
@ -1,3 +1,25 @@
|
||||
import { Meta, Story, Preview, Props } from "@storybook/addon-docs/blocks";
|
||||
import { Switch } from "./Switch";
|
||||
|
||||
<Meta title="MDX|Switch" component={Switch} />
|
||||
|
||||
# Switch
|
||||
|
||||
A basic docs for Switch component
|
||||
### When to use
|
||||
|
||||
`Switch` is a representation of an on-off state – like a light switch. So you can use `Switch` to toggle binary states.
|
||||
|
||||
Switches trigger changes immediately. If your component should trigger a change only after sending a form, it's better to use either `RadioButtonGroup` or `Checkbox` instead. Furthermore, switches cannot be grouped – each `Switch` triggers an independent state. If you want multiple mutually exclusive choices, the `RadioButtonGroup` is the better option. To offer multiple choices within the same group or context which are not mutually exclusive, use `Checkbox` instead.
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
```jsx
|
||||
import { Switch } from '@grafana/ui';
|
||||
|
||||
<Switch disabled={...} checked={...} onChange={...} />
|
||||
```
|
||||
|
||||
### Props
|
||||
|
||||
<Props of={Switch} />
|
||||
|
@ -1,72 +1,101 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import React, { HTMLProps } from 'react';
|
||||
import { css, cx } from 'emotion';
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import { Tooltip } from '../Tooltip/Tooltip';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import * as PopperJS from 'popper.js';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { stylesFactory, useTheme } from '../../themes';
|
||||
import { getFocusCss } from '../Forms/commonStyles';
|
||||
|
||||
export interface Props {
|
||||
label: string;
|
||||
checked: boolean;
|
||||
className?: string;
|
||||
labelClass?: string;
|
||||
switchClass?: string;
|
||||
tooltip?: string;
|
||||
tooltipPlacement?: PopperJS.Placement;
|
||||
transparent?: boolean;
|
||||
onChange: (event?: React.SyntheticEvent<HTMLInputElement>) => void;
|
||||
export interface SwitchProps extends Omit<HTMLProps<HTMLInputElement>, 'value'> {
|
||||
value?: boolean;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
id: string;
|
||||
}
|
||||
export const getSwitchStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
return {
|
||||
switch: css`
|
||||
width: 32px;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
|
||||
export class Switch extends PureComponent<Props, State> {
|
||||
state = {
|
||||
id: uniqueId(),
|
||||
input {
|
||||
opacity: 0;
|
||||
left: -100vw;
|
||||
z-index: -1000;
|
||||
position: absolute;
|
||||
|
||||
&:disabled + label {
|
||||
background: ${theme.colors.formSwitchBgDisabled};
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&:checked + label {
|
||||
background: ${theme.colors.formSwitchBgActive};
|
||||
|
||||
&:hover {
|
||||
background: ${theme.colors.formSwitchBgActiveHover};
|
||||
}
|
||||
|
||||
&::after {
|
||||
transform: translate3d(18px, -50%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus + label {
|
||||
${getFocusCss(theme)};
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
border-radius: 50px;
|
||||
background: ${theme.colors.formSwitchBg};
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: ${theme.colors.formSwitchBgHover};
|
||||
}
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: '';
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 6px;
|
||||
background: ${theme.colors.formSwitchDot};
|
||||
top: 50%;
|
||||
transform: translate3d(2px, -50%, 0);
|
||||
transition: transform 0.2s cubic-bezier(0.19, 1, 0.22, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
internalOnChange = (event: React.FormEvent<HTMLInputElement>) => {
|
||||
event.stopPropagation();
|
||||
this.props.onChange(event);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
labelClass = '',
|
||||
switchClass = '',
|
||||
label,
|
||||
checked,
|
||||
transparent,
|
||||
className,
|
||||
tooltip,
|
||||
tooltipPlacement,
|
||||
} = this.props;
|
||||
|
||||
const labelId = this.state.id;
|
||||
const labelClassName = `gf-form-label ${labelClass} ${transparent ? 'gf-form-label--transparent' : ''} pointer`;
|
||||
const switchClassName = `gf-form-switch ${switchClass} ${transparent ? 'gf-form-switch--transparent' : ''}`;
|
||||
export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
|
||||
({ value, checked, disabled = false, onChange, ...inputProps }, ref) => {
|
||||
const theme = useTheme();
|
||||
const styles = getSwitchStyles(theme);
|
||||
const switchId = uniqueId('switch-');
|
||||
|
||||
return (
|
||||
<div className="gf-form-switch-container-react">
|
||||
<label htmlFor={labelId} className={`gf-form gf-form-switch-container ${className || ''}`}>
|
||||
{label && (
|
||||
<div className={labelClassName}>
|
||||
{label}
|
||||
{tooltip && (
|
||||
<Tooltip placement={tooltipPlacement ? tooltipPlacement : 'auto'} content={tooltip} theme={'info'}>
|
||||
<div className="gf-form-help-icon gf-form-help-icon--right-normal">
|
||||
<Icon name="info-circle" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className={switchClassName}>
|
||||
<input id={labelId} type="checkbox" checked={checked} onChange={this.internalOnChange} />
|
||||
<span className="gf-form-switch__slider" />
|
||||
</div>
|
||||
</label>
|
||||
<div className={cx(styles.switch)}>
|
||||
<input
|
||||
type="checkbox"
|
||||
disabled={disabled}
|
||||
checked={value}
|
||||
onChange={event => {
|
||||
onChange?.(event);
|
||||
}}
|
||||
id={switchId}
|
||||
{...inputProps}
|
||||
ref={ref}
|
||||
/>
|
||||
<label htmlFor={switchId} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -143,8 +143,10 @@ export { HorizontalGroup, VerticalGroup, Container } from './Layout/Layout';
|
||||
export { RadioButtonGroup } from './Forms/RadioButtonGroup/RadioButtonGroup';
|
||||
|
||||
export { Input } from './Input/Input';
|
||||
export { Switch } from './Forms/Switch';
|
||||
|
||||
export { Switch } from './Switch/Switch';
|
||||
export { Checkbox } from './Forms/Checkbox';
|
||||
|
||||
export { TextArea } from './TextArea/TextArea';
|
||||
|
||||
// Legacy forms
|
||||
@ -158,7 +160,7 @@ import { ButtonSelect } from './Forms/Legacy/Select/ButtonSelect';
|
||||
//Input
|
||||
import { Input, LegacyInputStatus } from './Forms/Legacy/Input/Input';
|
||||
|
||||
import { Switch } from './Switch/Switch';
|
||||
import { Switch } from './Forms/Legacy/Switch/Switch';
|
||||
|
||||
const LegacyForms = {
|
||||
Select,
|
||||
|
@ -19,8 +19,9 @@ import {
|
||||
valueMappingsOverrideProcessor,
|
||||
ThresholdsMode,
|
||||
} from '@grafana/data';
|
||||
|
||||
import { Switch } from '../components/Switch/Switch';
|
||||
import { NumberValueEditor, RadioButtonGroup, StringValueEditor, Select } from '../components';
|
||||
import { Switch } from '../components/Forms/Switch';
|
||||
import { ValueMappingsValueEditor } from '../components/OptionsUI/mappings';
|
||||
import { ThresholdsValueEditor } from '../components/OptionsUI/thresholds';
|
||||
import { UnitValueEditor } from '../components/OptionsUI/units';
|
||||
|
Loading…
Reference in New Issue
Block a user