Skip to content

Commit

Permalink
Popup window to be centred on screen (#198)
Browse files Browse the repository at this point in the history
Co-authored-by: Matt Gowland <[email protected]>
Co-authored-by: Sebastian Vittersø <[email protected]>
  • Loading branch information
3 people authored Nov 5, 2024
1 parent 7dbd49d commit 1a5b45e
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
8 changes: 7 additions & 1 deletion src/authentication.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { postWithXForm } from './httpUtils'
import { generateCodeChallenge, generateRandomString } from './pkceUtils'
import { calculatePopupPosition } from './popupUtils'
import type {
TInternalConfig,
TPrimitiveRecord,
Expand Down Expand Up @@ -54,7 +55,12 @@ export async function redirectToLogin(
if (config?.preLogin) config.preLogin()

if (method === 'popup') {
const handle: null | WindowProxy = window.open(loginUrl, 'loginPopup', 'popup width=600 height=600')
const { width, height, left, top } = calculatePopupPosition(600, 600)
const handle: null | WindowProxy = window.open(
loginUrl,
'loginPopup',
`width=${width},height=${height},top=${top},left=${left}`
)
if (handle) return
console.warn('Popup blocked. Redirecting to login page. Disable popup blocker to use popup login.')
}
Expand Down
25 changes: 25 additions & 0 deletions src/popupUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { TPopupPosition } from './types'

export function calculatePopupPosition(popupWidth = 600, popupHeight = 600): TPopupPosition {
// Calculate the screen dimensions and position the popup at the center
const screenLeft = window.screenLeft
const screenTop = window.screenTop
const screenWidth = window.innerWidth
const screenHeight = window.innerHeight

// Calculate the position to center the popup
const defaultLeft = screenLeft + (screenWidth - popupWidth) / 2
const defaultTop = screenTop + (screenHeight - popupHeight) / 2

// Ensure the bottom-right corner does not go off the screen
// Adjust the left and top positions if necessary
const maxLeft = screenLeft + (screenWidth - popupWidth)
const maxTop = screenTop + (screenHeight - popupHeight)

return {
width: Math.min(popupWidth, screenWidth),
height: Math.min(popupHeight, screenHeight),
left: Math.max(0, Math.min(defaultLeft, maxLeft)),
top: Math.max(0, Math.min(defaultTop, maxTop)),
}
}
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ export type TTokenResponse = {
id_token?: string
}

export type TPopupPosition = {
left: number
top: number
width: number
height: number
}

export interface IAuthProvider {
authConfig: TAuthConfig
children: ReactNode
Expand Down
5 changes: 4 additions & 1 deletion tests/login.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ test('First page visit should redirect to auth provider for login', async () =>
})

test('First page visit should popup to auth provider for login', async () => {
// set window size to 1200x800 to make test predictable in different environments
global.innerWidth = 1200
global.innerHeight = 800
render(
<AuthProvider authConfig={{ ...authConfig, loginMethod: 'popup' }}>
<AuthConsumer />
Expand All @@ -33,7 +36,7 @@ test('First page visit should popup to auth provider for login', async () => {
/^myAuthEndpoint\?response_type=code&client_id=myClientID&redirect_uri=http%3A%2F%2Flocalhost%2F&code_challenge=.{43}&code_challenge_method=S256&scope=someScope\+openid&state=testState/gm
),
'loginPopup',
'popup width=600 height=600'
'width=600,height=600,top=100,left=300'
)
})
})
Expand Down

0 comments on commit 1a5b45e

Please sign in to comment.