@grafana/ui
Version:
Grafana Components Library
157 lines (154 loc) • 4.8 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { css, cx } from '@emotion/css';
import { useFloating, useDismiss, useInteractions } from '@floating-ui/react';
import { FocusScope } from '@react-aria/focus';
import { useState } from 'react';
import { dateTime, getDefaultTimeRange } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useStyles2 } from '../../themes/ThemeContext.mjs';
import { Icon } from '../Icon/Icon.mjs';
import { getInputStyles } from '../Input/Input.mjs';
import { TimePickerContent } from './TimeRangePicker/TimePickerContent.mjs';
import { TimeRangeLabel } from './TimeRangePicker/TimeRangeLabel.mjs';
import { getQuickOptions } from './options.mjs';
import { isValidTimeRange } from './utils.mjs';
"use strict";
const noop = () => {
};
const TimeRangeInput = ({
value,
onChange,
onChangeTimeZone = noop,
clearable,
weekStart,
hideTimeZone = true,
timeZone = "browser",
placeholder = "Select time range",
isReversed = true,
hideQuickRanges = false,
disabled = false,
showIcon = false
}) => {
const [isOpen, setIsOpen] = useState(false);
const styles = useStyles2(getStyles, disabled);
const onOpen = (event) => {
event.stopPropagation();
event.preventDefault();
if (disabled) {
return;
}
setIsOpen(!isOpen);
};
const onClose = () => {
setIsOpen(false);
};
const onRangeChange = (timeRange) => {
onClose();
onChange(timeRange);
};
const onRangeClear = (event) => {
event.stopPropagation();
const from = dateTime(null);
const to = dateTime(null);
onChange({ from, to, raw: { from, to } });
};
const { refs, floatingStyles, context } = useFloating({
open: isOpen,
onOpenChange: setIsOpen,
placement: "bottom-start",
strategy: "fixed"
});
const dismiss = useDismiss(context, {
bubbles: {
outsidePress: false
}
});
const { getReferenceProps, getFloatingProps } = useInteractions([dismiss]);
return /* @__PURE__ */ jsxs("div", { className: styles.container, children: [
/* @__PURE__ */ jsxs(
"button",
{
type: "button",
className: styles.pickerInput,
"data-testid": selectors.components.TimePicker.openButton,
onClick: onOpen,
ref: refs.setReference,
...getReferenceProps(),
children: [
showIcon && /* @__PURE__ */ jsx(Icon, { name: "clock-nine", size: "sm", className: styles.icon }),
/* @__PURE__ */ jsx(TimeRangeLabel, { value, timeZone, placeholder }),
!disabled && /* @__PURE__ */ jsxs("span", { className: styles.caretIcon, children: [
isValidTimeRange(value) && clearable && /* @__PURE__ */ jsx(Icon, { className: styles.clearIcon, name: "times", size: "lg", onClick: onRangeClear }),
/* @__PURE__ */ jsx(Icon, { name: isOpen ? "angle-up" : "angle-down", size: "lg" })
] })
]
}
),
isOpen && /* @__PURE__ */ jsx(FocusScope, { contain: true, autoFocus: true, restoreFocus: true, children: /* @__PURE__ */ jsx("section", { className: styles.content, ref: refs.setFloating, style: floatingStyles, ...getFloatingProps(), children: /* @__PURE__ */ jsx(
TimePickerContent,
{
timeZone,
value: isValidTimeRange(value) ? value : getDefaultTimeRange(),
onChange: onRangeChange,
quickOptions: getQuickOptions(),
onChangeTimeZone,
className: styles.content,
hideTimeZone,
isReversed,
hideQuickRanges,
weekStart
}
) }) })
] });
};
const getStyles = (theme, disabled = false) => {
const inputStyles = getInputStyles({ theme, invalid: false });
return {
container: css({
display: "flex",
position: "relative"
}),
content: css({
marginLeft: 0,
position: "absolute",
top: "116%",
zIndex: theme.zIndex.modal
}),
pickerInput: cx(
inputStyles.input,
disabled && inputStyles.inputDisabled,
inputStyles.wrapper,
css({
display: "flex",
alignItems: "center",
justifyContent: "space-between",
cursor: "pointer",
paddingRight: 0,
lineHeight: `${theme.spacing.gridSize * 4 - 2}px`
})
),
caretIcon: cx(
inputStyles.suffix,
css({
position: "relative",
top: "-1px",
marginLeft: theme.spacing(0.5)
})
),
clearIcon: css({
marginRight: theme.spacing(0.5),
"&:hover": {
color: theme.colors.text.maxContrast
}
}),
placeholder: css({
color: theme.colors.text.disabled,
opacity: 1
}),
icon: css({
marginRight: theme.spacing(0.5)
})
};
};
export { TimeRangeInput };
//# sourceMappingURL=TimeRangeInput.mjs.map