UNPKG

@grafana/ui

Version:
104 lines (101 loc) 3.27 kB
import { jsxs, Fragment, jsx } from 'react/jsx-runtime'; import { css } from '@emotion/css'; import { debounce } from 'lodash'; import * as React from 'react'; import { useRef, useCallback, useMemo } from 'react'; import { Trans } from '@grafana/i18n'; import { useStyles2 } from '../../themes/ThemeContext.mjs'; import { Field } from '../Forms/Field.mjs'; import { InlineToast } from '../InlineToast/InlineToast.mjs'; import { EllipsisAnimated } from './EllipsisAnimated.mjs'; "use strict"; const SHOW_SUCCESS_DURATION = 2 * 1e3; function AutoSaveField(props) { const { invalid, loading, onFinishChange, saveErrorMessage = "Error saving this value", error, children, disabled, ...restProps } = props; const [fieldState, setFieldState] = React.useState({ isLoading: false, showSuccess: false, showError: invalid }); const fieldRef = useRef(null); React.useEffect(() => { let timeoutId; if (fieldState.showSuccess) { const time = fieldState.showError ? 0 : SHOW_SUCCESS_DURATION; timeoutId = setTimeout(() => { setFieldState({ ...fieldState, showSuccess: false }); }, time); } return () => { window.clearTimeout(timeoutId); }; }, [fieldState]); const handleChange = useCallback( (nextValue) => { if (invalid) { return; } setFieldState({ ...fieldState, isLoading: true, showSuccess: false }); onFinishChange(nextValue).then(() => { setFieldState({ isLoading: false, showSuccess: true, showError: false }); }).catch(() => { setFieldState({ ...fieldState, isLoading: false, showError: true }); }); }, [invalid, fieldState, onFinishChange] ); const lodashDebounce = useMemo(() => debounce(handleChange, 600, { leading: false }), [handleChange]); const isInvalid = invalid || fieldState.showError || void 0; const styles = useStyles2(getStyles); return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( Field, { ...restProps, loading: loading || void 0, invalid: isInvalid, disabled, error: error || fieldState.showError && saveErrorMessage, ref: fieldRef, className: styles.widthFitContent, children: React.cloneElement( children((newValue) => { lodashDebounce(newValue); }) ) } ), fieldState.isLoading && /* @__PURE__ */ jsx(InlineToast, { referenceElement: fieldRef.current, placement: "right", children: /* @__PURE__ */ jsxs(Trans, { i18nKey: "grafana-ui.auto-save-field.saving", children: [ "Saving ", /* @__PURE__ */ jsx(EllipsisAnimated, {}) ] }) }), fieldState.showSuccess && /* @__PURE__ */ jsx(InlineToast, { suffixIcon: "check", referenceElement: fieldRef.current, placement: "right", children: /* @__PURE__ */ jsx(Trans, { i18nKey: "grafana-ui.auto-save-field.saved", children: "Saved!" }) }) ] }); } AutoSaveField.displayName = "AutoSaveField"; const getStyles = () => { return { widthFitContent: css({ width: "fit-content" }) }; }; export { AutoSaveField }; //# sourceMappingURL=AutoSaveField.mjs.map