mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-23 18:26:32 -05:00
fix: deduplicate different buttons
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
160f0f8297
commit
aa6bd2a884
12 changed files with 44 additions and 194 deletions
|
@ -21,8 +21,8 @@ describe('Languages', () => {
|
|||
|
||||
it('language changes affect the UI', () => {
|
||||
cy.getByCypressId('language-picker').select('English')
|
||||
cy.getByCypressId('new-note-button').find('span').contains('New note')
|
||||
cy.getByCypressId('new-note-button').contains('New Note')
|
||||
cy.getByCypressId('language-picker').select('Deutsch')
|
||||
cy.getByCypressId('new-note-button').find('span').contains('Neue Notiz')
|
||||
cy.getByCypressId('new-note-button').contains('Neue Notiz')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
"slogan": "Der beste Weg, Notizen zu schreiben und teilen.",
|
||||
"title": "Gemeinschaftliche Markdown Notizen"
|
||||
},
|
||||
"navigation": {
|
||||
"newNote": "Neue Notiz"
|
||||
},
|
||||
"landing": {
|
||||
"intro": {
|
||||
"exploreFeatures": "Alle Funktionen",
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
"title": "Test",
|
||||
"content": "It works!"
|
||||
},
|
||||
"navigation": {
|
||||
"newNote": "New Note"
|
||||
},
|
||||
"renderer": {
|
||||
"highlightCode": {
|
||||
"copyCode": "Copy code to clipboard"
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
import { IconButton } from '../icon-button/icon-button'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import { FileEarmarkPlus as IconPlus } from 'react-bootstrap-icons'
|
||||
import { Trans } from 'react-i18next'
|
||||
|
||||
/**
|
||||
* Links to the "new note" endpoint
|
||||
*/
|
||||
export const NewNoteButton: React.FC = () => {
|
||||
return (
|
||||
<Link href={'/new'} passHref={true}>
|
||||
<IconButton {...cypressId('new-note-button')} iconSize={1.5} size={'sm'} icon={IconPlus}>
|
||||
<Trans i18nKey='navigation.newNote' />
|
||||
</IconButton>
|
||||
</Link>
|
||||
)
|
||||
}
|
|
@ -5,13 +5,13 @@
|
|||
*/
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { NoteType } from '../../../redux/note-details/types/note-details'
|
||||
import { NewNoteButton } from '../../common/new-note-button/new-note-button'
|
||||
import { ShowIf } from '../../common/show-if/show-if'
|
||||
import { SignInButton } from '../../landing-layout/navigation/sign-in-button'
|
||||
import { UserDropdown } from '../../landing-layout/navigation/user-dropdown'
|
||||
import { SettingsButton } from '../../layout/settings-dialog/settings-button'
|
||||
import { HelpButton } from './help-button/help-button'
|
||||
import { NavbarBranding } from './navbar-branding'
|
||||
import { NewNoteButton } from './new-note-button'
|
||||
import { ReadOnlyModeButton } from './read-only-mode-button'
|
||||
import { SlideModeButton } from './slide-mode-button'
|
||||
import React from 'react'
|
||||
|
@ -49,8 +49,8 @@ export const AppBar: React.FC<AppBarProps> = ({ mode }) => {
|
|||
<HelpButton />
|
||||
</ShowIf>
|
||||
</Nav>
|
||||
<Nav className='d-flex align-items-center text-secondary justify-content-end'>
|
||||
<SettingsButton className={'p-1 mx-2'} variant={'outline-dark'} />
|
||||
<Nav className='d-flex gap-2 align-items-center text-secondary justify-content-end'>
|
||||
<SettingsButton variant={'outline-dark'} />
|
||||
<NewNoteButton />
|
||||
<ShowIf condition={!userExists}>
|
||||
<SignInButton size={'sm'} />
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { IconButton } from '../../common/icon-button/icon-button'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import { Plus as IconPlus } from 'react-bootstrap-icons'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
|
||||
/**
|
||||
* Renders a button to create a new note.
|
||||
*/
|
||||
export const NewNoteButton: React.FC = () => {
|
||||
useTranslation()
|
||||
|
||||
return (
|
||||
<Link href={'/new'} passHref={true}>
|
||||
<IconButton className='mx-2' iconSize={1.5} icon={IconPlus}>
|
||||
<Trans i18nKey='editor.appBar.new' />
|
||||
</IconButton>
|
||||
</Link>
|
||||
)
|
||||
}
|
|
@ -5,13 +5,12 @@
|
|||
*/
|
||||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
import { NewNoteButton } from '../../../common/new-note-button/new-note-button'
|
||||
import { SettingsButton } from '../../../layout/settings-dialog/settings-button'
|
||||
import { NewGuestNoteButton } from '../new-guest-note-button'
|
||||
import { NewUserNoteButton } from '../new-user-note-button'
|
||||
import { SignInButton } from '../sign-in-button'
|
||||
import { UserDropdown } from '../user-dropdown'
|
||||
import { HeaderNavLink } from './header-nav-link'
|
||||
import React, { Fragment } from 'react'
|
||||
import React from 'react'
|
||||
import { Navbar } from 'react-bootstrap'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
|
||||
|
@ -32,23 +31,10 @@ const HeaderBar: React.FC = () => {
|
|||
<Trans i18nKey='landing.navigation.history' />
|
||||
</HeaderNavLink>
|
||||
</div>
|
||||
<div className='d-inline-flex'>
|
||||
<SettingsButton className={'p-1 mx-2'} variant={'outline-light'} />
|
||||
{!userExists ? (
|
||||
<Fragment>
|
||||
<span className={'mx-1 d-flex'}>
|
||||
<NewGuestNoteButton />
|
||||
</span>
|
||||
<SignInButton size='sm' />
|
||||
</Fragment>
|
||||
) : (
|
||||
<Fragment>
|
||||
<span className={'mx-1 d-flex'}>
|
||||
<NewUserNoteButton />
|
||||
</span>
|
||||
<UserDropdown />
|
||||
</Fragment>
|
||||
)}
|
||||
<div className='d-inline-flex gap-2'>
|
||||
<SettingsButton variant={'outline-light'} />
|
||||
<NewNoteButton />
|
||||
{!userExists ? <SignInButton size='sm' /> : <UserDropdown />}
|
||||
</div>
|
||||
</Navbar>
|
||||
)
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
import { UiIcon } from '../../common/icons/ui-icon'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import { Button } from 'react-bootstrap'
|
||||
import { Plus as IconPlus } from 'react-bootstrap-icons'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
|
||||
/**
|
||||
* Renders a button to create a new note as a guest.
|
||||
*/
|
||||
export const NewGuestNoteButton: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<Link href={'/new'} passHref={true}>
|
||||
<Button
|
||||
title={t('landing.navigation.newGuestNote') ?? undefined}
|
||||
variant='primary'
|
||||
size='sm'
|
||||
className='d-inline-flex align-items-center'
|
||||
{...cypressId('new-guest-note-button')}>
|
||||
<UiIcon icon={IconPlus} className='mx-1' size={2} />
|
||||
<span>
|
||||
<Trans i18nKey='landing.navigation.newGuestNote' />
|
||||
</span>
|
||||
</Button>
|
||||
</Link>
|
||||
)
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
import { UiIcon } from '../../common/icons/ui-icon'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import { Button } from 'react-bootstrap'
|
||||
import { Plus as IconPlus } from 'react-bootstrap-icons'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
|
||||
/**
|
||||
* Renders a button to create a new note as a logged in user.
|
||||
*/
|
||||
export const NewUserNoteButton: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<Link href={'/new'} passHref={true}>
|
||||
<Button
|
||||
title={t('landing.navigation.newNote') ?? undefined}
|
||||
variant='primary'
|
||||
size='sm'
|
||||
className='d-inline-flex align-items-center'
|
||||
{...cypressId('new-note-button')}>
|
||||
<UiIcon icon={IconPlus} className='mx-1' size={2} />
|
||||
<span>
|
||||
<Trans i18nKey='landing.navigation.newNote' />
|
||||
</span>
|
||||
</Button>
|
||||
</Link>
|
||||
)
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
.social-link-button {
|
||||
|
||||
&, &:hover {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.icon-part {
|
||||
padding: 0.375rem 0.375rem;
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.2);
|
||||
display: flex;
|
||||
|
||||
.social-icon {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.text-part {
|
||||
padding: 0.375rem 0.75rem;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { UiIcon } from '../../../common/icons/ui-icon'
|
||||
import styles from './social-link-button.module.scss'
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import React from 'react'
|
||||
import type { Icon } from 'react-bootstrap-icons'
|
||||
|
||||
export interface SocialButtonProps {
|
||||
backgroundClass: string
|
||||
href: string
|
||||
icon: Icon
|
||||
title?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a link for a social login.
|
||||
*
|
||||
* @param title The link title
|
||||
* @param backgroundClass Additional classes for the a-tag
|
||||
* @param href The link
|
||||
* @param icon The icon to be used
|
||||
* @param children The children to be rendered in addition to the icon.
|
||||
*/
|
||||
export const SocialLinkButton: React.FC<PropsWithChildren<SocialButtonProps>> = ({
|
||||
title,
|
||||
backgroundClass,
|
||||
href,
|
||||
icon,
|
||||
children
|
||||
}) => {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
title={title}
|
||||
className={`btn ${styles['social-link-button']} p-0 d-inline-flex align-items-stretch ${backgroundClass}`}>
|
||||
<span className={`${styles['icon-part']} d-flex align-items-center`}>
|
||||
<UiIcon icon={icon} className={styles['social-icon']} />
|
||||
</span>
|
||||
<span className={`${styles['text-part']} d-flex align-items-center mx-auto`}>{children}</span>
|
||||
</a>
|
||||
)
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { AuthProvider, AuthProviderWithCustomName } from '../../../api/config/types'
|
||||
import { SocialLinkButton } from './social-link-button/social-link-button'
|
||||
import { IconButton } from '../../common/icon-button/icon-button'
|
||||
import { getOneClickProviderMetadata } from './utils/get-one-click-provider-metadata'
|
||||
import React, { useMemo } from 'react'
|
||||
|
||||
|
@ -22,8 +22,8 @@ export const ViaOneClick: React.FC<ViaOneClickProps> = ({ provider }) => {
|
|||
const text = (provider as AuthProviderWithCustomName).providerName || name
|
||||
|
||||
return (
|
||||
<SocialLinkButton backgroundClass={className} icon={icon} href={url} title={text}>
|
||||
<IconButton className={className} icon={icon} href={url} title={text} border={true}>
|
||||
{text}
|
||||
</SocialLinkButton>
|
||||
</IconButton>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue