toggle>
+);
+```
diff --git a/src/components/utils/_use-first-paint-example.scss b/src/components/utils/_use-first-paint-example.scss
new file mode 100644
index 0000000000..4576598c96
--- /dev/null
+++ b/src/components/utils/_use-first-paint-example.scss
@@ -0,0 +1,38 @@
+.use-first-paint-example-box {
+ animation-duration: 1000ms;
+ position: absolute;
+ height: 200px;
+ width: 200px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background: var(--blue-40);
+ color: var(--white);
+ border-radius: var(--border-radius-xs);
+ cursor: pointer;
+ animation-fill-mode: both;
+ font-weight: bold;
+ animation-name: useFirstPaintExampleToggleOff;
+
+ &--toggled {
+ animation-name: useFirstPaintExampleToggleOn;
+ }
+}
+
+@keyframes useFirstPaintExampleToggleOn {
+ 0% {
+ transform: translateX(0);
+ }
+ 100% {
+ transform: translateX(300px);
+ }
+}
+
+@keyframes useFirstPaintExampleToggleOff {
+ 0% {
+ transform: translateX(300px);
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
diff --git a/src/components/utils/useFirstPaint.stories.mdx b/src/components/utils/useFirstPaint.stories.mdx
new file mode 100644
index 0000000000..fa4e873d32
--- /dev/null
+++ b/src/components/utils/useFirstPaint.stories.mdx
@@ -0,0 +1,62 @@
+import {ArgsTable, Meta, Story, Canvas} from '@storybook/addon-docs';
+import Accordion from '../accordion/Accordion';
+import AccordionItem from '../accordion/AccordionItem';
+import PageHeader from 'blocks/PageHeader';
+import {Example} from './UseFirstpaintExample.tsx';
+
+
+
+
useFirstPaint
+
+`useFirstPaint` is a custom hook for detecting when first DOM paint of component happened. This is useful for e.g. preventing unnecessary animations on initial render.
+
+## Import
+
+```jsx
+import {useFirstPaint} from 'brainly-style-guide';
+```
+
+## Usage
+
+```jsx
+const animatedElementRef = React.useRef();
+const shouldAnimateRef = React.useRef(false);
+const [isToggled, setIsToggled] = React.useState(true);
+const handleClick = React.useCallback(() => {
+ setIsToggled(!isToggled);
+
+ if (shouldAnimateRef.current) {
+ animatedElementRef.current.style.animationDuration = '';
+ }
+}, [isToggled]);
+
+React.useLayoutEffect(() => {
+ animatedElementRef.current.style.animationDuration = '0ms';
+}, []);
+
+useFirstPaint(() => {
+ shouldAnimateRef.current = true;
+});
+
+return (
+
+);
+```
+
+`useFirstPaint` is used here to "hide" transition on first render by making its duration 0ms, but when first paint is done we can reset the duration to see full animation.
+
+
diff --git a/src/components/utils/useFirstPaint.ts b/src/components/utils/useFirstPaint.ts
new file mode 100644
index 0000000000..aa11b7f9b9
--- /dev/null
+++ b/src/components/utils/useFirstPaint.ts
@@ -0,0 +1,13 @@
+import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';
+
+export const useFirstPaint = (cb: () => void) => {
+ useIsomorphicLayoutEffect(() => {
+ const raf = window.requestAnimationFrame(() => {
+ cb();
+ });
+
+ return () => {
+ window.cancelAnimationFrame(raf);
+ };
+ }, [cb]);
+};
diff --git a/src/components/utils/useIsFirstRender.ts b/src/components/utils/useIsFirstRender.ts
deleted file mode 100644
index 33fce0b4e2..0000000000
--- a/src/components/utils/useIsFirstRender.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import {useRef} from 'react';
-
-const useIsFirstRender = () => {
- const isFirstRender = useRef(true);
-
- if (isFirstRender.current === true) {
- isFirstRender.current = false;
- return true;
- }
-
- return isFirstRender.current;
-};
-
-export default useIsFirstRender;
diff --git a/yarn.lock b/yarn.lock
index 8c338f6c05..d85c8290d9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -20068,6 +20068,11 @@ url@^0.11.0:
punycode "1.3.2"
querystring "0.2.0"
+use-isomorphic-layout-effect@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
+ integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
+
use@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"