diff options
Diffstat (limited to 'src/client/views/nodes/LinkBox.tsx')
-rw-r--r-- | src/client/views/nodes/LinkBox.tsx | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 4d9d2460e..d5dc256d9 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -20,6 +20,7 @@ import { StyleProp } from '../StyleProp'; import { ComparisonBox } from './ComparisonBox'; import { DocumentView } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; +import { RichTextMenu } from './formattedText/RichTextMenu'; import './LinkBox.scss'; @observer @@ -29,6 +30,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { } _hackToSeeIfDeleted: NodeJS.Timeout | undefined; _disposers: { [name: string]: IReactionDisposer } = {}; + _divRef: HTMLDivElement | null = null; @observable _forceAnimate: number = 0; // forces xArrow to animate when a transition animation is detected on something that affects an anchor @observable _hide = false; // don't render if anchor is not visible since that breaks xAnchor @@ -78,6 +80,24 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { })) // prettier-ignore ); } + /** + * When an IconButton is clicked, it will receive focus. However, we don't want that since we want or need that since we really want + * to maintain focus in the label's editing div (and cursor position). so this relies on IconButton's having a tabindex set to -1 so that + * we can march up the tree from the 'relatedTarget' to determine if the loss of focus was caused by a fonticonbox. If it is, we then + * restore focus + * @param e focusout event on the editing div + */ + keepFocus = (e: FocusEvent) => { + if (e.relatedTarget instanceof HTMLElement && e.relatedTarget.tabIndex === -1) { + for (let ele: HTMLElement | null = e.relatedTarget; ele; ele = (ele as HTMLElement)?.parentElement) { + if (['listItem-container', 'fonticonbox'].includes((ele as HTMLElement)?.className ?? '')) { + console.log('RESTORE :', document.activeElement, this._divRef); + this._divRef?.focus(); + break; + } + } + } + }; render() { TraceMobx(); @@ -98,7 +118,6 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { a.Document[DocCss]; b.Document[DocCss]; - // eslint-disable-next-line @typescript-eslint/no-unused-vars const axf = a.screenToViewTransform(); // these force re-render when a or b moves (so do NOT remove) const bxf = b.screenToViewTransform(); const scale = docView?.screenToViewTransform().Scale ?? 1; @@ -157,10 +176,9 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { const fontFamily = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily) as string; const fontSize = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize) as number; const fontColor = (c => (c !== 'transparent' ? c : undefined))(StrCast(this.layoutDoc.link_fontColor)); - // eslint-disable-next-line camelcase const { stroke_markerScale: strokeMarkerScale, stroke_width: strokeRawWidth, stroke_startMarker: strokeStartMarker, stroke_endMarker: strokeEndMarker, stroke_dash: strokeDash } = this.Document; - const strokeWidth = NumCast(strokeRawWidth, 4); + const strokeWidth = NumCast(strokeRawWidth, 1); const linkDesc = StrCast(this.dataDoc.link_description) || ' '; const labelText = linkDesc.substring(0, 50) + (linkDesc.length > 50 ? '...' : ''); return ( @@ -197,8 +215,23 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { <div id={this.DocumentView?.().DocUniqueId} className="linkBox-label" + tabIndex={-1} + ref={r => (this._divRef = r)} + onPointerDown={e => e.stopPropagation()} + onFocus={() => { + RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined, this.dataDoc); + this._divRef?.removeEventListener('focusout', this.keepFocus); + this._divRef?.addEventListener('focusout', this.keepFocus); + }} + onBlur={() => { + if (document.activeElement !== this._divRef && document.activeElement?.parentElement !== this._divRef) { + this._divRef?.removeEventListener('focusout', this.keepFocus); + RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined, undefined); + } + }} style={{ borderRadius: '8px', + transform: `scale(${1 / scale})`, pointerEvents: this._props.isDocumentActive?.() ? 'all' : undefined, fontSize, fontFamily /* , fontStyle: 'italic' */, @@ -250,7 +283,6 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { return ( <div className={`linkBox-container${this._props.isContentActive() ? '-interactive' : ''}`} style={{ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string }}> <ComparisonBox - // eslint-disable-next-line react/jsx-props-no-spreading {...this.props} // fieldKey="link_anchor" setHeight={emptyFunction} |