better support for rtl languages (#170)

* set text direction on language load and change to rtl if arabic is chosen

see https://www.w3schools.com/tags/att_global_dir.asp

* minor fixes to make rtl-mode look good:
- margins not only on the right, but on both sides
- fix bootstrap ToggleButtonGroup to always be ltr

* removed console.log statements

* fixed margin on the name in the user-avatar

* '$Icon CodiMD' on the intro page now always uses ftr text direction, since we don't translate the same of the software

* fixed import

* removed setHTMLDirection function

* added toplevel div with dir='auto'
some elements got dir='auto' if they contain potentially not translated or intended english text

* added text-align: start to the user-dropdown

* moved toplevel dir='auto'

* moved shortenLanguageCode to language-picker

* Changed mr-2 to mx-2 for profile buttons

Co-authored-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
Philip Molares 2020-06-08 23:49:14 +02:00 committed by GitHub
parent 235b24b49c
commit 7794538c6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 29 additions and 22 deletions

View file

@ -17,6 +17,6 @@
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root" dir="auto"></div>
</body> </body>
</html> </html>

View file

@ -8,7 +8,9 @@ export const ExternalLink: React.FC<LinkWithTextProps> = ({ href, text, icon, cl
<a href={href} <a href={href}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className={className}> className={className}
dir='auto'
>
<ShowIf condition={!!icon}> <ShowIf condition={!!icon}>
<ForkAwesomeIcon icon={icon as IconName} fixedWidth={true}/>&nbsp; <ForkAwesomeIcon icon={icon as IconName} fixedWidth={true}/>&nbsp;
</ShowIf> </ShowIf>

View file

@ -58,7 +58,7 @@ export const PagerPagination: React.FC<PaginationProps> = ({ numberOfPageButtons
}) })
return ( return (
<Pagination> <Pagination dir='ltr'>
<ShowIf condition={correctedLowerPageIndex > 0}> <ShowIf condition={correctedLowerPageIndex > 0}>
<PagerItem key={0} index={0} onClick={setPageIndex}/> <PagerItem key={0} index={0} onClick={setPageIndex}/>
<Pagination.Ellipsis disabled/> <Pagination.Ellipsis disabled/>

View file

@ -7,8 +7,9 @@ const LanguagePicker: React.FC = () => {
const { i18n } = useTranslation() const { i18n } = useTranslation()
const onChangeLang = async (event: React.ChangeEvent<HTMLSelectElement>) => { const onChangeLang = async (event: React.ChangeEvent<HTMLSelectElement>) => {
moment.locale(event.currentTarget.value) const language = event.currentTarget.value
await i18n.changeLanguage(event.currentTarget.value) moment.locale(language)
await i18n.changeLanguage(language)
} }
const shortenLanguageCode = (language: string): string => { const shortenLanguageCode = (language: string): string => {

View file

@ -27,13 +27,13 @@ const HeaderBar: React.FC = () => {
<div className="d-inline-flex"> <div className="d-inline-flex">
{!user {!user
? <Fragment> ? <Fragment>
<span className={'mr-1 d-flex'}> <span className={'mx-1 d-flex'}>
<NewGuestNoteButton/> <NewGuestNoteButton/>
</span> </span>
<SignInButton size="sm"/> <SignInButton size="sm"/>
</Fragment> </Fragment>
: <Fragment> : <Fragment>
<span className={'mr-1 d-flex'}> <span className={'mx-1 d-flex'}>
<NewUserNoteButton/> <NewUserNoteButton/>
</span> </span>
<UserDropdown/> <UserDropdown/>

View file

@ -12,7 +12,7 @@ export const NewGuestNoteButton: React.FC = () => {
variant="primary" variant="primary"
size="sm" size="sm"
className="d-inline-flex align-items-center"> className="d-inline-flex align-items-center">
<ForkAwesomeIcon icon="plus" className="mr-1"/> <ForkAwesomeIcon icon="plus" className="mx-1"/>
<span> <span>
<Trans i18nKey='landing.navigation.newGuestNote'/> <Trans i18nKey='landing.navigation.newGuestNote'/>
</span> </span>

View file

@ -12,7 +12,7 @@ export const NewUserNoteButton: React.FC = () => {
variant="primary" variant="primary"
size="sm" size="sm"
className="d-inline-flex align-items-center"> className="d-inline-flex align-items-center">
<ForkAwesomeIcon icon="plus" className="mr-1"/> <ForkAwesomeIcon icon="plus" className="mx-1"/>
<span> <span>
<Trans i18nKey='landing.navigation.newNote'/> <Trans i18nKey='landing.navigation.newNote'/>
</span> </span>

View file

@ -22,24 +22,24 @@ export const UserDropdown: React.FC = () => {
<UserAvatar name={user.name} photo={user.photo}/> <UserAvatar name={user.name} photo={user.photo}/>
</Dropdown.Toggle> </Dropdown.Toggle>
<Dropdown.Menu> <Dropdown.Menu className='text-start'>
<LinkContainer to={'/features'}> <LinkContainer to={'/features'}>
<Dropdown.Item> <Dropdown.Item dir='auto'>
<ForkAwesomeIcon icon="bolt" fixedWidth={true} className="mr-2"/> <ForkAwesomeIcon icon="bolt" fixedWidth={true} className="mx-2"/>
<Trans i18nKey="editor.help.documents.features"/> <Trans i18nKey="editor.help.documents.features"/>
</Dropdown.Item> </Dropdown.Item>
</LinkContainer> </LinkContainer>
<LinkContainer to={'/profile'}> <LinkContainer to={'/profile'}>
<Dropdown.Item> <Dropdown.Item dir='auto'>
<ForkAwesomeIcon icon="user" fixedWidth={true} className="mr-2"/> <ForkAwesomeIcon icon="user" fixedWidth={true} className="mx-2"/>
<Trans i18nKey="profile.userProfile"/> <Trans i18nKey="profile.userProfile"/>
</Dropdown.Item> </Dropdown.Item>
</LinkContainer> </LinkContainer>
<Dropdown.Item <Dropdown.Item dir='auto'
onClick={() => { onClick={() => {
clearUser() clearUser()
}}> }}>
<ForkAwesomeIcon icon="sign-out" fixedWidth={true} className="mr-2"/> <ForkAwesomeIcon icon="sign-out" fixedWidth={true} className="mx-2"/>
<Trans i18nKey="login.signOut"/> <Trans i18nKey="login.signOut"/>
</Dropdown.Item> </Dropdown.Item>
</Dropdown.Menu> </Dropdown.Menu>

View file

@ -16,7 +16,7 @@ const UserAvatar: React.FC<UserAvatarProps> = ({ name, photo, additionalClasses
className="user-avatar" className="user-avatar"
alt={`Avatar of ${name}`} alt={`Avatar of ${name}`}
/> />
<span className="ml-1 user-name">{name}</span> <span className="mx-1 user-name">{name}</span>
</span> </span>
) )
} }

View file

@ -114,7 +114,7 @@ export const HistoryToolbar: React.FC<HistoryToolbarProps> = ({ onSettingsChange
</Button> </Button>
</InputGroup> </InputGroup>
<InputGroup className={'mr-1 mb-1'}> <InputGroup className={'mr-1 mb-1'}>
<ToggleButtonGroup type="radio" name="options" value={state.viewState} className={'button-height'} <ToggleButtonGroup type="radio" name="options" dir='ltr' value={state.viewState} className={'button-height'}
onChange={(newViewState: ViewStateEnum) => { onChange={(newViewState: ViewStateEnum) => {
toggleViewChanged(newViewState) toggleViewChanged(newViewState)
}}> }}>

View file

@ -10,7 +10,7 @@ const Intro: React.FC = () => {
return ( return (
<div> <div>
<h1> <h1 dir='auto'>
<ForkAwesomeIcon icon="file-text"/> CodiMD <ForkAwesomeIcon icon="file-text"/> CodiMD
</h1> </h1>
<p className="lead mb-5"> <p className="lead mb-5">

View file

@ -58,11 +58,11 @@ export const ProfileAccountManagement: React.FC = () => {
<Card.Body> <Card.Body>
<Card.Title><Trans i18nKey="profile.accountManagement"/></Card.Title> <Card.Title><Trans i18nKey="profile.accountManagement"/></Card.Title>
<Button variant="secondary" block href={getBackendUrl() + '/me/export'} className="mb-2"> <Button variant="secondary" block href={getBackendUrl() + '/me/export'} className="mb-2">
<ForkAwesomeIcon icon="cloud-download" fixedWidth={true} className="mr-2"/> <ForkAwesomeIcon icon="cloud-download" fixedWidth={true} className="mx-2"/>
<Trans i18nKey="profile.exportUserData"/> <Trans i18nKey="profile.exportUserData"/>
</Button> </Button>
<Button variant="danger" block onClick={handleModalOpen}> <Button variant="danger" block onClick={handleModalOpen}>
<ForkAwesomeIcon icon="trash" fixedWidth={true} className="mr-2"/> <ForkAwesomeIcon icon="trash" fixedWidth={true} className="mx-2"/>
<Trans i18nKey="profile.deleteUser"/> <Trans i18nKey="profile.deleteUser"/>
</Button> </Button>
</Card.Body> </Card.Body>
@ -70,7 +70,7 @@ export const ProfileAccountManagement: React.FC = () => {
<Modal show={showDeleteModal} onHide={handleModalClose} animation={true}> <Modal show={showDeleteModal} onHide={handleModalClose} animation={true}>
<Modal.Body className="text-dark"> <Modal.Body className="text-dark">
<h3><Trans i18nKey="profile.modal.deleteUser.message"/></h3> <h3 dir="auto"><Trans i18nKey="profile.modal.deleteUser.message"/></h3>
<Trans i18nKey="profile.modal.deleteUser.subMessage"/> <Trans i18nKey="profile.modal.deleteUser.subMessage"/>
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>

View file

@ -23,3 +23,7 @@ body {
.fa.fa-fix-line-height { .fa.fa-fix-line-height {
line-height: inherit; line-height: inherit;
} }
.text-start {
text-align: start;
}