Simplify column headers (#27557)
This commit is contained in:
		
							parent
							
								
									1f5187e2e2
								
							
						
					
					
						commit
						13d310e64d
					
				| @ -1,6 +1,7 @@ | |||||||
| import { render, fireEvent, screen } from '@testing-library/react'; |  | ||||||
| import renderer from 'react-test-renderer'; | import renderer from 'react-test-renderer'; | ||||||
| 
 | 
 | ||||||
|  | import { render, fireEvent, screen } from 'mastodon/test_helpers'; | ||||||
|  | 
 | ||||||
| import { Button } from '../button'; | import { Button } from '../button'; | ||||||
| 
 | 
 | ||||||
| describe('<Button />', () => { | describe('<Button />', () => { | ||||||
|  | |||||||
| @ -43,28 +43,3 @@ export const ColumnBackButton: React.FC<{ onClick: OnClickCallback }> = ({ | |||||||
| 
 | 
 | ||||||
|   return <ButtonInTabsBar>{component}</ButtonInTabsBar>; |   return <ButtonInTabsBar>{component}</ButtonInTabsBar>; | ||||||
| }; | }; | ||||||
| 
 |  | ||||||
| export const ColumnBackButtonSlim: React.FC<{ onClick: OnClickCallback }> = ({ |  | ||||||
|   onClick, |  | ||||||
| }) => { |  | ||||||
|   const handleClick = useHandleClick(onClick); |  | ||||||
| 
 |  | ||||||
|   return ( |  | ||||||
|     <div className='column-back-button--slim'> |  | ||||||
|       {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */} |  | ||||||
|       <div |  | ||||||
|         role='button' |  | ||||||
|         tabIndex={0} |  | ||||||
|         onClick={handleClick} |  | ||||||
|         className='column-back-button column-back-button--slim-button' |  | ||||||
|       > |  | ||||||
|         <Icon |  | ||||||
|           id='chevron-left' |  | ||||||
|           icon={ArrowBackIcon} |  | ||||||
|           className='column-back-button__icon' |  | ||||||
|         /> |  | ||||||
|         <FormattedMessage id='column_back_button.label' defaultMessage='Back' /> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import { PureComponent } from 'react'; | import { PureComponent, useCallback } from 'react'; | ||||||
| 
 | 
 | ||||||
| import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; | import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; | ||||||
| 
 | 
 | ||||||
| @ -14,9 +14,11 @@ import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/ | |||||||
| import { ReactComponent as TuneIcon } from '@material-symbols/svg-600/outlined/tune.svg'; | import { ReactComponent as TuneIcon } from '@material-symbols/svg-600/outlined/tune.svg'; | ||||||
| 
 | 
 | ||||||
| import { Icon }  from 'mastodon/components/icon'; | import { Icon }  from 'mastodon/components/icon'; | ||||||
| import { ButtonInTabsBar } from 'mastodon/features/ui/util/columns_context'; | import { ButtonInTabsBar, useColumnsContext } from 'mastodon/features/ui/util/columns_context'; | ||||||
| import { WithRouterPropTypes } from 'mastodon/utils/react_router'; | import { WithRouterPropTypes } from 'mastodon/utils/react_router'; | ||||||
| 
 | 
 | ||||||
|  | import { useAppHistory } from './router'; | ||||||
|  | 
 | ||||||
| const messages = defineMessages({ | const messages = defineMessages({ | ||||||
|   show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' }, |   show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' }, | ||||||
|   hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' }, |   hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' }, | ||||||
| @ -24,6 +26,34 @@ const messages = defineMessages({ | |||||||
|   moveRight: { id: 'column_header.moveRight_settings', defaultMessage: 'Move column to the right' }, |   moveRight: { id: 'column_header.moveRight_settings', defaultMessage: 'Move column to the right' }, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | const BackButton = ({ pinned, show }) => { | ||||||
|  |   const history = useAppHistory(); | ||||||
|  |   const { multiColumn } = useColumnsContext(); | ||||||
|  | 
 | ||||||
|  |   const handleBackClick = useCallback(() => { | ||||||
|  |     if (history.location?.state?.fromMastodon) { | ||||||
|  |       history.goBack(); | ||||||
|  |     } else { | ||||||
|  |       history.push('/'); | ||||||
|  |     } | ||||||
|  |   }, [history]); | ||||||
|  | 
 | ||||||
|  |   const showButton = history && !pinned && ((multiColumn && history.location?.state?.fromMastodon) || show); | ||||||
|  | 
 | ||||||
|  |   if(!showButton) return null; | ||||||
|  | 
 | ||||||
|  |   return (<button onClick={handleBackClick} className='column-header__back-button'> | ||||||
|  |     <Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' /> | ||||||
|  |     <FormattedMessage id='column_back_button.label' defaultMessage='Back' /> | ||||||
|  |   </button>); | ||||||
|  | 
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | BackButton.propTypes = { | ||||||
|  |   pinned: PropTypes.bool, | ||||||
|  |   show: PropTypes.bool, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class ColumnHeader extends PureComponent { | class ColumnHeader extends PureComponent { | ||||||
| 
 | 
 | ||||||
|   static contextTypes = { |   static contextTypes = { | ||||||
| @ -72,16 +102,6 @@ class ColumnHeader extends PureComponent { | |||||||
|     this.props.onMove(1); |     this.props.onMove(1); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   handleBackClick = () => { |  | ||||||
|     const { history } = this.props; |  | ||||||
| 
 |  | ||||||
|     if (history.location?.state?.fromMastodon) { |  | ||||||
|       history.goBack(); |  | ||||||
|     } else { |  | ||||||
|       history.push('/'); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   handleTransitionEnd = () => { |   handleTransitionEnd = () => { | ||||||
|     this.setState({ animating: false }); |     this.setState({ animating: false }); | ||||||
|   }; |   }; | ||||||
| @ -95,7 +115,7 @@ class ColumnHeader extends PureComponent { | |||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   render () { |   render () { | ||||||
|     const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues, history } = this.props; |     const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues } = this.props; | ||||||
|     const { collapsed, animating } = this.state; |     const { collapsed, animating } = this.state; | ||||||
| 
 | 
 | ||||||
|     const wrapperClassName = classNames('column-header__wrapper', { |     const wrapperClassName = classNames('column-header__wrapper', { | ||||||
| @ -138,14 +158,7 @@ class ColumnHeader extends PureComponent { | |||||||
|       pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' icon={AddIcon} /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>; |       pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' icon={AddIcon} /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (!pinned && ((multiColumn && history.location?.state?.fromMastodon) || showBackButton)) { |     backButton = <BackButton pinned={pinned} show={showBackButton} />; | ||||||
|       backButton = ( |  | ||||||
|         <button onClick={this.handleBackClick} className='column-header__back-button'> |  | ||||||
|           <Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' /> |  | ||||||
|           <FormattedMessage id='column_back_button.label' defaultMessage='Back' /> |  | ||||||
|         </button> |  | ||||||
|       ); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     const collapsedContent = [ |     const collapsedContent = [ | ||||||
|       extraContent, |       extraContent, | ||||||
|  | |||||||
| @ -10,7 +10,6 @@ import { ReactComponent as BlockIcon } from '@material-symbols/svg-600/outlined/ | |||||||
| import { debounce } from 'lodash'; | import { debounce } from 'lodash'; | ||||||
| 
 | 
 | ||||||
| import { fetchBlocks, expandBlocks } from '../../actions/blocks'; | import { fetchBlocks, expandBlocks } from '../../actions/blocks'; | ||||||
| import { ColumnBackButtonSlim } from '../../components/column_back_button'; |  | ||||||
| import { LoadingIndicator } from '../../components/loading_indicator'; | import { LoadingIndicator } from '../../components/loading_indicator'; | ||||||
| import ScrollableList from '../../components/scrollable_list'; | import ScrollableList from '../../components/scrollable_list'; | ||||||
| import AccountContainer from '../../containers/account_container'; | import AccountContainer from '../../containers/account_container'; | ||||||
| @ -60,8 +59,7 @@ class Blocks extends ImmutablePureComponent { | |||||||
|     const emptyMessage = <FormattedMessage id='empty_column.blocks' defaultMessage="You haven't blocked any users yet." />; |     const emptyMessage = <FormattedMessage id='empty_column.blocks' defaultMessage="You haven't blocked any users yet." />; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)}> |       <Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton> | ||||||
|         <ColumnBackButtonSlim /> |  | ||||||
|         <ScrollableList |         <ScrollableList | ||||||
|           scrollKey='blocks' |           scrollKey='blocks' | ||||||
|           onLoadMore={this.handleLoadMore} |           onLoadMore={this.handleLoadMore} | ||||||
|  | |||||||
| @ -12,7 +12,6 @@ import { ReactComponent as BlockIcon } from '@material-symbols/svg-600/outlined/ | |||||||
| import { debounce } from 'lodash'; | import { debounce } from 'lodash'; | ||||||
| 
 | 
 | ||||||
| import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks'; | import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks'; | ||||||
| import { ColumnBackButtonSlim } from '../../components/column_back_button'; |  | ||||||
| import { LoadingIndicator } from '../../components/loading_indicator'; | import { LoadingIndicator } from '../../components/loading_indicator'; | ||||||
| import ScrollableList from '../../components/scrollable_list'; | import ScrollableList from '../../components/scrollable_list'; | ||||||
| import DomainContainer from '../../containers/domain_container'; | import DomainContainer from '../../containers/domain_container'; | ||||||
| @ -61,9 +60,7 @@ class Blocks extends ImmutablePureComponent { | |||||||
|     const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no blocked domains yet.' />; |     const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no blocked domains yet.' />; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)}> |       <Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton> | ||||||
|         <ColumnBackButtonSlim /> |  | ||||||
| 
 |  | ||||||
|         <ScrollableList |         <ScrollableList | ||||||
|           scrollKey='domain_blocks' |           scrollKey='domain_blocks' | ||||||
|           onLoadMore={this.handleLoadMore} |           onLoadMore={this.handleLoadMore} | ||||||
|  | |||||||
| @ -12,7 +12,6 @@ import { ReactComponent as PersonAddIcon } from '@material-symbols/svg-600/outli | |||||||
| import { debounce } from 'lodash'; | import { debounce } from 'lodash'; | ||||||
| 
 | 
 | ||||||
| import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts'; | import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts'; | ||||||
| import { ColumnBackButtonSlim } from '../../components/column_back_button'; |  | ||||||
| import ScrollableList from '../../components/scrollable_list'; | import ScrollableList from '../../components/scrollable_list'; | ||||||
| import { me } from '../../initial_state'; | import { me } from '../../initial_state'; | ||||||
| import Column from '../ui/components/column'; | import Column from '../ui/components/column'; | ||||||
| @ -68,8 +67,7 @@ class FollowRequests extends ImmutablePureComponent { | |||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <Column bindToDocument={!multiColumn} icon='user-plus' iconComponent={PersonAddIcon} heading={intl.formatMessage(messages.heading)}> |       <Column bindToDocument={!multiColumn} icon='user-plus' iconComponent={PersonAddIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton> | ||||||
|         <ColumnBackButtonSlim /> |  | ||||||
|         <ScrollableList |         <ScrollableList | ||||||
|           scrollKey='follow_requests' |           scrollKey='follow_requests' | ||||||
|           onLoadMore={this.handleLoadMore} |           onLoadMore={this.handleLoadMore} | ||||||
|  | |||||||
| @ -12,7 +12,6 @@ import { ReactComponent as VolumeOffIcon } from '@material-symbols/svg-600/outli | |||||||
| import { debounce } from 'lodash'; | import { debounce } from 'lodash'; | ||||||
| 
 | 
 | ||||||
| import { fetchMutes, expandMutes } from '../../actions/mutes'; | import { fetchMutes, expandMutes } from '../../actions/mutes'; | ||||||
| import { ColumnBackButtonSlim } from '../../components/column_back_button'; |  | ||||||
| import { LoadingIndicator } from '../../components/loading_indicator'; | import { LoadingIndicator } from '../../components/loading_indicator'; | ||||||
| import ScrollableList from '../../components/scrollable_list'; | import ScrollableList from '../../components/scrollable_list'; | ||||||
| import AccountContainer from '../../containers/account_container'; | import AccountContainer from '../../containers/account_container'; | ||||||
| @ -62,8 +61,7 @@ class Mutes extends ImmutablePureComponent { | |||||||
|     const emptyMessage = <FormattedMessage id='empty_column.mutes' defaultMessage="You haven't muted any users yet." />; |     const emptyMessage = <FormattedMessage id='empty_column.mutes' defaultMessage="You haven't muted any users yet." />; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <Column bindToDocument={!multiColumn} icon='volume-off' iconComponent={VolumeOffIcon} heading={intl.formatMessage(messages.heading)}> |       <Column bindToDocument={!multiColumn} icon='volume-off' iconComponent={VolumeOffIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton> | ||||||
|         <ColumnBackButtonSlim /> |  | ||||||
|         <ScrollableList |         <ScrollableList | ||||||
|           scrollKey='mutes' |           scrollKey='mutes' | ||||||
|           onLoadMore={this.handleLoadMore} |           onLoadMore={this.handleLoadMore} | ||||||
|  | |||||||
| @ -13,7 +13,6 @@ import { ReactComponent as PushPinIcon } from '@material-symbols/svg-600/outline | |||||||
| import { getStatusList } from 'mastodon/selectors'; | import { getStatusList } from 'mastodon/selectors'; | ||||||
| 
 | 
 | ||||||
| import { fetchPinnedStatuses } from '../../actions/pin_statuses'; | import { fetchPinnedStatuses } from '../../actions/pin_statuses'; | ||||||
| import { ColumnBackButtonSlim } from '../../components/column_back_button'; |  | ||||||
| import StatusList from '../../components/status_list'; | import StatusList from '../../components/status_list'; | ||||||
| import Column from '../ui/components/column'; | import Column from '../ui/components/column'; | ||||||
| 
 | 
 | ||||||
| @ -52,8 +51,7 @@ class PinnedStatuses extends ImmutablePureComponent { | |||||||
|     const { intl, statusIds, hasMore, multiColumn } = this.props; |     const { intl, statusIds, hasMore, multiColumn } = this.props; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <Column bindToDocument={!multiColumn} icon='thumb-tack' iconComponent={PushPinIcon} heading={intl.formatMessage(messages.heading)} ref={this.setRef}> |       <Column bindToDocument={!multiColumn} icon='thumb-tack' iconComponent={PushPinIcon} heading={intl.formatMessage(messages.heading)} ref={this.setRef} alwaysShowBackButton> | ||||||
|         <ColumnBackButtonSlim /> |  | ||||||
|         <StatusList |         <StatusList | ||||||
|           statusIds={statusIds} |           statusIds={statusIds} | ||||||
|           scrollKey='pinned_statuses' |           scrollKey='pinned_statuses' | ||||||
|  | |||||||
| @ -1,13 +1,15 @@ | |||||||
| import { render, fireEvent, screen } from '@testing-library/react'; | import { render, fireEvent, screen } from 'mastodon/test_helpers'; | ||||||
| 
 | 
 | ||||||
| import Column from '../column'; | import Column from '../column'; | ||||||
| 
 | 
 | ||||||
|  | const fakeIcon = () => <span />; | ||||||
|  | 
 | ||||||
| describe('<Column />', () => { | describe('<Column />', () => { | ||||||
|   describe('<ColumnHeader /> click handler', () => { |   describe('<ColumnHeader /> click handler', () => { | ||||||
|     it('runs the scroll animation if the column contains scrollable content', () => { |     it('runs the scroll animation if the column contains scrollable content', () => { | ||||||
|       const scrollToMock = jest.fn(); |       const scrollToMock = jest.fn(); | ||||||
|       const { container } = render( |       const { container } = render( | ||||||
|         <Column heading='notifications'> |         <Column heading='notifications' icon='notifications' iconComponent={fakeIcon}> | ||||||
|           <div className='scrollable' /> |           <div className='scrollable' /> | ||||||
|         </Column>, |         </Column>, | ||||||
|       ); |       ); | ||||||
| @ -17,7 +19,7 @@ describe('<Column />', () => { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it('does not try to scroll if there is no scrollable content', () => { |     it('does not try to scroll if there is no scrollable content', () => { | ||||||
|       render(<Column heading='notifications' />); |       render(<Column heading='notifications' icon='notifications' iconComponent={fakeIcon} />); | ||||||
|       fireEvent.click(screen.getByText('notifications')); |       fireEvent.click(screen.getByText('notifications')); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|  | |||||||
| @ -3,15 +3,15 @@ import { PureComponent } from 'react'; | |||||||
| 
 | 
 | ||||||
| import { debounce } from 'lodash'; | import { debounce } from 'lodash'; | ||||||
| 
 | 
 | ||||||
|  | import ColumnHeader from '../../../components/column_header'; | ||||||
| import { isMobile } from '../../../is_mobile'; | import { isMobile } from '../../../is_mobile'; | ||||||
| import { scrollTop } from '../../../scroll'; | import { scrollTop } from '../../../scroll'; | ||||||
| 
 | 
 | ||||||
| import ColumnHeader from './column_header'; |  | ||||||
| 
 |  | ||||||
| export default class Column extends PureComponent { | export default class Column extends PureComponent { | ||||||
| 
 | 
 | ||||||
|   static propTypes = { |   static propTypes = { | ||||||
|     heading: PropTypes.string, |     heading: PropTypes.string, | ||||||
|  |     alwaysShowBackButton: PropTypes.bool, | ||||||
|     icon: PropTypes.string, |     icon: PropTypes.string, | ||||||
|     iconComponent: PropTypes.func, |     iconComponent: PropTypes.func, | ||||||
|     children: PropTypes.node, |     children: PropTypes.node, | ||||||
| @ -51,13 +51,14 @@ export default class Column extends PureComponent { | |||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   render () { |   render () { | ||||||
|     const { heading, icon, iconComponent, children, active, hideHeadingOnMobile } = this.props; |     const { heading, icon, iconComponent, children, active, hideHeadingOnMobile, alwaysShowBackButton } = this.props; | ||||||
| 
 | 
 | ||||||
|     const showHeading = heading && (!hideHeadingOnMobile || (hideHeadingOnMobile && !isMobile(window.innerWidth))); |     const showHeading = heading && (!hideHeadingOnMobile || (hideHeadingOnMobile && !isMobile(window.innerWidth))); | ||||||
| 
 | 
 | ||||||
|     const columnHeaderId = showHeading && heading.replace(/ /g, '-'); |     const columnHeaderId = showHeading && heading.replace(/ /g, '-'); | ||||||
|  | 
 | ||||||
|     const header = showHeading && ( |     const header = showHeading && ( | ||||||
|       <ColumnHeader icon={icon} iconComponent={iconComponent} active={active} type={heading} onClick={this.handleHeaderClick} columnHeaderId={columnHeaderId} /> |       <ColumnHeader icon={icon} iconComponent={iconComponent} active={active} title={heading} onClick={this.handleHeaderClick} columnHeaderId={columnHeaderId} showBackButton={alwaysShowBackButton} /> | ||||||
|     ); |     ); | ||||||
|     return ( |     return ( | ||||||
|       <div |       <div | ||||||
|  | |||||||
| @ -1,41 +0,0 @@ | |||||||
| import PropTypes from 'prop-types'; |  | ||||||
| import { PureComponent } from 'react'; |  | ||||||
| 
 |  | ||||||
| import classNames from 'classnames'; |  | ||||||
| 
 |  | ||||||
| import { Icon }  from 'mastodon/components/icon'; |  | ||||||
| 
 |  | ||||||
| export default class ColumnHeader extends PureComponent { |  | ||||||
| 
 |  | ||||||
|   static propTypes = { |  | ||||||
|     icon: PropTypes.string, |  | ||||||
|     iconComponent: PropTypes.func, |  | ||||||
|     type: PropTypes.string, |  | ||||||
|     active: PropTypes.bool, |  | ||||||
|     onClick: PropTypes.func, |  | ||||||
|     columnHeaderId: PropTypes.string, |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   handleClick = () => { |  | ||||||
|     this.props.onClick(); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   render () { |  | ||||||
|     const { icon, iconComponent, type, active, columnHeaderId } = this.props; |  | ||||||
|     let iconElement = ''; |  | ||||||
| 
 |  | ||||||
|     if (icon) { |  | ||||||
|       iconElement = <Icon id={icon} icon={iconComponent} className='column-header__icon' />; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return ( |  | ||||||
|       <h1 className={classNames('column-header', { active })} id={columnHeaderId || null}> |  | ||||||
|         <button onClick={this.handleClick}> |  | ||||||
|           {iconElement} |  | ||||||
|           {type} |  | ||||||
|         </button> |  | ||||||
|       </h1> |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
							
								
								
									
										62
									
								
								app/javascript/mastodon/test_helpers.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								app/javascript/mastodon/test_helpers.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | |||||||
|  | import PropTypes from 'prop-types'; | ||||||
|  | import type { PropsWithChildren } from 'react'; | ||||||
|  | import { Component } from 'react'; | ||||||
|  | 
 | ||||||
|  | import { IntlProvider } from 'react-intl'; | ||||||
|  | 
 | ||||||
|  | import { MemoryRouter } from 'react-router'; | ||||||
|  | 
 | ||||||
|  | // eslint-disable-next-line import/no-extraneous-dependencies
 | ||||||
|  | import { render as rtlRender } from '@testing-library/react'; | ||||||
|  | 
 | ||||||
|  | class FakeIdentityWrapper extends Component< | ||||||
|  |   PropsWithChildren<{ signedIn: boolean }> | ||||||
|  | > { | ||||||
|  |   static childContextTypes = { | ||||||
|  |     identity: PropTypes.shape({ | ||||||
|  |       signedIn: PropTypes.bool.isRequired, | ||||||
|  |       accountId: PropTypes.string, | ||||||
|  |       disabledAccountId: PropTypes.string, | ||||||
|  |       accessToken: PropTypes.string, | ||||||
|  |     }).isRequired, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   getChildContext() { | ||||||
|  |     return { | ||||||
|  |       identity: { | ||||||
|  |         signedIn: this.props.signedIn, | ||||||
|  |         accountId: '123', | ||||||
|  |         accessToken: 'test-access-token', | ||||||
|  |       }, | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   render() { | ||||||
|  |     return this.props.children; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function render( | ||||||
|  |   ui: React.ReactElement, | ||||||
|  |   { locale = 'en', signedIn = true, ...renderOptions } = {}, | ||||||
|  | ) { | ||||||
|  |   const Wrapper = (props: { children: React.ReactElement }) => { | ||||||
|  |     return ( | ||||||
|  |       <MemoryRouter> | ||||||
|  |         <IntlProvider locale={locale}> | ||||||
|  |           <FakeIdentityWrapper signedIn={signedIn}> | ||||||
|  |             {props.children} | ||||||
|  |           </FakeIdentityWrapper> | ||||||
|  |         </IntlProvider> | ||||||
|  |       </MemoryRouter> | ||||||
|  |     ); | ||||||
|  |   }; | ||||||
|  |   return rtlRender(ui, { wrapper: Wrapper, ...renderOptions }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // re-export everything
 | ||||||
|  | // eslint-disable-next-line import/no-extraneous-dependencies
 | ||||||
|  | export * from '@testing-library/react'; | ||||||
|  | 
 | ||||||
|  | // override render method
 | ||||||
|  | export { render }; | ||||||
| @ -3137,20 +3137,6 @@ $ui-header-height: 55px; | |||||||
|   margin-inline-end: 5px; |   margin-inline-end: 5px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .column-back-button--slim { |  | ||||||
|   position: relative; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .column-back-button--slim-button { |  | ||||||
|   cursor: pointer; |  | ||||||
|   flex: 0 0 auto; |  | ||||||
|   font-size: 16px; |  | ||||||
|   padding: 15px; |  | ||||||
|   position: absolute; |  | ||||||
|   inset-inline-end: 0; |  | ||||||
|   top: -50px; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .react-toggle { | .react-toggle { | ||||||
|   display: inline-block; |   display: inline-block; | ||||||
|   position: relative; |   position: relative; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user