Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
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 { GoBackButton } from 'src/components/GoBackButton'
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>
<GoBackButton
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%;
}
55 changes: 18 additions & 37 deletions src/components/DayOfMonthPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ 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'
Expand All @@ -12,6 +11,7 @@ import { __ } from 'src/utilities/Intl'
import { GoBackButton } from 'src/components/GoBackButton'
import { SlideDown } from 'src/components/SlideDown'
import { getDelay } from 'src/utilities/getDelay'
import styles from 'src/components/DayOfMonthPicker.module.css'

interface DayOfMonthPicker {
handleClose: () => void
Expand All @@ -21,8 +21,6 @@ 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>
Expand All @@ -35,59 +33,42 @@ export const DayOfMonthPicker = React.forwardRef<HTMLInputElement, DayOfMonthPic
/>
</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'
19 changes: 19 additions & 0 deletions src/components/GoBackButton.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.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;
padding: 0 var(--spacing-2);
transform: translateX(-5%);
}

.button:global(.MuiIconButton-root) {
color: var(--mui-palette-text-primary);
}
60 changes: 27 additions & 33 deletions src/components/GoBackButton.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,42 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { forwardRef, useRef } from 'react'
import PropTypes from 'prop-types'
import { useTokens } from '@kyper/tokenprovider'
import { IconButton } from '@mui/material'
import { ChevronLeft } from '@kyper/icon/ChevronLeft'
import { AppBar, Box, IconButton, Toolbar } from '@mui/material'
import { Icon } from '@mxenabled/mxui'

import { __ } from 'src/utilities/Intl'
import styles from 'src/components/GoBackButton.module.css'

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

export const GoBackButton = forwardRef<HTMLButtonElement, GoBackButtonProps>((props, ref) => {
const defaultRef = useRef(null)
const { handleGoBack } = props
const tokens = useTokens()
const styles = getStyles(tokens)
const { handleGoBack, shouldShowBackButton = true, toolbarClassName } = props

return (
<IconButton
aria-label={__('Go Back')}
data-test="back-button"
onClick={handleGoBack}
ref={ref ?? defaultRef}
style={styles}
>
<ChevronLeft
color={tokens.TextColor.Default}
height={tokens.Spacing.Large}
width={tokens.Spacing.Large}
/>
</IconButton>
<Box className={styles.container} data-test="navigation-header">
<AppBar className={styles.appBar} elevation={0} position="static">
<Toolbar
className={[styles.toolbar, toolbarClassName].filter(Boolean).join(' ')}
disableGutters={true}
>
{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} />
Comment thread
mwclemy marked this conversation as resolved.
</IconButton>
) : null}
</Toolbar>
</AppBar>
</Box>
)
})

const getStyles = (tokens: any) => ({
height: '44px',
margin: `0px ${tokens.Spacing.XSmall}px ${tokens.Spacing.XSmall}px -${tokens.Spacing.Medium}px`,
padding: `0px 8px`,
width: '44px',
})

GoBackButton.propTypes = {
handleGoBack: PropTypes.func.isRequired,
}

GoBackButton.displayName = 'GoBackButton'
13 changes: 8 additions & 5 deletions src/components/__tests__/GoBackButton-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,27 @@ import { render, screen, fireEvent } from 'src/utilities/testingLibrary'
import { GoBackButton } from '../GoBackButton'

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

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

it('navigates back when clicked', () => {
render(<GoBackButton handleGoBack={handleGoBack} />)
render(<GoBackButton {...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(<GoBackButton {...defaultProps} />)
const button = screen.getByRole('button', { name: /back/i })
expect(button).toHaveAttribute('aria-label', 'Go Back')
})
Expand Down
1 change: 0 additions & 1 deletion typings/kyper.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ declare module '@kyper/icon/Image'
declare module '@kyper/icon/Health'
declare module '@kyper/icon/Grid'
declare module '@kyper/progressindicators'
declare module '@kyper/icon/ChevronLeft'
declare module '@kyper/icon/Lock'
declare module '@kyper/utilityrow'
declare module '@kyper/hooks'
Expand Down
Loading