diff --git a/packages/grafana-e2e/src/pages/saveDashboardModal.ts b/packages/grafana-e2e/src/pages/saveDashboardModal.ts index f1131808325..aafd837e71b 100644 --- a/packages/grafana-e2e/src/pages/saveDashboardModal.ts +++ b/packages/grafana-e2e/src/pages/saveDashboardModal.ts @@ -4,5 +4,7 @@ export const SaveDashboardModal = pageFactory({ url: '', selectors: { save: 'Dashboard settings Save Dashboard Modal Save button', + saveVariables: 'Dashboard settings Save Dashboard Modal Save variables checkbox', + saveTimerange: 'Dashboard settings Save Dashboard Modal Save timerange checkbox', }, }); diff --git a/packages/grafana-ui/src/components/Button/Button.tsx b/packages/grafana-ui/src/components/Button/Button.tsx index cad5db2b3d6..b9271e3e536 100644 --- a/packages/grafana-ui/src/components/Button/Button.tsx +++ b/packages/grafana-ui/src/components/Button/Button.tsx @@ -3,6 +3,7 @@ import { ThemeContext } from '../../themes'; import { getButtonStyles } from './styles'; import { ButtonContent } from './ButtonContent'; import { ButtonSize, ButtonStyles, ButtonVariant } from './types'; +import { cx } from 'emotion'; type CommonProps = { size?: ButtonSize; @@ -34,7 +35,7 @@ export const Button = React.forwardRef((props, r }); return ( - ); @@ -62,7 +63,7 @@ export const LinkButton = React.forwardRef(( }); return ( - + {children} ); diff --git a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx index ca3906e2fef..84e5de2a8c2 100644 --- a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx +++ b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx @@ -5,6 +5,7 @@ import { IconType } from '../Icon/types'; import { Button } from '../Button/Button'; import { stylesFactory, ThemeContext } from '../../themes'; import { GrafanaTheme } from '@grafana/data'; +import { HorizontalGroup } from '..'; const getStyles = stylesFactory((theme: GrafanaTheme) => ({ modal: css` @@ -19,13 +20,6 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({ margin-bottom: calc(${theme.spacing.d} * 2); padding-top: ${theme.spacing.d}; `, - modalButtonRow: css` - margin-bottom: 14px; - a, - button { - margin-right: ${theme.spacing.d}; - } - `, })); const defaultIcon: IconType = 'exclamation-triangle'; @@ -33,11 +27,10 @@ const defaultIcon: IconType = 'exclamation-triangle'; interface Props { isOpen: boolean; title: string; - body: string; + body: React.ReactNode; confirmText: string; dismissText?: string; icon?: IconType; - onConfirm(): void; onDismiss(): void; } @@ -59,14 +52,14 @@ export const ConfirmModal: FC = ({
{body}
-
+ -
+
); diff --git a/packages/grafana-ui/src/components/Forms/Button.tsx b/packages/grafana-ui/src/components/Forms/Button.tsx index 4a2e0baddc8..0b8c1a4d38f 100644 --- a/packages/grafana-ui/src/components/Forms/Button.tsx +++ b/packages/grafana-ui/src/components/Forms/Button.tsx @@ -63,7 +63,6 @@ const getPropertiesForVariant = (theme: GrafanaTheme, variant: ButtonVariant) => } `, }; - case 'primary': default: return { @@ -139,23 +138,23 @@ type CommonProps = { export type ButtonProps = CommonProps & ButtonHTMLAttributes; -export const Button = React.forwardRef((props, ref) => { +export const Button = React.forwardRef(({ variant, ...otherProps }, ref) => { const theme = useContext(ThemeContext); const styles = getButtonStyles({ theme, - size: props.size || 'md', - variant: props.variant || 'primary', + size: otherProps.size || 'md', + variant: variant || 'primary', }); - return ; + return ; }); type ButtonLinkProps = CommonProps & AnchorHTMLAttributes; -export const LinkButton = React.forwardRef((props, ref) => { +export const LinkButton = React.forwardRef(({ variant, ...otherProps }, ref) => { const theme = useContext(ThemeContext); const styles = getButtonStyles({ theme, - size: props.size || 'md', - variant: props.variant || 'primary', + size: otherProps.size || 'md', + variant: variant || 'primary', }); - return ; + return ; }); diff --git a/packages/grafana-ui/src/components/Forms/Form.tsx b/packages/grafana-ui/src/components/Forms/Form.tsx index 8ef3d526e6f..b9a75500a1f 100644 --- a/packages/grafana-ui/src/components/Forms/Form.tsx +++ b/packages/grafana-ui/src/components/Forms/Form.tsx @@ -1,20 +1,5 @@ -/** - * This is a stub implementation only for correct styles to be applied - */ - import React, { useEffect } from 'react'; import { useForm, Mode, OnSubmit, DeepPartial, FormContextValues } from 'react-hook-form'; -import { GrafanaTheme } from '@grafana/data'; -import { css } from 'emotion'; -import { stylesFactory, useTheme } from '../../themes'; - -const getFormStyles = stylesFactory((theme: GrafanaTheme) => { - return { - form: css` - margin-bottom: ${theme.spacing.formMargin}; - `, - }; -}); type FormAPI = Pick, 'register' | 'errors' | 'control'>; @@ -26,23 +11,14 @@ interface FormProps { } export function Form({ validateOn, defaultValues, onSubmit, children }: FormProps) { - const theme = useTheme(); const { handleSubmit, register, errors, control, reset, getValues } = useForm({ mode: validateOn || 'onSubmit', - defaultValues: { - ...defaultValues, - }, + defaultValues, }); useEffect(() => { reset({ ...getValues(), ...defaultValues }); }, [defaultValues]); - const styles = getFormStyles(theme); - - return ( -
- {children({ register, errors, control })} -
- ); + return
{children({ register, errors, control })}
; } diff --git a/packages/grafana-ui/src/components/Forms/Select/SelectBase.tsx b/packages/grafana-ui/src/components/Forms/Select/SelectBase.tsx index bea9239b2e5..0af6db41447 100644 --- a/packages/grafana-ui/src/components/Forms/Select/SelectBase.tsx +++ b/packages/grafana-ui/src/components/Forms/Select/SelectBase.tsx @@ -65,6 +65,7 @@ export interface SelectCommonProps { prefix?: JSX.Element | string | null; /** Use a custom element to control Select. A proper ref to the renderControl is needed if 'portal' isn't set to null*/ renderControl?: ControlComponent; + menuPosition?: 'fixed' | 'absolute'; } export interface SelectAsyncProps { @@ -176,6 +177,7 @@ export function SelectBase({ width, invalid, components, + menuPosition, }: SelectBaseProps) { const theme = useTheme(); const styles = getSelectStyles(theme); @@ -246,6 +248,7 @@ export function SelectBase({ renderControl, captureMenuScroll: false, menuPlacement: 'auto', + menuPosition, }; // width property is deprecated in favor of size or className diff --git a/packages/grafana-ui/src/components/Forms/TextArea/TextArea.tsx b/packages/grafana-ui/src/components/Forms/TextArea/TextArea.tsx index b91b49547bc..c84322693c3 100644 --- a/packages/grafana-ui/src/components/Forms/TextArea/TextArea.tsx +++ b/packages/grafana-ui/src/components/Forms/TextArea/TextArea.tsx @@ -1,4 +1,4 @@ -import React, { HTMLProps, forwardRef } from 'react'; +import React, { HTMLProps } from 'react'; import { GrafanaTheme } from '@grafana/data'; import { css, cx } from 'emotion'; import { stylesFactory, useTheme } from '../../../themes'; @@ -12,6 +12,17 @@ export interface Props extends Omit, 'size'> { size?: FormInputSize; } +export const TextArea = React.forwardRef(({ invalid, size = 'auto', ...props }, ref) => { + const theme = useTheme(); + const styles = getTextAreaStyle(theme, invalid); + + return ( +
+