|
@@ -1,4 +1,5 @@
|
|
|
-import { FC, useRef } from 'react'
|
|
|
|
|
|
|
+import { FC, useCallback, useEffect, useRef } from 'react'
|
|
|
|
|
+import { useTranslation } from 'react-i18next'
|
|
|
import classnames from 'classnames'
|
|
import classnames from 'classnames'
|
|
|
import MaterialIcon from '@/shared/components/material-icon'
|
|
import MaterialIcon from '@/shared/components/material-icon'
|
|
|
import { useCodeMirrorViewContext } from '../codemirror-context'
|
|
import { useCodeMirrorViewContext } from '../codemirror-context'
|
|
@@ -11,7 +12,10 @@ export const ToolbarOverflow: FC<{
|
|
|
setOverflowOpen: (open: boolean) => void
|
|
setOverflowOpen: (open: boolean) => void
|
|
|
overflowRef?: React.Ref<HTMLDivElement>
|
|
overflowRef?: React.Ref<HTMLDivElement>
|
|
|
}> = ({ overflowed, overflowOpen, setOverflowOpen, overflowRef, children }) => {
|
|
}> = ({ overflowed, overflowOpen, setOverflowOpen, overflowRef, children }) => {
|
|
|
|
|
+ const { t } = useTranslation()
|
|
|
|
|
+
|
|
|
const buttonRef = useRef<HTMLButtonElement>(null)
|
|
const buttonRef = useRef<HTMLButtonElement>(null)
|
|
|
|
|
+ const keyboardInputRef = useRef(false)
|
|
|
const view = useCodeMirrorViewContext()
|
|
const view = useCodeMirrorViewContext()
|
|
|
|
|
|
|
|
const className = classnames(
|
|
const className = classnames(
|
|
@@ -22,6 +26,46 @@ export const ToolbarOverflow: FC<{
|
|
|
}
|
|
}
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+ // A11y - Move the focus inside the popover to the first toolbar button when it opens
|
|
|
|
|
+ const handlePopoverFocus = useCallback(() => {
|
|
|
|
|
+ if (keyboardInputRef.current) {
|
|
|
|
|
+ const firstToolbarItem = document.querySelector(
|
|
|
|
|
+ '#popover-toolbar-overflow .ol-cm-toolbar-overflow button:not([disabled])'
|
|
|
|
|
+ ) as HTMLButtonElement | null
|
|
|
|
|
+
|
|
|
|
|
+ if (firstToolbarItem) {
|
|
|
|
|
+ firstToolbarItem.focus()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }, [])
|
|
|
|
|
+
|
|
|
|
|
+ const handleKeyDown = useCallback(() => {
|
|
|
|
|
+ keyboardInputRef.current = true
|
|
|
|
|
+ }, [])
|
|
|
|
|
+
|
|
|
|
|
+ const handleMouseDown = useCallback(() => {
|
|
|
|
|
+ keyboardInputRef.current = false
|
|
|
|
|
+ }, [])
|
|
|
|
|
+
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ document.addEventListener('keydown', handleKeyDown)
|
|
|
|
|
+ document.addEventListener('mousedown', handleMouseDown)
|
|
|
|
|
+
|
|
|
|
|
+ return () => {
|
|
|
|
|
+ document.removeEventListener('keydown', handleKeyDown)
|
|
|
|
|
+ document.removeEventListener('mousedown', handleMouseDown)
|
|
|
|
|
+ }
|
|
|
|
|
+ }, [handleKeyDown, handleMouseDown])
|
|
|
|
|
+
|
|
|
|
|
+ // A11y - Move the focus back to the trigger when the popover is dismissed
|
|
|
|
|
+ const handleCloseAndReturnFocus = useCallback(() => {
|
|
|
|
|
+ setOverflowOpen(false)
|
|
|
|
|
+
|
|
|
|
|
+ if (keyboardInputRef.current && buttonRef.current) {
|
|
|
|
|
+ buttonRef.current.focus()
|
|
|
|
|
+ }
|
|
|
|
|
+ }, [setOverflowOpen])
|
|
|
|
|
+
|
|
|
return (
|
|
return (
|
|
|
<>
|
|
<>
|
|
|
<button
|
|
<button
|
|
@@ -29,7 +73,9 @@ export const ToolbarOverflow: FC<{
|
|
|
type="button"
|
|
type="button"
|
|
|
id="toolbar-more"
|
|
id="toolbar-more"
|
|
|
className={className}
|
|
className={className}
|
|
|
- aria-label="More"
|
|
|
|
|
|
|
+ aria-label={t('more_editor_toolbar_item')}
|
|
|
|
|
+ aria-expanded={overflowOpen}
|
|
|
|
|
+ aria-controls="popover-toolbar-overflow"
|
|
|
onMouseDown={event => {
|
|
onMouseDown={event => {
|
|
|
event.preventDefault()
|
|
event.preventDefault()
|
|
|
event.stopPropagation()
|
|
event.stopPropagation()
|
|
@@ -49,9 +95,14 @@ export const ToolbarOverflow: FC<{
|
|
|
// containerPadding={0}
|
|
// containerPadding={0}
|
|
|
transition
|
|
transition
|
|
|
rootClose
|
|
rootClose
|
|
|
- onHide={() => setOverflowOpen(false)}
|
|
|
|
|
|
|
+ onHide={handleCloseAndReturnFocus}
|
|
|
|
|
+ onEntered={handlePopoverFocus}
|
|
|
>
|
|
>
|
|
|
- <OLPopover id="popover-toolbar-overflow" ref={overflowRef}>
|
|
|
|
|
|
|
+ <OLPopover
|
|
|
|
|
+ id="popover-toolbar-overflow"
|
|
|
|
|
+ ref={overflowRef}
|
|
|
|
|
+ role="toolbar"
|
|
|
|
|
+ >
|
|
|
<div className="ol-cm-toolbar-overflow">{children}</div>
|
|
<div className="ol-cm-toolbar-overflow">{children}</div>
|
|
|
</OLPopover>
|
|
</OLPopover>
|
|
|
</OLOverlay>
|
|
</OLOverlay>
|