Просмотр исходного кода

WIP: impl focus behavior with SWR

Yuki Takei 4 лет назад
Родитель
Сommit
bc09f78fd9

+ 4 - 2
packages/app/src/components/Hotkeys/Subscribers/FocusToGlobalSearch.jsx

@@ -1,9 +1,11 @@
 import { FC, useEffect } from 'react';
 import { FC, useEffect } from 'react';
 
 
 import { useIsEditable } from '~/stores/context';
 import { useIsEditable } from '~/stores/context';
+import { useGlobalSearchFormRef } from '~/stores/ui';
 
 
 const FocusToGlobalSearch = (props) => {
 const FocusToGlobalSearch = (props) => {
   const { data: isEditable } = useIsEditable();
   const { data: isEditable } = useIsEditable();
+  const { data: globalSearchFormRef } = useGlobalSearchFormRef();
 
 
   // setup effect
   // setup effect
   useEffect(() => {
   useEffect(() => {
@@ -16,11 +18,11 @@ const FocusToGlobalSearch = (props) => {
       return;
       return;
     }
     }
 
 
-    console.log('focus to GlobalSearch');
+    globalSearchFormRef.current.focus();
 
 
     // remove this
     // remove this
     props.onDeleteRender();
     props.onDeleteRender();
-  }, [isEditable, props]);
+  }, [globalSearchFormRef, isEditable, props]);
 
 
   return null;
   return null;
 };
 };

+ 8 - 1
packages/app/src/components/Navbar/GlobalSearch.tsx

@@ -1,14 +1,16 @@
 import React, {
 import React, {
-  FC, useState, useCallback,
+  FC, useState, useCallback, useRef,
 } from 'react';
 } from 'react';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 
 
 import AppContainer from '~/client/services/AppContainer';
 import AppContainer from '~/client/services/AppContainer';
 import { IPage } from '~/interfaces/page';
 import { IPage } from '~/interfaces/page';
+import { IFocusable } from '~/client/interfaces/focusable';
 
 
 import { withUnstatedContainers } from '../UnstatedUtils';
 import { withUnstatedContainers } from '../UnstatedUtils';
 
 
 import SearchForm from '../SearchForm';
 import SearchForm from '../SearchForm';
+import { useGlobalSearchFormRef } from '~/stores/ui';
 
 
 
 
 type Props = {
 type Props = {
@@ -21,6 +23,10 @@ const GlobalSearch: FC<Props> = (props: Props) => {
   const { appContainer, dropup } = props;
   const { appContainer, dropup } = props;
   const { t } = useTranslation();
   const { t } = useTranslation();
 
 
+  const globalSearchFormRef = useRef<IFocusable>(null);
+
+  useGlobalSearchFormRef(globalSearchFormRef);
+
   const [text, setText] = useState('');
   const [text, setText] = useState('');
   const [isScopeChildren, setScopeChildren] = useState<boolean>(appContainer.getConfig().isSearchScopeChildrenAsDefault);
   const [isScopeChildren, setScopeChildren] = useState<boolean>(appContainer.getConfig().isSearchScopeChildrenAsDefault);
 
 
@@ -70,6 +76,7 @@ const GlobalSearch: FC<Props> = (props: Props) => {
           </div>
           </div>
         </div>
         </div>
         <SearchForm
         <SearchForm
+          ref={globalSearchFormRef}
           isSearchServiceReachable={isSearchServiceReachable}
           isSearchServiceReachable={isSearchServiceReachable}
           dropup={dropup}
           dropup={dropup}
           onChange={gotoPage}
           onChange={gotoPage}

+ 9 - 0
packages/app/src/stores/ui.tsx

@@ -5,11 +5,13 @@ import useSWRImmutable from 'swr/immutable';
 
 
 import { Breakpoint, addBreakpointListener } from '@growi/ui';
 import { Breakpoint, addBreakpointListener } from '@growi/ui';
 
 
+import { RefObject } from 'react';
 import { SidebarContentsType } from '~/interfaces/ui';
 import { SidebarContentsType } from '~/interfaces/ui';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
 import { useStaticSWR } from './use-static-swr';
 import { useStaticSWR } from './use-static-swr';
 import { useIsEditable } from './context';
 import { useIsEditable } from './context';
+import { IFocusable } from '~/client/interfaces/focusable';
 
 
 const logger = loggerFactory('growi:stores:ui');
 const logger = loggerFactory('growi:stores:ui');
 
 
@@ -215,3 +217,10 @@ export const usePageCreateModalOpened = (isOpened?: boolean): SWRResponse<boolea
   const initialData = false;
   const initialData = false;
   return useStaticSWR('isPageCreateModalOpened', isOpened || null, { fallbackData: initialData });
   return useStaticSWR('isPageCreateModalOpened', isOpened || null, { fallbackData: initialData });
 };
 };
+
+export const useGlobalSearchFormRef = (initialData?: RefObject<IFocusable>): SWRResponse<RefObject<IFocusable>, Error> => {
+  return useStaticSWR(
+    'globalSearchTypeahead',
+    initialData ?? null,
+  );
+};