Browse Source

show SkeletonItem while loading

Yuki Takei 2 years ago
parent
commit
e34fc7b8b5

+ 3 - 5
apps/app/src/components/Sidebar/PersonalDropdown.tsx → apps/app/src/components/Sidebar/SidebarNav/PersonalDropdown.tsx

@@ -10,6 +10,8 @@ import { apiv3Post } from '~/client/util/apiv3-client';
 import { toastError } from '~/client/util/toastr';
 import { toastError } from '~/client/util/toastr';
 import { useCurrentUser } from '~/stores/context';
 import { useCurrentUser } from '~/stores/context';
 
 
+import { SkeletonItem } from './SkeletonItem';
+
 const ProactiveQuestionnaireModal = dynamic(() => import('~/features/questionnaire/client/components/ProactiveQuestionnaireModal'), { ssr: false });
 const ProactiveQuestionnaireModal = dynamic(() => import('~/features/questionnaire/client/components/ProactiveQuestionnaireModal'), { ssr: false });
 
 
 export const PersonalDropdown = (): JSX.Element => {
 export const PersonalDropdown = (): JSX.Element => {
@@ -19,11 +21,7 @@ export const PersonalDropdown = (): JSX.Element => {
   const [isQuestionnaireModalOpen, setQuestionnaireModalOpen] = useState(false);
   const [isQuestionnaireModalOpen, setQuestionnaireModalOpen] = useState(false);
 
 
   if (currentUser == null) {
   if (currentUser == null) {
-    return (
-      <div className="text-muted text-center mb-5">
-        <i className="fa fa-2x fa-spinner fa-pulse me-1" />
-      </div>
-    );
+    return <SkeletonItem />;
   }
   }
 
 
   const logoutHandler = async() => {
   const logoutHandler = async() => {

+ 6 - 1
apps/app/src/components/Sidebar/SidebarNav/SecondaryItems.tsx

@@ -5,10 +5,15 @@ import Link from 'next/link';
 
 
 import { useGrowiCloudUri, useIsAdmin } from '~/stores/context';
 import { useGrowiCloudUri, useIsAdmin } from '~/stores/context';
 
 
+import { SkeletonItem } from './SkeletonItem';
+
 import styles from './SecondaryItems.module.scss';
 import styles from './SecondaryItems.module.scss';
 
 
 
 
-const PersonalDropdown = dynamic(() => import('../PersonalDropdown').then(mod => mod.PersonalDropdown), { ssr: false });
+const PersonalDropdown = dynamic(() => import('./PersonalDropdown').then(mod => mod.PersonalDropdown), {
+  ssr: false,
+  loading: () => <SkeletonItem />,
+});
 
 
 
 
 type SecondaryItemProps = {
 type SecondaryItemProps = {

+ 12 - 0
apps/app/src/components/Sidebar/SidebarNav/SkeletonItem.module.scss

@@ -0,0 +1,12 @@
+@use '@growi/core/scss/bootstrap/init' as bs;
+
+@use './variables' as sidebarNavVar;
+
+.grw-skeleton-item :global {
+  height: sidebarNavVar.$grw-sidebar-primary-button-height;
+  padding: .75rem;
+
+  .grw-skeleton {
+    background-color: var(--bs-secondary-bg-subtle);
+  }
+}

+ 10 - 0
apps/app/src/components/Sidebar/SidebarNav/SkeletonItem.tsx

@@ -0,0 +1,10 @@
+import { memo } from 'react';
+
+import { Skeleton } from '~/components/Skeleton';
+
+import styles from './SkeletonItem.module.scss';
+
+
+export const SkeletonItem = memo(() => {
+  return <Skeleton additionalClass={styles['grw-skeleton-item']} roundedPill />;
+});