diff --git a/packages/html-reporter/src/treeItem.tsx b/packages/html-reporter/src/treeItem.tsx
index 98e75f2483..5372a71347 100644
--- a/packages/html-reporter/src/treeItem.tsx
+++ b/packages/html-reporter/src/treeItem.tsx
@@ -17,20 +17,7 @@
import * as React from 'react';
import './treeItem.css';
import * as icons from './icons';
-import { clsx } from '@web/uiUtils';
-
-// flash is retriggered whenever the value changes
-function useFlash(flash: any | undefined) {
- const [flashState, setFlashState] = React.useState(false);
- React.useEffect(() => {
- if (flash) {
- setFlashState(true);
- const timeout = setTimeout(() => setFlashState(false), 1000);
- return () => clearTimeout(timeout);
- }
- }, [flash]);
- return flashState;
-}
+import { clsx, useFlash } from '@web/uiUtils';
export const TreeItem: React.FunctionComponent<{
title: JSX.Element,
diff --git a/packages/trace-viewer/src/ui/attachmentsTab.tsx b/packages/trace-viewer/src/ui/attachmentsTab.tsx
index 31a9355810..f6c0dc2d04 100644
--- a/packages/trace-viewer/src/ui/attachmentsTab.tsx
+++ b/packages/trace-viewer/src/ui/attachmentsTab.tsx
@@ -24,20 +24,7 @@ import { CodeMirrorWrapper, lineHeight } from '@web/components/codeMirrorWrapper
import { isTextualMimeType } from '@isomorphic/mimeType';
import { Expandable } from '@web/components/expandable';
import { linkifyText } from '@web/renderUtils';
-import { clsx } from '@web/uiUtils';
-
-// flash is retriggered whenever the value changes
-function useFlash(flash: any | undefined) {
- const [flashState, setFlashState] = React.useState(false);
- React.useEffect(() => {
- if (flash) {
- setFlashState(true);
- const timeout = setTimeout(() => setFlashState(false), 1000);
- return () => clearTimeout(timeout);
- }
- }, [flash]);
- return flashState;
-}
+import { clsx, useFlash } from '@web/uiUtils';
type Attachment = AfterActionTraceEventAttachment & { traceUrl: string };
diff --git a/packages/web/src/uiUtils.ts b/packages/web/src/uiUtils.ts
index 3544ec4bdc..fe24828b97 100644
--- a/packages/web/src/uiUtils.ts
+++ b/packages/web/src/uiUtils.ts
@@ -224,3 +224,16 @@ export function scrollIntoViewIfNeeded(element: Element | undefined) {
const kControlCodesRe = '\\u0000-\\u0020\\u007f-\\u009f';
export const kWebLinkRe = new RegExp('(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|www\\.)[^\\s' + kControlCodesRe + '"]{2,}[^\\s' + kControlCodesRe + '"\')}\\],:;.!?]', 'ug');
+
+// flash is retriggered whenever the value changes
+export function useFlash(flash: any | undefined) {
+ const [flashState, setFlashState] = React.useState(false);
+ React.useEffect(() => {
+ if (flash) {
+ setFlashState(true);
+ const timeout = setTimeout(() => setFlashState(false), 1000);
+ return () => clearTimeout(timeout);
+ }
+ }, [flash]);
+ return flashState;
+}