Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const App = () => {
| `onShowConnectSuccessSurvey` | [`AnalyticContextType`](./typings/connectProps.d.ts#L100) | The connect widget provides a way to let your analytics provider know that the connect success survey was shown. [More details](./docs/ANALYTICS.md#onShowConnectSuccessSurvey) |
| `onSubmitConnectSuccessSurvey` | [`AnalyticContextType`](./typings/connectProps.d.ts#L101) | The connect widget provides a way to submit connect success survey responses using your own analytics provider. [More details](./docs/ANALYTICS.md#onSubmitConnectSuccessSurvey) | |
| `profiles` | [`ProfilesTypes`](./typings/connectProps.d.ts) | The connect widget uses the profiles to set the initial state of the widget. [More details](./docs/PROFILES.md) | See more details |
| `userFeatures` | [`UserFeaturesType`](./typings/connectProps.d.ts) | The connect widget uses user features to determine the behavior of the widget. [More details](./docs/USER_FEATURES.md) | See more details
| `userFeatures` | [`UserFeaturesType`](./typings/connectProps.d.ts) | The connect widget uses user features to determine the behavior of the widget. [More details](./docs/USER_FEATURES.md) | See more details |
| `webSocketConnection` | `object` | An object containing `isConnected()` function and `webSocketMessages$` observable for real-time updates. | `null` |
| `experimentalFeatures` | `object` | An object to enable or disable experimental features like `useWebSockets: true`. | `null` |

Expand Down
54 changes: 11 additions & 43 deletions src/components/ConnectNavigationHeader.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import React, { useContext, useState, useEffect, useRef } from 'react'
import PropTypes from 'prop-types'
import { useSelector } from 'react-redux'
import { useTokens } from '@kyper/tokenprovider'

import AppBar from '@mui/material/AppBar'
import Box from '@mui/material/Box'
import Toolbar from '@mui/material/Toolbar'
import IconButton from '@mui/material/IconButton'
import { Icon } from '@mxenabled/mxui'

import { __ } from 'src/utilities/Intl'
import { STEPS } from 'src/const/Connect'
import { PostMessageContext } from 'src/ConnectWidget'
import { GoBackButtonHeader } from 'src/components/GoBackButtonHeader'
import styles from 'src/components/ConnectNavigationHeader.module.css'

export const ConnectNavigationHeader = (props) => {
const goBackButtonContainerRef = useRef()
const postMessageFunctions = useContext(PostMessageContext)
const tokens = useTokens()
const sx = getStyles(tokens)
const step = useSelector(
(state) => state.connect.location[state.connect.location.length - 1]?.step ?? STEPS.SEARCH,
)
const showMobileBackButton = useSelector(
(state) => state.config.show_back_button && state.connect.location.length === 1,
)
const showMobileBackButton =
useSelector((state) => state.config.show_back_button && state.connect.location.length === 1) ||
false
const [shouldShowGlobalBackButton, setShouldShowGlobalBackButton] = useState(false)

useEffect(() => {
Expand Down Expand Up @@ -65,40 +57,16 @@ export const ConnectNavigationHeader = (props) => {
}

return (
<Box data-test="navigation-header" sx={sx.container}>
<AppBar elevation={0} position="static" sx={sx.appBar}>
<Toolbar disableGutters={true} sx={sx.toolbar}>
{shouldShowGlobalBackButton || showMobileBackButton ? (
<IconButton
aria-label={__('Go Back')}
data-test="back-button"
name="connect-navigation-back-button"
onClick={backButtonNavigationHandler}
ref={goBackButtonContainerRef}
sx={sx.button}
>
<Icon name="arrow_back_ios_new" size={24} />
</IconButton>
) : null}
</Toolbar>
</AppBar>
</Box>
<GoBackButtonHeader
handleGoBack={backButtonNavigationHandler}
ref={goBackButtonContainerRef}
shouldShowBackButton={shouldShowGlobalBackButton || showMobileBackButton}
toolbarClassName={styles.toolbar}
/>
)
}

ConnectNavigationHeader.propTypes = {
connectGoBack: PropTypes.func.isRequired,
stepComponentRef: PropTypes.object,
}

const getStyles = (tokens) => ({
container: { flexGrow: 1 },
appBar: { backgroundColor: tokens.BackgroundColor.Container, display: 'flex' },
toolbar: {
padding: `0 ${tokens.Spacing.Medium}px`,
maxWidth: '368px',
left: '50%',
transform: 'translateX(-50%)',
},
button: { color: tokens.TextColor.Default },
})
4 changes: 4 additions & 0 deletions src/components/ConnectNavigationHeader.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.toolbar.toolbar:global(.MuiToolbar-root) {
left: 50%;
transform: translateX(-50%);
}
7 changes: 7 additions & 0 deletions src/components/DayOfMonthPicker.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.textGroup:global(.MuiStack-root) {
margin-bottom: var(--spacing-3);
}

.button:global(.MuiButton-root) {
width: 14.25%;
}
60 changes: 21 additions & 39 deletions src/components/DayOfMonthPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import React, { MutableRefObject } from 'react'

import _range from 'lodash/range'

import { useTokens } from '@kyper/tokenprovider'
import { Button } from '@mui/material'
import { Button, Stack } from '@mui/material'
import { Text } from '@mxenabled/mxui'

import { fadeOut } from 'src/utilities/Animation'
import { __ } from 'src/utilities/Intl'

import { GoBackButton } from 'src/components/GoBackButton'
import { GoBackButtonHeader } from 'src/components/GoBackButtonHeader'
import { SlideDown } from 'src/components/SlideDown'
import { getDelay } from 'src/utilities/getDelay'

import styles from './DayOfMonthPicker.module.css'

interface DayOfMonthPicker {
handleClose: () => void
handleSelect: (e: React.MouseEvent<HTMLElement>) => void
Expand All @@ -21,73 +22,54 @@ interface DayOfMonthPicker {

export const DayOfMonthPicker = React.forwardRef<HTMLInputElement, DayOfMonthPicker>(
(props, ref) => {
const tokens = useTokens()
const styles = getStyles(tokens)
const getNextDelay = getDelay()
const days = _range(1, 32)
const containerRef = ref as MutableRefObject<HTMLInputElement>

return (
<div ref={containerRef}>
<SlideDown delay={getNextDelay()}>
<GoBackButton
<GoBackButtonHeader
handleGoBack={() => fadeOut(containerRef?.current, 'up', 300).then(props.handleClose)}
/>
</SlideDown>
<SlideDown delay={getNextDelay()}>
<Text
component="h2"
data-test="date-picker-header"
sx={{ marginBottom: tokens.Spacing.XSmall }}
truncate={false}
variant="H2"
>
{__('Payment due day')}
</Text>
<Text
component="p"
data-test="date-picker-paragraph"
sx={{ marginBottom: tokens.Spacing.Large }}
truncate={false}
variant="Paragraph"
>
{__('Choose what day of the month your payment is due.')}
</Text>
<Stack className={styles.textGroup} spacing={1}>
<Text component="h2" data-test="date-picker-header" truncate={false} variant="H2">
{__('Payment due day')}
</Text>
<Text
component="p"
data-test="date-picker-paragraph"
truncate={false}
variant="Paragraph"
>
{__('Choose what day of the month your payment is due.')}
</Text>
</Stack>
</SlideDown>
<SlideDown delay={getNextDelay()}>
<div data-test="date-picker-calendar" style={styles.buttons}>
<Stack data-test="date-picker-calendar" direction="row" flexWrap="wrap">
{days.map((day: number) => (
<Button
autoFocus={day === 1}
className={styles.button}
data-test={`date-picker-button-${day}`}
key={day}
name={props.name}
onClick={(e: React.MouseEvent<HTMLElement>) => {
fadeOut(containerRef?.current, 'up', 300).then(() => props.handleSelect(e))
}}
style={styles.button}
value={day}
>
{day}
</Button>
))}
</div>
</Stack>
</SlideDown>
</div>
)
},
)

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getStyles = (tokens: any) => ({
buttons: {
display: 'flex',
flexWrap: 'wrap' as const,
marginTop: tokens.Spacing.XSmall,
},
button: {
width: '14.25%',
},
})

DayOfMonthPicker.displayName = 'DayOfMonthPicker'
48 changes: 0 additions & 48 deletions src/components/GoBackButton.tsx

This file was deleted.

18 changes: 18 additions & 0 deletions src/components/GoBackButtonHeader.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.container:global(.MuiBox-root) {
flex-grow: 1;
}

.appBar:global(.MuiAppBar-root) {
background-color: var(--mui-palette-background-paper);
display: flex;
}

.toolbar:global(.MuiToolbar-root) {
left: 0;
max-width: 368px;
transform: translateX(-10%);
}

.button:global(.MuiIconButton-root) {
color: var(--mui-palette-text-primary);
}
42 changes: 42 additions & 0 deletions src/components/GoBackButtonHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { forwardRef, useRef } from 'react'
import { AppBar, Box, IconButton, Toolbar } from '@mui/material'
import { Icon } from '@mxenabled/mxui'
import clsx from 'clsx'

import { __ } from 'src/utilities/Intl'

import styles from 'src/components/GoBackButtonHeader.module.css'

interface GoBackButtonProps {
handleGoBack: () => void
shouldShowBackButton?: boolean
toolbarClassName?: string
}

export const GoBackButtonHeader = forwardRef<HTMLButtonElement, GoBackButtonProps>((props, ref) => {
const defaultRef = useRef(null)
const { handleGoBack, shouldShowBackButton = true, toolbarClassName } = props

return (
<Box className={styles.container} data-test="navigation-header">
<AppBar className={styles.appBar} elevation={0} position="static">
<Toolbar className={clsx(styles.toolbar, toolbarClassName)}>
{shouldShowBackButton ? (
<IconButton
aria-label={__('Go Back')}
className={styles.button}
data-test="back-button"
name="connect-navigation-back-button"
onClick={handleGoBack}
ref={ref ?? defaultRef}
>
<Icon name="arrow_back_ios_new" size={24} />
</IconButton>
) : null}
</Toolbar>
</AppBar>
</Box>
)
})

GoBackButtonHeader.displayName = 'GoBackButtonHeader'
4 changes: 2 additions & 2 deletions src/components/LeavingNoticeFlat.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Text, Icon } from '@mxenabled/mxui'
import { Button, Stack } from '@mui/material'

import { SlideDown } from 'src/components/SlideDown'
import { GoBackButton } from 'src/components/GoBackButton'
import { GoBackButtonHeader } from 'src/components/GoBackButtonHeader'

import { getDelay } from 'src/utilities/getDelay'
import styles from 'src/components/LeavingNoticeFlat.module.css'
Expand All @@ -20,7 +20,7 @@ export const LeavingNoticeFlat = ({ onContinue, onCancel, portalTo = 'connect-wr
<div className={styles.container} role="alert">
<div className={styles.content}>
<SlideDown delay={getNextDelay()}>
<GoBackButton handleGoBack={onCancel} />
<GoBackButtonHeader handleGoBack={onCancel} />
</SlideDown>
<SlideDown delay={getNextDelay()}>
<Stack spacing={2}>
Expand Down
15 changes: 9 additions & 6 deletions src/components/__tests__/GoBackButton-test.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
import React from 'react'
import { render, screen, fireEvent } from 'src/utilities/testingLibrary'
import { GoBackButton } from '../GoBackButton'
import { GoBackButtonHeader } from 'src/components/GoBackButtonHeader'

describe('GoBackButton', () => {
const handleGoBack = vi.fn()
const defaultProps = {
handleGoBack: vi.fn(),
shouldShowBackButton: true,
}

it('renders the go back button', () => {
render(<GoBackButton handleGoBack={handleGoBack} />)
render(<GoBackButtonHeader {...defaultProps} />)
const button = screen.getByRole('button', { name: /back/i })
expect(button).toBeInTheDocument()
})

it('navigates back when clicked', () => {
render(<GoBackButton handleGoBack={handleGoBack} />)
render(<GoBackButtonHeader {...defaultProps} />)
const button = screen.getByRole('button', { name: /back/i })

fireEvent.click(button)
expect(handleGoBack).toHaveBeenCalled()
expect(defaultProps.handleGoBack).toHaveBeenCalled()
})

it('is accessible', () => {
render(<GoBackButton handleGoBack={handleGoBack} />)
render(<GoBackButtonHeader {...defaultProps} />)
const button = screen.getByRole('button', { name: /back/i })
expect(button).toHaveAttribute('aria-label', 'Go Back')
})
Expand Down
4 changes: 2 additions & 2 deletions src/views/microdeposits/SharedRoutingNumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { PageviewInfo } from 'src/const/Analytics'
import { SlideDown } from 'src/components/SlideDown'
import { InstitutionTile } from 'src/components/InstitutionTile'
import { getDelay } from 'src/utilities/getDelay'
import { GoBackButton } from 'src/components/GoBackButton'
import { GoBackButtonHeader } from 'src/components/GoBackButtonHeader'
import { ActionTile } from 'src/components/ActionTile'
import { fadeOut } from 'src/utilities/Animation'

Expand All @@ -29,7 +29,7 @@ export const SharedRoutingNumber = (props) => {
return (
<div ref={containerRef} style={styles.container}>
<SlideDown delay={getNextDelay()}>
<GoBackButton handleGoBack={onGoBack} />
<GoBackButtonHeader handleGoBack={onGoBack} />

<Text component="h2" style={styles.title} truncate={false} variant="H2">
{__('Select how to connect your account')}
Expand Down
Loading
Loading