From 26f090369abbc051c7d5ec983e84b348240af504 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Thu, 20 Nov 2025 15:20:01 -0500 Subject: [PATCH] feat: Coin flip animation --- .../EnableOrganizationsPrompt/index.tsx | 266 ++++++++++-------- 1 file changed, 143 insertions(+), 123 deletions(-) diff --git a/packages/clerk-js/src/ui/components/devPrompts/EnableOrganizationsPrompt/index.tsx b/packages/clerk-js/src/ui/components/devPrompts/EnableOrganizationsPrompt/index.tsx index 152549adbfb..aad8f189846 100644 --- a/packages/clerk-js/src/ui/components/devPrompts/EnableOrganizationsPrompt/index.tsx +++ b/packages/clerk-js/src/ui/components/devPrompts/EnableOrganizationsPrompt/index.tsx @@ -4,7 +4,7 @@ import type { __internal_EnableOrganizationsPromptProps, EnableEnvironmentSettin import type { SerializedStyles } from '@emotion/react'; // eslint-disable-next-line no-restricted-imports import { css, type Theme } from '@emotion/react'; -import { forwardRef, useId, useMemo, useRef, useState } from 'react'; +import { forwardRef, useId, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { useEnvironment } from '@/ui/contexts'; import { Modal } from '@/ui/elements/Modal'; @@ -122,128 +122,7 @@ const EnableOrganizationsPromptInternal = ({ gap: t.sizes.$2, })} > -
- {isEnabled ? ( - - - - ) : ( - <> - - - - - - - - - - - - - - )} -
+

& { css?: S ); }, ); + +const CoinFlip = ({ isEnabled }: { isEnabled: boolean }) => { + const [rotation, setRotation] = useState(0); + + useLayoutEffect(() => { + if (isEnabled) { + setRotation(r => (r === 0 ? 180 : 0)); + return; + } + + const interval = setInterval(() => { + setRotation(r => (r === 0 ? 180 : 0)); + }, 2000); + + return () => clearInterval(interval); + }, [isEnabled]); + + let frontFaceType: 'idle' | 'success' = 'idle'; + let backFaceType: 'warning' | 'success' = 'warning'; + + if (isEnabled) { + if (rotation === 0) { + frontFaceType = 'success'; + backFaceType = 'warning'; + } else { + backFaceType = 'success'; + frontFaceType = 'idle'; + } + } + + const renderContent = (type: 'idle' | 'warning' | 'success') => { + switch (type) { + case 'idle': + return ; + case 'success': + return ( + + ); + case 'warning': + return ( + + + + + + + ); + } + }; + + return ( +
+
+ + {renderContent(frontFaceType)} + + + + {renderContent(backFaceType)} + +
+
+ ); +};