mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
create an explicit giveFocus() method on the viewmodel. fix preview header text
This commit is contained in:
parent
b2ee164b85
commit
198ec60e69
@ -602,6 +602,11 @@ const BlockFull = React.memo(({ blockId, layoutModel }: BlockProps) => {
|
|||||||
setBlockClicked(true);
|
setBlockClicked(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
let { viewElem, viewModel } = React.useMemo(
|
||||||
|
() => getViewElemAndModel(blockId, blockData?.view, blockRef),
|
||||||
|
[blockId, blockData?.view, blockRef]
|
||||||
|
);
|
||||||
|
|
||||||
const determineFocusedChild = React.useCallback(
|
const determineFocusedChild = React.useCallback(
|
||||||
(event: React.FocusEvent<HTMLDivElement, Element>) => {
|
(event: React.FocusEvent<HTMLDivElement, Element>) => {
|
||||||
setFocusedChild(event.target);
|
setFocusedChild(event.target);
|
||||||
@ -609,33 +614,13 @@ const BlockFull = React.memo(({ blockId, layoutModel }: BlockProps) => {
|
|||||||
[setFocusedChild]
|
[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 setFocusTarget = React.useCallback(() => {
|
||||||
const focusableChildren = getFocusableChildren();
|
const ok = viewModel?.giveFocus?.();
|
||||||
if (focusableChildren.length == 0) {
|
if (ok) {
|
||||||
focusElemRef.current.focus({ preventScroll: true });
|
return;
|
||||||
} else {
|
|
||||||
const firstFocusableChild = focusableChildren[0] as HTMLElement;
|
|
||||||
if (!firstFocusableChild.classList.contains("url-input")) {
|
|
||||||
firstFocusableChild.focus({ preventScroll: true });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [getFocusableChildren]);
|
focusElemRef.current.focus({ preventScroll: true });
|
||||||
|
}, []);
|
||||||
let { viewElem, viewModel } = React.useMemo(
|
|
||||||
() => getViewElemAndModel(blockId, blockData?.view, blockRef),
|
|
||||||
[blockId, blockData?.view, blockRef]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!blockId || !blockData) return null;
|
if (!blockId || !blockData) return null;
|
||||||
|
|
||||||
@ -658,14 +643,7 @@ const BlockFull = React.memo(({ blockId, layoutModel }: BlockProps) => {
|
|||||||
viewModel={viewModel}
|
viewModel={viewModel}
|
||||||
>
|
>
|
||||||
<div key="focuselem" className="block-focuselem">
|
<div key="focuselem" className="block-focuselem">
|
||||||
<input
|
<input type="text" value="" ref={focusElemRef} id={`${blockId}-dummy-focus`} onChange={() => {}} />
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
ref={focusElemRef}
|
|
||||||
id={`${blockId}-dummy-focus`}
|
|
||||||
onChange={() => {}}
|
|
||||||
disabled={getFocusableChildren().length > 0}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div key="content" className="block-content">
|
<div key="content" className="block-content">
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
|
@ -560,6 +560,14 @@ function DirectoryPreview({ fileNameAtom, model }: DirectoryPreviewProps) {
|
|||||||
}
|
}
|
||||||
}, [filteredData]);
|
}, [filteredData]);
|
||||||
|
|
||||||
|
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||||
|
React.useEffect(() => {
|
||||||
|
model.directoryInputElem = inputRef.current;
|
||||||
|
return () => {
|
||||||
|
model.directoryInputElem = null;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="dir-table-container"
|
className="dir-table-container"
|
||||||
@ -574,9 +582,9 @@ function DirectoryPreview({ fileNameAtom, model }: DirectoryPreviewProps) {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="dir-table-search-box"
|
className="dir-table-search-box"
|
||||||
|
ref={inputRef}
|
||||||
onChange={() => {}} //for nuisance warnings
|
onChange={() => {}} //for nuisance warnings
|
||||||
maxLength={400}
|
maxLength={400}
|
||||||
autoFocus={true}
|
|
||||||
value={searchText}
|
value={searchText}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,6 +54,7 @@ export class PreviewModel implements ViewModel {
|
|||||||
showHiddenFiles: jotai.PrimitiveAtom<boolean>;
|
showHiddenFiles: jotai.PrimitiveAtom<boolean>;
|
||||||
refreshVersion: jotai.PrimitiveAtom<number>;
|
refreshVersion: jotai.PrimitiveAtom<number>;
|
||||||
refreshCallback: () => void;
|
refreshCallback: () => void;
|
||||||
|
directoryInputElem: HTMLInputElement;
|
||||||
|
|
||||||
setPreviewFileName(fileName: string) {
|
setPreviewFileName(fileName: string) {
|
||||||
services.ObjectService.UpdateObjectMeta(`block:${this.blockId}`, { file: fileName });
|
services.ObjectService.UpdateObjectMeta(`block:${this.blockId}`, { file: fileName });
|
||||||
@ -101,14 +102,14 @@ export class PreviewModel implements ViewModel {
|
|||||||
});
|
});
|
||||||
this.viewName = jotai.atom("Preview");
|
this.viewName = jotai.atom("Preview");
|
||||||
this.viewText = jotai.atom((get) => {
|
this.viewText = jotai.atom((get) => {
|
||||||
const viewTextChildren: HeaderElem[] = [
|
|
||||||
{
|
|
||||||
elemtype: "input",
|
|
||||||
value: get(this.fileName),
|
|
||||||
isDisabled: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
if (get(this.isCeView)) {
|
if (get(this.isCeView)) {
|
||||||
|
const viewTextChildren: HeaderElem[] = [
|
||||||
|
{
|
||||||
|
elemtype: "input",
|
||||||
|
value: get(this.fileName),
|
||||||
|
isDisabled: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
if (get(this.ceReadOnly) == false) {
|
if (get(this.ceReadOnly) == false) {
|
||||||
viewTextChildren.push(
|
viewTextChildren.push(
|
||||||
{
|
{
|
||||||
@ -138,6 +139,13 @@ export class PreviewModel implements ViewModel {
|
|||||||
children: viewTextChildren,
|
children: viewTextChildren,
|
||||||
},
|
},
|
||||||
] as HeaderElem[];
|
] as HeaderElem[];
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
elemtype: "text",
|
||||||
|
text: get(this.fileName),
|
||||||
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -272,6 +280,14 @@ export class PreviewModel implements ViewModel {
|
|||||||
});
|
});
|
||||||
return menuItems;
|
return menuItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
giveFocus(): boolean {
|
||||||
|
if (this.directoryInputElem) {
|
||||||
|
this.directoryInputElem.focus({ preventScroll: true });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makePreviewModel(blockId: string): PreviewModel {
|
function makePreviewModel(blockId: string): PreviewModel {
|
||||||
|
@ -280,6 +280,13 @@ export class WebViewModel implements ViewModel {
|
|||||||
getUrl() {
|
getUrl() {
|
||||||
return this.historyStack[this.historyIndex];
|
return this.historyStack[this.historyIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
giveFocus(): boolean {
|
||||||
|
if (this.urlInputRef.current) {
|
||||||
|
this.urlInputRef.current.focus({ preventScroll: true });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeWebViewModel(blockId: string): WebViewModel {
|
function makeWebViewModel(blockId: string): WebViewModel {
|
||||||
|
1
frontend/types/custom.d.ts
vendored
1
frontend/types/custom.d.ts
vendored
@ -173,6 +173,7 @@ declare global {
|
|||||||
onSearchChange?: (text: string) => void;
|
onSearchChange?: (text: string) => void;
|
||||||
onSearch?: (text: string) => void;
|
onSearch?: (text: string) => void;
|
||||||
getSettingsMenuItems?: () => ContextMenuItem[];
|
getSettingsMenuItems?: () => ContextMenuItem[];
|
||||||
|
giveFocus?: () => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// jotai doesn't export this type :/
|
// jotai doesn't export this type :/
|
||||||
|
Loading…
Reference in New Issue
Block a user