diff --git a/frontend/cypress/e2e/fileUpload.spec.ts b/frontend/cypress/e2e/fileUpload.spec.ts
index ffe6738fd..9dfb469bc 100644
--- a/frontend/cypress/e2e/fileUpload.spec.ts
+++ b/frontend/cypress/e2e/fileUpload.spec.ts
@@ -29,8 +29,8 @@ describe('File upload', () => {
})
it('via button', () => {
cy.getByCypressId('editor-pane').should('have.attr', 'data-cypress-editor-ready', 'true')
- cy.getByCypressId('editor-toolbar-upload-image-button').should('be.visible')
- cy.getByCypressId('editor-toolbar-upload-image-input').selectFile(
+ cy.getByCypressId('toolbar.uploadImage').should('be.visible')
+ cy.getByCypressId('toolbar.uploadImage.input').selectFile(
{
contents: '@demoImage',
fileName: 'demo.png',
@@ -80,8 +80,8 @@ describe('File upload', () => {
statusCode: 400
}
)
- cy.getByCypressId('editor-toolbar-upload-image-button').should('be.visible')
- cy.getByCypressId('editor-toolbar-upload-image-input').selectFile(
+ cy.getByCypressId('toolbar.uploadImage').should('be.visible')
+ cy.getByCypressId('toolbar.uploadImage.input').selectFile(
{
contents: '@demoImage',
fileName: 'demo.png',
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/bold-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/bold-button.tsx
index 72e49095e..279fd73b5 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/bold-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/bold-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { wrapSelection } from '../formatters/wrap-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { TypeBold as IconTypeBold } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const BoldButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection }) => {
return wrapSelection(currentSelection, '**', '**')
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/check-list-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/check-list-button.tsx
index 4d992b001..62ac39e28 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/check-list-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/check-list-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { CheckSquare as IconCheckSquare } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const CheckListButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => {
return prependLinesOfSelection(markdownContent, currentSelection, () => `- [ ] `)
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/code-fence-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/code-fence-button.tsx
index 49654d0e9..ed3e269d3 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/code-fence-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/code-fence-button.tsx
@@ -4,9 +4,9 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { changeCursorsToWholeLineIfNoToCursor } from '../formatters/utils/change-cursors-to-whole-line-if-no-to-cursor'
import { wrapSelection } from '../formatters/wrap-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { Code as IconCode } from 'react-bootstrap-icons'
@@ -17,5 +17,5 @@ export const CodeFenceButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => {
return wrapSelection(changeCursorsToWholeLineIfNoToCursor(markdownContent, currentSelection), '```\n', '\n```')
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/collapsible-block-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/collapsible-block-button.tsx
index 2a322eadd..d1712b05e 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/collapsible-block-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/collapsible-block-button.tsx
@@ -4,9 +4,9 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { changeCursorsToWholeLineIfNoToCursor } from '../formatters/utils/change-cursors-to-whole-line-if-no-to-cursor'
import { wrapSelection } from '../formatters/wrap-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { ArrowsCollapse as IconArrowsCollapse } from 'react-bootstrap-icons'
@@ -21,5 +21,5 @@ export const CollapsibleBlockButton: React.FC = () => {
'\n:::\n'
)
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/comment-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/comment-button.tsx
index 654e365b9..073956e6d 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/comment-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/comment-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { replaceSelection } from '../formatters/replace-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { ChatDots as IconChatDots } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const CommentButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection }) => {
return replaceSelection({ from: currentSelection.to ?? currentSelection.from }, '> []', true)
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/header-level-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/header-level-button.tsx
index 3e385d28b..600be58fb 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/header-level-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/header-level-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { TypeH1 as IconTypeH1 } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const HeaderLevelButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => {
return prependLinesOfSelection(markdownContent, currentSelection, (line) => (line.startsWith('#') ? `#` : `# `))
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/highlight-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/highlight-button.tsx
index f5e0271ed..dff64fa2f 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/highlight-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/highlight-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { wrapSelection } from '../formatters/wrap-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { Eraser as IconEraser } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const HighlightButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection }) => {
return wrapSelection(currentSelection, '==', '==')
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/horizontal-line-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/horizontal-line-button.tsx
index 0bf22019f..03f9b4efe 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/horizontal-line-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/horizontal-line-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { replaceSelection } from '../formatters/replace-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { DashLg as IconDashLg } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const HorizontalLineButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection }) => {
return replaceSelection({ from: currentSelection.to ?? currentSelection.from }, '----\n', true)
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/image-link-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/image-link-button.tsx
index 0b7231d41..67a4eacdd 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/image-link-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/image-link-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { addLink } from '../formatters/add-link'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { Image as IconImage } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const ImageLinkButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => {
return addLink(markdownContent, currentSelection, '!')
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/italic-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/italic-button.tsx
index aed31c36f..11b2842b9 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/italic-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/italic-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { wrapSelection } from '../formatters/wrap-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { TypeItalic as IconTypeItalic } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const ItalicButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection }) => {
return wrapSelection(currentSelection, '*', '*')
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/link-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/link-button.tsx
index d0e650bcd..6c546c7d3 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/link-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/link-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { addLink } from '../formatters/add-link'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { Link as IconLink } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const LinkButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => {
return addLink(markdownContent, currentSelection)
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/ordered-list-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/ordered-list-button.tsx
index 600622f70..335247f35 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/ordered-list-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/ordered-list-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { ListOl as IconListOl } from 'react-bootstrap-icons'
@@ -20,5 +20,5 @@ export const OrderedListButton: React.FC = () => {
(line, lineIndexInBlock) => `${lineIndexInBlock + 1}. `
)
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/quotes-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/quotes-button.tsx
index 9ae9265e6..75ee303c9 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/quotes-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/quotes-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { Quote as IconQuote } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const QuotesButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => {
return prependLinesOfSelection(markdownContent, currentSelection, () => `> `)
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/strikethrough-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/strikethrough-button.tsx
index 739523c98..a89e41c59 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/strikethrough-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/strikethrough-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { wrapSelection } from '../formatters/wrap-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { TypeStrikethrough as IconTypeStrikethrough } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const StrikethroughButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection }) => {
return wrapSelection(currentSelection, '~~', '~~')
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/subscript-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/subscript-button.tsx
index ea8781508..88f0f9a93 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/subscript-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/subscript-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { wrapSelection } from '../formatters/wrap-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { Subscript as IconSubscript } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const SubscriptButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection }) => {
return wrapSelection(currentSelection, '~', '~')
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/superscript-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/superscript-button.tsx
index 9195634e5..469518910 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/superscript-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/superscript-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { wrapSelection } from '../formatters/wrap-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { Superscript as IconSuperscript } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const SuperscriptButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection }) => {
return wrapSelection(currentSelection, '^', '^')
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/underline-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/underline-button.tsx
index 468aa4250..3b9d1c8e3 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/underline-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/underline-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { wrapSelection } from '../formatters/wrap-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { TypeUnderline as IconTypeUnderline } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const UnderlineButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection }) => {
return wrapSelection(currentSelection, '++', '++')
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/unordered-list-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/unordered-list-button.tsx
index 00e0588ff..e4a6d5ec1 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/unordered-list-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/unordered-list-button.tsx
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ContentFormatter } from '../../../change-content-context/use-change-editor-content-callback'
+import { FormatterToolbarButton } from '../formatter-toolbar-button'
import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection'
-import { ToolbarButton } from '../toolbar-button'
import React, { useCallback } from 'react'
import { List as IconList } from 'react-bootstrap-icons'
@@ -16,5 +16,5 @@ export const UnorderedListButton: React.FC = () => {
const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => {
return prependLinesOfSelection(markdownContent, currentSelection, () => `- `)
}, [])
- return
+ return
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx
index fc2bc753a..a497490d6 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx
@@ -3,29 +3,26 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { cypressId } from '../../../../../utils/cypress-attribute'
-import { UiIcon } from '../../../../common/icons/ui-icon'
import { useChangeEditorContentCallback } from '../../../change-content-context/use-change-editor-content-callback'
import { replaceSelection } from '../formatters/replace-selection'
+import { ToolbarButton } from '../toolbar-button'
import { EmojiPickerPopover } from './emoji-picker-popover'
import styles from './emoji-picker.module.scss'
import { extractEmojiShortCode } from './extract-emoji-short-code'
import type { EmojiClickEventDetail } from 'emoji-picker-element/shared'
import React, { Fragment, useCallback, useRef, useState } from 'react'
-import { Button, Overlay } from 'react-bootstrap'
+import { Overlay } from 'react-bootstrap'
import { EmojiSmile as IconEmojiSmile } from 'react-bootstrap-icons'
import type { OverlayInjectedProps } from 'react-bootstrap/Overlay'
-import { useTranslation } from 'react-i18next'
/**
* Renders a button to open the emoji picker.
* @see EmojiPickerPopover
*/
export const EmojiPickerButton: React.FC = () => {
- const { t } = useTranslation()
const [showEmojiPicker, setShowEmojiPicker] = useState(false)
const changeEditorContent = useChangeEditorContentCallback()
- const buttonRef = useRef(null)
+ const buttonRef = useRef(null)
const onEmojiSelected = useCallback(
(emojiClickEvent: EmojiClickEventDetail) => {
@@ -57,15 +54,7 @@ export const EmojiPickerButton: React.FC = () => {
offset={[0, 0]}>
{createPopoverElement}
-
+
)
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/formatter-toolbar-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/formatter-toolbar-button.tsx
new file mode 100644
index 000000000..e8470c6ae
--- /dev/null
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/formatter-toolbar-button.tsx
@@ -0,0 +1,31 @@
+/*
+ * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+import type { ContentFormatter } from '../../change-content-context/use-change-editor-content-callback'
+import { useChangeEditorContentCallback } from '../../change-content-context/use-change-editor-content-callback'
+import type { ToolbarButtonProps } from './toolbar-button'
+import { ToolbarButton } from './toolbar-button'
+import React, { useCallback } from 'react'
+
+export interface FormatterToolbarButtonProps extends Omit {
+ formatter: ContentFormatter
+}
+
+/**
+ * Renders a button for the editor toolbar that formats the content using a given formatter function.
+ *
+ * @param i18nKey Used to generate a title for the button by interpreting it as translation key in the i18n-namespace `editor.editorToolbar`-
+ * @param iconName A fork awesome icon name that is shown in the button
+ * @param formatter The formatter function changes the editor content on click
+ */
+export const FormatterToolbarButton: React.FC = ({ i18nKey, icon, formatter }) => {
+ const changeEditorContent = useChangeEditorContentCallback()
+
+ const onClick = useCallback(() => {
+ changeEditorContent?.(formatter)
+ }, [formatter, changeEditorContent])
+
+ return
+}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-picker-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-picker-button.tsx
index f4a243fc9..25a5a701c 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-picker-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-picker-button.tsx
@@ -3,19 +3,17 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { cypressId } from '../../../../../utils/cypress-attribute'
-import { UiIcon } from '../../../../common/icons/ui-icon'
import { useChangeEditorContentCallback } from '../../../change-content-context/use-change-editor-content-callback'
import { replaceSelection } from '../formatters/replace-selection'
+import { ToolbarButton } from '../toolbar-button'
import { createMarkdownTable } from './create-markdown-table'
import { CustomTableSizeModal } from './custom-table-size-modal'
import './table-picker.module.scss'
import { TableSizePickerPopover } from './table-size-picker-popover'
-import React, { Fragment, useCallback, useMemo, useRef, useState } from 'react'
-import { Button, Overlay } from 'react-bootstrap'
+import React, { Fragment, useCallback, useRef, useState } from 'react'
+import { Overlay } from 'react-bootstrap'
import { Table as IconTable } from 'react-bootstrap-icons'
import type { OverlayInjectedProps } from 'react-bootstrap/Overlay'
-import { useTranslation } from 'react-i18next'
enum PickerMode {
INVISIBLE,
@@ -27,7 +25,6 @@ enum PickerMode {
* Toggles the visibility of a table size picker overlay and inserts the result into the editor.
*/
export const TablePickerButton: React.FC = () => {
- const { t } = useTranslation()
const [pickerMode, setPickerMode] = useState(PickerMode.INVISIBLE)
const onDismiss = useCallback(() => setPickerMode(PickerMode.INVISIBLE), [])
const onShowModal = useCallback(() => setPickerMode(PickerMode.CUSTOM), [])
@@ -42,7 +39,6 @@ export const TablePickerButton: React.FC = () => {
[changeEditorContent]
)
- const tableTitle = useMemo(() => t('editor.editorToolbar.table.titleWithoutSize'), [t])
const button = useRef(null)
const toggleOverlayVisibility = useCallback(() => {
setPickerMode((oldPickerMode) => (oldPickerMode === PickerMode.INVISIBLE ? PickerMode.GRID : PickerMode.INVISIBLE))
@@ -71,15 +67,12 @@ export const TablePickerButton: React.FC = () => {
return (
-
+ buttonRef={button}
+ />
+
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/toolbar-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/toolbar-button.tsx
index bf00e4b5b..4f908c51f 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/toolbar-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/toolbar-button.tsx
@@ -5,9 +5,8 @@
*/
import { cypressId } from '../../../../utils/cypress-attribute'
import { UiIcon } from '../../../common/icons/ui-icon'
-import type { ContentFormatter } from '../../change-content-context/use-change-editor-content-callback'
-import { useChangeEditorContentCallback } from '../../change-content-context/use-change-editor-content-callback'
-import React, { useCallback, useMemo } from 'react'
+import type { PropsWithChildren, RefObject } from 'react'
+import React, { useMemo } from 'react'
import { Button } from 'react-bootstrap'
import type { Icon } from 'react-bootstrap-icons'
import { useTranslation } from 'react-i18next'
@@ -15,33 +14,41 @@ import { useTranslation } from 'react-i18next'
export interface ToolbarButtonProps {
i18nKey: string
icon: Icon
- formatter: ContentFormatter
+ onClick: () => void
+ disabled?: boolean
+ buttonRef?: RefObject
}
/**
- * Renders a button for the editor toolbar that formats the content using a given formatter function.
+ * Renders a button for the editor toolbar.
*
* @param i18nKey Used to generate a title for the button by interpreting it as translation key in the i18n-namespace `editor.editorToolbar`-
- * @param iconName A fork awesome icon name that is shown in the button
- * @param formatter The formatter function changes the editor content on click
+ * @param iconName An icon that is shown in the button
+ * @param onClick A callback that is executed on click
+ * @param disabled Defines if the button is disabled
+ * @param buttonRef A reference to the button element
*/
-export const ToolbarButton: React.FC = ({ i18nKey, icon, formatter }) => {
+export const ToolbarButton: React.FC> = ({
+ i18nKey,
+ icon,
+ onClick,
+ disabled = false,
+ buttonRef,
+ children
+}) => {
const { t } = useTranslation('', { keyPrefix: 'editor.editorToolbar' })
- const changeEditorContent = useChangeEditorContentCallback()
-
- const onClick = useCallback(() => {
- changeEditorContent?.(formatter)
- }, [formatter, changeEditorContent])
const title = useMemo(() => t(i18nKey), [i18nKey, t])
return (
)
}
diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx
index 056d577e9..afe1a4936 100644
--- a/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx
+++ b/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx
@@ -5,18 +5,16 @@
*/
import { cypressId } from '../../../../../utils/cypress-attribute'
import { Logger } from '../../../../../utils/logger'
-import { UiIcon } from '../../../../common/icons/ui-icon'
import { ShowIf } from '../../../../common/show-if/show-if'
import { acceptedMimeTypes } from '../../../../common/upload-image-mimetypes'
import { UploadInput } from '../../../../common/upload-input'
import { useCodemirrorReferenceContext } from '../../../change-content-context/codemirror-reference-context'
import { useHandleUpload } from '../../hooks/use-handle-upload'
+import { ToolbarButton } from '../toolbar-button'
import { extractSelectedText } from './extract-selected-text'
import { Optional } from '@mrdrogdrog/optional'
import React, { Fragment, useCallback, useRef } from 'react'
-import { Button } from 'react-bootstrap'
import { Upload as IconUpload } from 'react-bootstrap-icons'
-import { useTranslation } from 'react-i18next'
const logger = new Logger('Upload image button')
@@ -24,7 +22,6 @@ const logger = new Logger('Upload image button')
* Shows a button that uploads a chosen file to the backend and adds the link to the note.
*/
export const UploadImageButton: React.FC = () => {
- const { t } = useTranslation()
const clickRef = useRef<() => void>()
const buttonClick = useCallback(() => {
clickRef.current?.()
@@ -49,22 +46,16 @@ export const UploadImageButton: React.FC = () => {
return (
-
-
-
-
+
+
+
+
+
)
}