create an explicit giveFocus() method on the viewmodel. fix preview header text

This commit is contained in:
sawka 2024-07-22 16:41:18 -07:00
parent b2ee164b85
commit 198ec60e69
5 changed files with 51 additions and 41 deletions

View File

@ -602,6 +602,11 @@ const BlockFull = React.memo(({ blockId, layoutModel }: BlockProps) => {
setBlockClicked(true);
}, []);
let { viewElem, viewModel } = React.useMemo(
() => getViewElemAndModel(blockId, blockData?.view, blockRef),
[blockId, blockData?.view, blockRef]
);
const determineFocusedChild = React.useCallback(
(event: React.FocusEvent<HTMLDivElement, Element>) => {
setFocusedChild(event.target);
@ -609,33 +614,13 @@ const BlockFull = React.memo(({ blockId, layoutModel }: BlockProps) => {
[setFocusedChild]
);
const getFocusableChildren = React.useCallback(() => {
if (blockRef.current == null) {
return [];
}
return Array.from(
blockRef.current.querySelectorAll(
'a[href], area[href], input:not([disabled]), select:not([disabled]), button:not([disabled]), [tabindex="0"]'
)
).filter((elem) => elem.id != `${blockId}-dummy-focus`);
}, [blockRef.current]);
const setFocusTarget = React.useCallback(() => {
const focusableChildren = getFocusableChildren();
if (focusableChildren.length == 0) {
focusElemRef.current.focus({ preventScroll: true });
} else {
const firstFocusableChild = focusableChildren[0] as HTMLElement;
if (!firstFocusableChild.classList.contains("url-input")) {
firstFocusableChild.focus({ preventScroll: true });
}
const ok = viewModel?.giveFocus?.();
if (ok) {
return;
}
}, [getFocusableChildren]);
let { viewElem, viewModel } = React.useMemo(
() => getViewElemAndModel(blockId, blockData?.view, blockRef),
[blockId, blockData?.view, blockRef]
);
focusElemRef.current.focus({ preventScroll: true });
}, []);
if (!blockId || !blockData) return null;
@ -658,14 +643,7 @@ const BlockFull = React.memo(({ blockId, layoutModel }: BlockProps) => {
viewModel={viewModel}
>
<div key="focuselem" className="block-focuselem">
<input
type="text"
value=""
ref={focusElemRef}
id={`${blockId}-dummy-focus`}
onChange={() => {}}
disabled={getFocusableChildren().length > 0}
/>
<input type="text" value="" ref={focusElemRef} id={`${blockId}-dummy-focus`} onChange={() => {}} />
</div>
<div key="content" className="block-content">
<ErrorBoundary>

View File

@ -560,6 +560,14 @@ function DirectoryPreview({ fileNameAtom, model }: DirectoryPreviewProps) {
}
}, [filteredData]);
const inputRef = React.useRef<HTMLInputElement>(null);
React.useEffect(() => {
model.directoryInputElem = inputRef.current;
return () => {
model.directoryInputElem = null;
};
}, []);
return (
<div
className="dir-table-container"
@ -574,9 +582,9 @@ function DirectoryPreview({ fileNameAtom, model }: DirectoryPreviewProps) {
<input
type="text"
className="dir-table-search-box"
ref={inputRef}
onChange={() => {}} //for nuisance warnings
maxLength={400}
autoFocus={true}
value={searchText}
/>
</div>

View File

@ -54,6 +54,7 @@ export class PreviewModel implements ViewModel {
showHiddenFiles: jotai.PrimitiveAtom<boolean>;
refreshVersion: jotai.PrimitiveAtom<number>;
refreshCallback: () => void;
directoryInputElem: HTMLInputElement;
setPreviewFileName(fileName: string) {
services.ObjectService.UpdateObjectMeta(`block:${this.blockId}`, { file: fileName });
@ -101,14 +102,14 @@ export class PreviewModel implements ViewModel {
});
this.viewName = jotai.atom("Preview");
this.viewText = jotai.atom((get) => {
const viewTextChildren: HeaderElem[] = [
{
elemtype: "input",
value: get(this.fileName),
isDisabled: true,
},
];
if (get(this.isCeView)) {
const viewTextChildren: HeaderElem[] = [
{
elemtype: "input",
value: get(this.fileName),
isDisabled: true,
},
];
if (get(this.ceReadOnly) == false) {
viewTextChildren.push(
{
@ -138,6 +139,13 @@ export class PreviewModel implements ViewModel {
children: viewTextChildren,
},
] as HeaderElem[];
} else {
return [
{
elemtype: "text",
text: get(this.fileName),
},
];
}
});
@ -272,6 +280,14 @@ export class PreviewModel implements ViewModel {
});
return menuItems;
}
giveFocus(): boolean {
if (this.directoryInputElem) {
this.directoryInputElem.focus({ preventScroll: true });
return true;
}
return false;
}
}
function makePreviewModel(blockId: string): PreviewModel {

View File

@ -280,6 +280,13 @@ export class WebViewModel implements ViewModel {
getUrl() {
return this.historyStack[this.historyIndex];
}
giveFocus(): boolean {
if (this.urlInputRef.current) {
this.urlInputRef.current.focus({ preventScroll: true });
return true;
}
}
}
function makeWebViewModel(blockId: string): WebViewModel {

View File

@ -173,6 +173,7 @@ declare global {
onSearchChange?: (text: string) => void;
onSearch?: (text: string) => void;
getSettingsMenuItems?: () => ContextMenuItem[];
giveFocus?: () => boolean;
}
// jotai doesn't export this type :/