Skip to content

Commit

Permalink
Added optional FloatingArrow to TextAnnotatorPopup
Browse files Browse the repository at this point in the history
  • Loading branch information
rsimon committed Nov 8, 2024
1 parent 5abe652 commit ce7014d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { ReactNode, useEffect, useMemo, useState } from 'react';
import { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
import { useAnnotator, useSelection } from '@annotorious/react';
import { isRevived, NOT_ANNOTATABLE_CLASS, TextAnnotation, TextAnnotator } from '@recogito/text-annotator';
import { isMobile } from './isMobile';
import {
arrow,
autoUpdate,
flip,
FloatingArrow,
FloatingArrowProps,
FloatingFocusManager,
FloatingPortal,
inline,
Expand All @@ -22,6 +25,10 @@ interface TextAnnotationPopupProps {

ariaCloseWarning?: string;

arrow?: boolean;

arrowProps?: Omit<FloatingArrowProps, 'context' | 'ref'>;

popup(props: TextAnnotationPopupContentProps): ReactNode;

}
Expand All @@ -46,6 +53,22 @@ export const TextAnnotatorPopup = (props: TextAnnotationPopupProps) => {

const [isOpen, setOpen] = useState(selected?.length > 0);

const arrowRef = useRef(null);

// Conditional floating-ui middleware
const middleware = useMemo(() => {
const m = [
inline(),
offset(10),
flip({ crossAxis: true }),
shift({ crossAxis: true, padding: 10 })
];

return props.arrow
? [...m, arrow({ element: arrowRef }) ]
: m;
}, [props.arrow]);

const { refs, floatingStyles, update, context } = useFloating({
placement: isMobile() ? 'bottom' : 'top',
open: isOpen,
Expand All @@ -55,12 +78,7 @@ export const TextAnnotatorPopup = (props: TextAnnotationPopupProps) => {
r?.cancelSelected();
}
},
middleware: [
offset(10),
inline(),
flip(),
shift({ mainAxis: false, crossAxis: true, padding: 10 })
],
middleware,
whileElementsMounted: autoUpdate
});

Expand Down Expand Up @@ -132,6 +150,13 @@ export const TextAnnotatorPopup = (props: TextAnnotationPopupProps) => {
event
})}

{props.arrow && (
<FloatingArrow
ref={arrowRef}
context={context}
{...(props.arrowProps || {})} />
)}

<button className="r6o-popup-sr-only" aria-live="assertive" onClick={onClose}>
{props.ariaCloseWarning || 'Click or leave this dialog to close it.'}
</button>
Expand Down
4 changes: 4 additions & 0 deletions packages/text-annotator-react/test/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ export const App: FC = () => {
</TextAnnotator>

<TextAnnotatorPopup
arrow
arrowProps={{
fill: '#000000'
}}
popup={
props => (<TestPopup {...props} />)
}
Expand Down
1 change: 1 addition & 0 deletions packages/text-annotator-react/test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
p {
font-size: 17px;
line-height: 160%;
min-width: 600px;
}

.r6o-popup {
Expand Down

0 comments on commit ce7014d

Please sign in to comment.