From 52b120cb676ebdcb745cb9468018d7b3b71ee292 Mon Sep 17 00:00:00 2001 From: Juan Cabanas Date: Fri, 25 Apr 2025 09:48:32 -0300 Subject: [PATCH] Grafana UI: Add `ref` to `DatePickerWithInput` (#104346) Co-authored-by: Ashley Harrison --- .../DatePickerWithInput.tsx | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx index c1f151beded..e13dd5d8840 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx @@ -1,6 +1,6 @@ import { css } from '@emotion/css'; import { autoUpdate, flip, shift, useClick, useDismiss, useFloating, useInteractions } from '@floating-ui/react'; -import { ChangeEvent, useState } from 'react'; +import { ChangeEvent, forwardRef, useImperativeHandle, useState } from 'react'; import { GrafanaTheme2, dateTime } from '@grafana/data'; @@ -11,7 +11,7 @@ import { DatePicker } from '../DatePicker/DatePicker'; export const formatDate = (date: Date | string) => dateTime(date).format('L'); /** @public */ -export interface DatePickerWithInputProps extends Omit { +export interface DatePickerWithInputProps extends Omit { /** Value selected by the DatePicker */ value?: Date | string; /** The minimum date the value can be set to */ @@ -27,78 +27,78 @@ export interface DatePickerWithInputProps extends Omit { - const [open, setOpen] = useState(false); - const styles = useStyles2(getStyles); +export const DatePickerWithInput = forwardRef( + ({ value, minDate, maxDate, onChange, closeOnSelect, placeholder = 'Date', ...rest }, ref) => { + const [open, setOpen] = useState(false); + const styles = useStyles2(getStyles); - // the order of middleware is important! - // see https://floating-ui.com/docs/arrow#order - const middleware = [ - flip({ - // see https://floating-ui.com/docs/flip#combining-with-shift - crossAxis: false, - boundary: document.body, - }), - shift(), - ]; + // the order of middleware is important! + // see https://floating-ui.com/docs/arrow#order + const middleware = [ + flip({ + // see https://floating-ui.com/docs/flip#combining-with-shift + crossAxis: false, + boundary: document.body, + }), + shift(), + ]; - const { context, refs, floatingStyles } = useFloating({ - open, - placement: 'bottom-start', - onOpenChange: setOpen, - middleware, - whileElementsMounted: autoUpdate, - strategy: 'fixed', - }); + const { context, refs, floatingStyles } = useFloating({ + open, + placement: 'bottom-start', + onOpenChange: setOpen, + middleware, + whileElementsMounted: autoUpdate, + strategy: 'fixed', + }); - const click = useClick(context); - const dismiss = useDismiss(context); - const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, click]); + const click = useClick(context); + const dismiss = useDismiss(context); + const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, click]); - return ( -
- ) => { - // Allow resetting the date - if (ev.target.value === '') { - onChange(''); - } - }} - className={styles.input} - {...rest} - {...getReferenceProps()} - /> -
- { - onChange(ev); - if (closeOnSelect) { - setOpen(false); + useImperativeHandle(ref, () => refs.domReference.current, [ + refs.domReference, + ]); + + return ( +
+ ) => { + // Allow resetting the date + if (ev.target.value === '') { + onChange(''); } }} - onClose={() => setOpen(false)} + className={styles.input} + {...rest} + {...getReferenceProps()} /> +
+ { + onChange(ev); + if (closeOnSelect) { + setOpen(false); + } + }} + onClose={() => setOpen(false)} + /> +
-
- ); -}; + ); + } +); + +DatePickerWithInput.displayName = 'DatePickerWithInput'; const getStyles = (theme: GrafanaTheme2) => { return {