grafana/ui: Unify disabled styles for input components (#34126)

* Select: Add disabled prop to SingleValue

* TagsInput: Disable remove button with disabled prop

* Checkbox: Add disabled styles
This commit is contained in:
Alex Khomenko 2021-05-15 11:06:42 +03:00 committed by GitHub
parent 1367f7171e
commit 65cacd31c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 39 deletions

View File

@ -1,7 +1,7 @@
import React, { HTMLProps, useCallback } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { getLabelStyles } from './Label';
import { useTheme2, stylesFactory } from '../../themes';
import { stylesFactory, useStyles2 } from '../../themes';
import { css, cx } from '@emotion/css';
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
@ -11,6 +11,37 @@ export interface CheckboxProps extends Omit<HTMLProps<HTMLInputElement>, 'value'
value?: boolean;
}
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
({ label, description, value, onChange, disabled, className, ...inputProps }, ref) => {
const handleOnChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
if (onChange) {
onChange(e);
}
},
[onChange]
);
const styles = useStyles2(getCheckboxStyles);
return (
<label className={cx(styles.wrapper, className)}>
<input
type="checkbox"
className={styles.input}
checked={value}
disabled={disabled}
onChange={handleOnChange}
{...inputProps}
ref={ref}
/>
<span className={styles.checkmark} />
{label && <span className={styles.label}>{label}</span>}
{description && <span className={styles.description}>{description}</span>}
</label>
);
}
);
export const getCheckboxStyles = stylesFactory((theme: GrafanaTheme2) => {
const labelStyles = getLabelStyles(theme);
const checkboxSize = '16px';
@ -79,6 +110,18 @@ export const getCheckboxStyles = stylesFactory((theme: GrafanaTheme2) => {
transform: rotate(45deg);
}
}
&:disabled + span {
background-color: ${theme.colors.action.disabledBackground};
cursor: not-allowed;
&:hover {
background-color: ${theme.colors.action.disabledBackground};
}
&:after {
border-color: ${theme.colors.action.disabledText};
}
}
`,
checkmark: css`
display: inline-block;
@ -100,36 +143,4 @@ export const getCheckboxStyles = stylesFactory((theme: GrafanaTheme2) => {
};
});
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
({ label, description, value, onChange, disabled, className, ...inputProps }, ref) => {
const theme = useTheme2();
const handleOnChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
if (onChange) {
onChange(e);
}
},
[onChange]
);
const styles = getCheckboxStyles(theme);
return (
<label className={cx(styles.wrapper, className)}>
<input
type="checkbox"
className={styles.input}
checked={value}
disabled={disabled}
onChange={handleOnChange}
{...inputProps}
ref={ref}
/>
<span className={styles.checkmark} />
{label && <span className={styles.label}>{label}</span>}
{description && <span className={styles.description}>{description}</span>}
</label>
);
}
);
Checkbox.displayName = 'Checkbox';

View File

@ -314,7 +314,9 @@ export function SelectBase<T>({
DropdownIndicator(props: any) {
return <DropdownIndicator isOpen={props.selectProps.menuIsOpen} />;
},
SingleValue: SingleValue,
SingleValue(props: any) {
return <SingleValue {...props} disabled={disabled} />;
},
MultiValueContainer: MultiValueContainer,
MultiValueRemove: MultiValueRemove,
...components,

View File

@ -34,7 +34,11 @@ const getStyles = (theme: GrafanaTheme2) => {
position: absolute;
`;
return { singleValue, container, item };
const disabled = css`
color: ${theme.colors.action.disabledText};
`;
return { singleValue, container, item, disabled };
};
type StylesType = ReturnType<typeof getStyles>;
@ -44,17 +48,18 @@ interface Props
imgUrl?: string;
loading?: boolean;
hideText?: boolean;
}> {}
}> {
disabled?: boolean;
}
export const SingleValue = (props: Props) => {
const { children, data } = props;
const { children, data, disabled } = props;
const styles = useStyles2(getStyles);
const loading = useDelayedSwitch(data.loading || false, { delay: 250, duration: 750 });
return (
<components.SingleValue {...props}>
<div className={cx(styles.singleValue)}>
<div className={cx(styles.singleValue, disabled && styles.disabled)}>
{data.imgUrl ? (
<FadeWithImage loading={loading} imgUrl={data.imgUrl} styles={styles} />
) : (

View File

@ -32,6 +32,9 @@ export const TagsInput: FC<Props> = ({
};
const onRemove = (tagToRemove: string) => {
if (disabled) {
return;
}
onChange(tags?.filter((x) => x !== tagToRemove));
};