mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Grafana-UI: Add disabled state to picker components (#34005)
* TimeRangeInput: add disabled prop * TimeOfDayPicker: add disabled prop * TimeZonePicker: add disabled prop * TagsInput: add disabled prop
This commit is contained in:
parent
6200c40160
commit
167bad070b
@ -145,6 +145,10 @@ export const getInputStyles = stylesFactory(({ theme, invalid = false, width }:
|
||||
inputDisabled: css`
|
||||
background-color: ${theme.colors.action.disabledBackground};
|
||||
color: ${theme.colors.action.disabledText};
|
||||
border: 1px solid ${theme.colors.action.disabledBackground};
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
`,
|
||||
addon: css`
|
||||
label: input-addon;
|
||||
|
@ -12,6 +12,7 @@ export interface Props {
|
||||
onChange: (tags: string[]) => void;
|
||||
width?: number;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const TagsInput: FC<Props> = ({
|
||||
@ -20,6 +21,7 @@ export const TagsInput: FC<Props> = ({
|
||||
onChange,
|
||||
width,
|
||||
className,
|
||||
disabled,
|
||||
}) => {
|
||||
const [newTagName, setNewName] = useState('');
|
||||
const styles = useStyles(getStyles);
|
||||
@ -58,6 +60,7 @@ export const TagsInput: FC<Props> = ({
|
||||
</div>
|
||||
<div>
|
||||
<Input
|
||||
disabled={disabled}
|
||||
placeholder={placeholder}
|
||||
onChange={onNameChange}
|
||||
value={newTagName}
|
||||
|
@ -2,7 +2,7 @@ import React, { FC } from 'react';
|
||||
import RcTimePicker from 'rc-time-picker';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { dateTime, DateTime, dateTimeAsMoment, GrafanaTheme } from '@grafana/data';
|
||||
import { useTheme, Icon } from '../../index';
|
||||
import { Icon, useStyles } from '../../index';
|
||||
import { stylesFactory } from '../../themes';
|
||||
import { inputSizes } from '../Forms/commonStyles';
|
||||
import { FormInputSize } from '../Forms/types';
|
||||
@ -14,8 +14,48 @@ export interface Props {
|
||||
showHour?: boolean;
|
||||
minuteStep?: number;
|
||||
size?: FormInputSize;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const TimeOfDayPicker: FC<Props> = ({
|
||||
minuteStep = 1,
|
||||
showHour = true,
|
||||
onChange,
|
||||
value,
|
||||
size = 'auto',
|
||||
disabled,
|
||||
}) => {
|
||||
const styles = useStyles(getStyles);
|
||||
|
||||
return (
|
||||
<RcTimePicker
|
||||
className={cx(inputSizes()[size], styles.input)}
|
||||
popupClassName={styles.picker}
|
||||
defaultValue={dateTimeAsMoment()}
|
||||
onChange={(value: any) => onChange(dateTime(value))}
|
||||
allowEmpty={false}
|
||||
showSecond={false}
|
||||
value={dateTimeAsMoment(value)}
|
||||
showHour={showHour}
|
||||
minuteStep={minuteStep}
|
||||
inputIcon={<Caret wrapperStyle={styles.caretWrapper} />}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
interface CaretProps {
|
||||
wrapperStyle?: string;
|
||||
}
|
||||
|
||||
const Caret: FC<CaretProps> = ({ wrapperStyle = '' }) => {
|
||||
return (
|
||||
<div className={wrapperStyle}>
|
||||
<Icon name="angle-down" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
const bgColor = theme.colors.formInputBg;
|
||||
const menuShadowColor = theme.colors.dropdownShadow;
|
||||
@ -79,40 +119,16 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
&:focus {
|
||||
${focusCss(theme)}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background-color: ${theme.colors.formInputBgDisabled};
|
||||
color: ${theme.colors.formInputDisabledText};
|
||||
border: 1px solid ${theme.colors.formInputBgDisabled};
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
export const TimeOfDayPicker: FC<Props> = ({ minuteStep = 1, showHour = true, onChange, value, size = 'auto' }) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyles(theme);
|
||||
return (
|
||||
<div>
|
||||
<RcTimePicker
|
||||
className={cx(inputSizes()[size], styles.input)}
|
||||
popupClassName={styles.picker}
|
||||
defaultValue={dateTimeAsMoment()}
|
||||
onChange={(value: any) => onChange(dateTime(value))}
|
||||
allowEmpty={false}
|
||||
showSecond={false}
|
||||
value={dateTimeAsMoment(value)}
|
||||
showHour={showHour}
|
||||
minuteStep={minuteStep}
|
||||
inputIcon={<Caret wrapperStyle={styles.caretWrapper} />}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface CaretProps {
|
||||
wrapperStyle?: string;
|
||||
}
|
||||
|
||||
const Caret: FC<CaretProps> = ({ wrapperStyle = '' }) => {
|
||||
return (
|
||||
<div className={wrapperStyle}>
|
||||
<Icon name="angle-down" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,15 +1,15 @@
|
||||
import React, { FC, FormEvent, MouseEvent, useState } from 'react';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { dateMath, dateTime, getDefaultTimeRange, GrafanaTheme2, TimeRange, TimeZone } from '@grafana/data';
|
||||
import { useStyles2 } from '../../themes/ThemeContext';
|
||||
import { useTheme2 } from '../../themes/ThemeContext';
|
||||
import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { getInputStyles } from '../Input/Input';
|
||||
import { getFocusStyle } from '../Forms/commonStyles';
|
||||
import { TimePickerButtonLabel } from './TimeRangePicker';
|
||||
import { TimePickerContent } from './TimeRangePicker/TimePickerContent';
|
||||
import { otherOptions, quickOptions } from './rangeOptions';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { stylesFactory } from '../../themes';
|
||||
|
||||
const isValidTimeRange = (range: any) => {
|
||||
return dateMath.isValid(range.from) && dateMath.isValid(range.to);
|
||||
@ -25,6 +25,7 @@ export interface TimeRangeInputProps {
|
||||
clearable?: boolean;
|
||||
isReversed?: boolean;
|
||||
hideQuickRanges?: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const noop = () => {};
|
||||
@ -39,13 +40,18 @@ export const TimeRangeInput: FC<TimeRangeInputProps> = ({
|
||||
placeholder = 'Select time range',
|
||||
isReversed = true,
|
||||
hideQuickRanges = false,
|
||||
disabled = false,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const styles = useStyles2(getStyles);
|
||||
const theme = useTheme2();
|
||||
const styles = getStyles(theme, disabled);
|
||||
|
||||
const onOpen = (event: FormEvent<HTMLDivElement>) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
@ -79,12 +85,14 @@ export const TimeRangeInput: FC<TimeRangeInputProps> = ({
|
||||
<span className={styles.placeholder}>{placeholder}</span>
|
||||
)}
|
||||
|
||||
{!disabled && (
|
||||
<span className={styles.caretIcon}>
|
||||
{isValidTimeRange(value) && clearable && (
|
||||
<Icon className={styles.clearIcon} name="times" size="lg" onClick={onRangeClear} />
|
||||
)}
|
||||
<Icon name={isOpen ? 'angle-up' : 'angle-down'} size="lg" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{isOpen && (
|
||||
<ClickOutsideWrapper includeButtonPress={false} onClick={onClose}>
|
||||
@ -106,7 +114,7 @@ export const TimeRangeInput: FC<TimeRangeInputProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme2, disabled = false) => {
|
||||
const inputStyles = getInputStyles({ theme, invalid: false });
|
||||
return {
|
||||
container: css`
|
||||
@ -118,6 +126,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
`,
|
||||
pickerInput: cx(
|
||||
inputStyles.input,
|
||||
disabled && inputStyles.inputDisabled,
|
||||
inputStyles.wrapper,
|
||||
css`
|
||||
display: flex;
|
||||
@ -126,7 +135,6 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
cursor: pointer;
|
||||
padding-right: 0;
|
||||
line-height: ${theme.v1.spacing.formInputHeight - 2}px;
|
||||
${getFocusStyle(theme.v1)};
|
||||
`
|
||||
),
|
||||
caretIcon: cx(
|
||||
@ -147,4 +155,4 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
opacity: 1;
|
||||
`,
|
||||
};
|
||||
};
|
||||
});
|
||||
|
@ -21,10 +21,11 @@ export interface Props {
|
||||
autoFocus?: boolean;
|
||||
onBlur?: () => void;
|
||||
includeInternal?: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const TimeZonePicker: React.FC<Props> = (props) => {
|
||||
const { onChange, width, autoFocus = false, onBlur, value, includeInternal = false } = props;
|
||||
const { onChange, width, autoFocus = false, onBlur, value, includeInternal = false, disabled = false } = props;
|
||||
const groupedTimeZones = useTimeZones(includeInternal);
|
||||
const selected = useSelectedTimeZone(groupedTimeZones, value);
|
||||
const filterBySearchIndex = useFilterBySearchIndex();
|
||||
@ -52,6 +53,7 @@ export const TimeZonePicker: React.FC<Props> = (props) => {
|
||||
onChange={onChangeTz}
|
||||
onBlur={onBlur}
|
||||
components={{ Option: TimeZoneOption, Group: TimeZoneGroup }}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user