From da6056d5e1b0824c80fcfc1c1ca3270738581af0 Mon Sep 17 00:00:00 2001 From: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com> Date: Wed, 15 Apr 2020 10:59:15 +0200 Subject: [PATCH] Form migrations: Forms/switch move folders (#23430) * Move legacy Switch * Move from Forms folder * Fix prettify issue * Fix prettify issue --- .../ColorPicker/SeriesColorPickerPopover.tsx | 2 +- .../components/DataLinks/DataLinkEditor.tsx | 2 +- .../DataSourceHttpSettings.tsx | 2 +- .../DataSourceSettings/HttpProxySettings.tsx | 2 +- .../src/components/Forms/Field.story.tsx | 2 +- .../src/components/Forms/Form.story.tsx | 2 +- .../components/Forms/Legacy/Switch/Switch.mdx | 3 + .../Legacy}/Switch/Switch.story.internal.tsx | 0 .../components/Forms/Legacy/Switch/Switch.tsx | 71 +++++++++ .../src/components/Forms/Switch.mdx | 25 --- .../src/components/Forms/Switch.tsx | 101 ------------ .../src/components/Forms/getFormStyles.ts | 2 +- .../src/components/Switch/Switch.mdx | 24 ++- .../{Forms => Switch}/Switch.story.tsx | 0 .../src/components/Switch/Switch.tsx | 149 +++++++++++------- packages/grafana-ui/src/components/index.ts | 6 +- .../grafana-ui/src/utils/standardEditors.tsx | 3 +- 17 files changed, 199 insertions(+), 197 deletions(-) create mode 100644 packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.mdx rename packages/grafana-ui/src/components/{ => Forms/Legacy}/Switch/Switch.story.internal.tsx (100%) create mode 100644 packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.tsx delete mode 100644 packages/grafana-ui/src/components/Forms/Switch.mdx delete mode 100644 packages/grafana-ui/src/components/Forms/Switch.tsx rename packages/grafana-ui/src/components/{Forms => Switch}/Switch.story.tsx (100%) diff --git a/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx b/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx index c40d7434611..bd64b5f230c 100644 --- a/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx @@ -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 { diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx index f622f12ede3..74831fdb7d9 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx @@ -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'; diff --git a/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx index e6ec09478db..f2698f10882 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx @@ -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> = [ diff --git a/packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx index bb09064a78a..9b6622d2640 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx @@ -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 = ({ dataSourceConfig, onChange }) => { return ( diff --git a/packages/grafana-ui/src/components/Forms/Field.story.tsx b/packages/grafana-ui/src/components/Forms/Field.story.tsx index 75cd5dabfee..41aeaed495d 100644 --- a/packages/grafana-ui/src/components/Forms/Field.story.tsx +++ b/packages/grafana-ui/src/components/Forms/Field.story.tsx @@ -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 { diff --git a/packages/grafana-ui/src/components/Forms/Form.story.tsx b/packages/grafana-ui/src/components/Forms/Form.story.tsx index 0148d5e5f08..ded4478e682 100644 --- a/packages/grafana-ui/src/components/Forms/Form.story.tsx +++ b/packages/grafana-ui/src/components/Forms/Form.story.tsx @@ -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'; diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.mdx b/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.mdx new file mode 100644 index 00000000000..f347718b212 --- /dev/null +++ b/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.mdx @@ -0,0 +1,3 @@ +# Switch + +A basic docs for Switch component diff --git a/packages/grafana-ui/src/components/Switch/Switch.story.internal.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.story.internal.tsx similarity index 100% rename from packages/grafana-ui/src/components/Switch/Switch.story.internal.tsx rename to packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.story.internal.tsx diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.tsx new file mode 100644 index 00000000000..a0c6fc958c2 --- /dev/null +++ b/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.tsx @@ -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) => void; +} + +export interface State { + id: string; +} + +export class Switch extends PureComponent { + state = { + id: uniqueId(), + }; + + internalOnChange = (event: React.FormEvent) => { + 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 ( +
+ +
+ ); + } +} diff --git a/packages/grafana-ui/src/components/Forms/Switch.mdx b/packages/grafana-ui/src/components/Forms/Switch.mdx deleted file mode 100644 index 1e1936a26cc..00000000000 --- a/packages/grafana-ui/src/components/Forms/Switch.mdx +++ /dev/null @@ -1,25 +0,0 @@ -import { Meta, Story, Preview, Props } from "@storybook/addon-docs/blocks"; -import { Switch } from "./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'; - - -``` - -### Props - - diff --git a/packages/grafana-ui/src/components/Forms/Switch.tsx b/packages/grafana-ui/src/components/Forms/Switch.tsx deleted file mode 100644 index 0848257a939..00000000000 --- a/packages/grafana-ui/src/components/Forms/Switch.tsx +++ /dev/null @@ -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, '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( - ({ value, checked, disabled = false, onChange, ...inputProps }, ref) => { - const theme = useTheme(); - const styles = getSwitchStyles(theme); - const switchId = uniqueId('switch-'); - - return ( -
- { - onChange?.(event); - }} - id={switchId} - {...inputProps} - ref={ref} - /> -
- ); - } -); diff --git a/packages/grafana-ui/src/components/Forms/getFormStyles.ts b/packages/grafana-ui/src/components/Forms/getFormStyles.ts index c46c3b003fd..11c329902bd 100644 --- a/packages/grafana-ui/src/components/Forms/getFormStyles.ts +++ b/packages/grafana-ui/src/components/Forms/getFormStyles.ts @@ -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( diff --git a/packages/grafana-ui/src/components/Switch/Switch.mdx b/packages/grafana-ui/src/components/Switch/Switch.mdx index f347718b212..1e1936a26cc 100644 --- a/packages/grafana-ui/src/components/Switch/Switch.mdx +++ b/packages/grafana-ui/src/components/Switch/Switch.mdx @@ -1,3 +1,25 @@ +import { Meta, Story, Preview, Props } from "@storybook/addon-docs/blocks"; +import { Switch } from "./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'; + + +``` + +### Props + + diff --git a/packages/grafana-ui/src/components/Forms/Switch.story.tsx b/packages/grafana-ui/src/components/Switch/Switch.story.tsx similarity index 100% rename from packages/grafana-ui/src/components/Forms/Switch.story.tsx rename to packages/grafana-ui/src/components/Switch/Switch.story.tsx diff --git a/packages/grafana-ui/src/components/Switch/Switch.tsx b/packages/grafana-ui/src/components/Switch/Switch.tsx index 6dc7a3ecee4..8db64260d3a 100644 --- a/packages/grafana-ui/src/components/Switch/Switch.tsx +++ b/packages/grafana-ui/src/components/Switch/Switch.tsx @@ -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) => void; +export interface SwitchProps extends Omit, '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 { - 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) => { - 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( + ({ value, checked, disabled = false, onChange, ...inputProps }, ref) => { + const theme = useTheme(); + const styles = getSwitchStyles(theme); + const switchId = uniqueId('switch-'); return ( -
- +
+ { + onChange?.(event); + }} + id={switchId} + {...inputProps} + ref={ref} + /> +
); } -} +); diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index 46b334b8a63..ba1579a9d75 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -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, diff --git a/packages/grafana-ui/src/utils/standardEditors.tsx b/packages/grafana-ui/src/utils/standardEditors.tsx index 470ba283ea0..3bdcea7b38e 100644 --- a/packages/grafana-ui/src/utils/standardEditors.tsx +++ b/packages/grafana-ui/src/utils/standardEditors.tsx @@ -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';