Przeglądaj źródła

Merge pull request #8216 from weseek/imprv/pae-create-button

imprv: Page create button styles
Yuki Takei 2 lat temu
rodzic
commit
c377280254
25 zmienionych plików z 236 dodań i 94 usunięć
  1. 0 17
      apps/app/_obsolete/src/components/Sidebar/NavigationResizeHexagon.tsx
  2. 1 1
      apps/app/src/components/SearchPage/SearchPageBase.tsx
  3. 3 1
      apps/app/src/components/SearchPage/SearchResultContent.tsx
  4. 46 0
      apps/app/src/components/Sidebar/PageCreateButton/CreateButton.module.scss
  5. 24 0
      apps/app/src/components/Sidebar/PageCreateButton/CreateButton.tsx
  6. 3 3
      apps/app/src/components/Sidebar/PageCreateButton/DropendMenu.tsx
  7. 60 0
      apps/app/src/components/Sidebar/PageCreateButton/DropendToggle.module.scss
  8. 24 0
      apps/app/src/components/Sidebar/PageCreateButton/DropendToggle.tsx
  9. 18 0
      apps/app/src/components/Sidebar/PageCreateButton/Hexagon.tsx
  10. 2 0
      apps/app/src/components/Sidebar/PageCreateButton/PageCreateButton.module.scss
  11. 12 17
      apps/app/src/components/Sidebar/PageCreateButton/PageCreateButton.tsx
  12. 1 1
      apps/app/src/components/Sidebar/SidebarHead/ToggleCollapseButton.module.scss
  13. 3 6
      apps/app/src/components/Sidebar/SidebarNav/PrimaryItems.module.scss
  14. 1 1
      apps/app/src/components/Sidebar/SidebarNav/PrimaryItems.tsx
  15. 2 5
      apps/app/src/components/Sidebar/SidebarNav/SecondaryItems.module.scss
  16. 2 2
      apps/app/src/components/Sidebar/SidebarNav/SecondaryItems.tsx
  17. 2 2
      apps/app/src/components/Sidebar/SidebarNav/SkeletonItem.module.scss
  18. 0 1
      apps/app/src/components/Sidebar/SidebarNav/_variables.scss
  19. 10 3
      apps/app/src/components/Sidebar/_button-styles.scss
  20. 1 0
      apps/app/src/components/Sidebar/_variables.scss
  21. 2 1
      apps/app/src/styles/_editor.scss
  22. 1 11
      apps/app/src/styles/_layout.scss
  23. 17 4
      packages/core/scss/_flex-expand.scss
  24. 0 17
      packages/core/scss/placeholders/_flex-expand.scss
  25. 1 1
      packages/editor/src/components/playground/Playground.tsx

+ 0 - 17
apps/app/_obsolete/src/components/Sidebar/NavigationResizeHexagon.tsx

@@ -1,17 +0,0 @@
-import React from 'react';
-
-export const NavigationResizeHexagon = React.memo((): JSX.Element => (
-  <svg
-    xmlns="http://www.w3.org/2000/svg"
-    viewBox="0 0 27.691 23.999"
-  >
-    <g className="background" transform="translate(0 0)">
-      <path d="M20.768,0l6.923,12L20.768,24H6.923L0,12,6.923,0Z" transform="translate(0)"></path>
-    </g>
-    <g className="icon" transform="translate(10 6)">
-      { /* eslint-disable-next-line max-len */ }
-      <path d="M2.124,9.114l5.28,5.34a.647.647,0,0,0,.922,0l.616-.623a.665.665,0,0,0,0-.932L4.759,8.648,8.943,4.4a.665.665,0,0,0,0-.932l-.616-.623a.647.647,0,0,0-.922,0l-5.28,5.34A.665.665,0,0,0,2.124,9.114Z" transform="translate(-1.933 -2.648)"></path>
-    </g>
-  </svg>
-));
-NavigationResizeHexagon.displayName = 'NavigationResizeHexagon';

+ 1 - 1
apps/app/src/components/SearchPage/SearchPageBase.tsx

@@ -169,7 +169,7 @@ const SearchPageBaseSubstance: ForwardRefRenderFunction<ISelectableAll & IReturn
     : undefined;
 
   return (
-    <div className="search-result-base flex-expand-horiz" data-testid="search-result-base">
+    <div className="search-result-base flex-grow-1 d-flex flex-expand-vh-100" data-testid="search-result-base">
 
       <div className="flex-expand-vert border boder-gray search-result-list" id="search-result-list">
 

+ 3 - 1
apps/app/src/components/SearchPage/SearchResultContent.tsx

@@ -31,6 +31,8 @@ import type { PageContentFooterProps } from '../PageContentFooter';
 
 import styles from './SearchResultContent.module.scss';
 
+const moduleClass = styles['search-result-content'];
+
 
 const SubNavButtons = dynamic(() => import('../PageControls').then(mod => mod.PageControls), { ssr: false });
 const RevisionLoader = dynamic<RevisionLoaderProps>(() => import('../Page/RevisionLoader').then(mod => mod.RevisionLoader), { ssr: false });
@@ -210,7 +212,7 @@ export const SearchResultContent: FC<Props> = (props: Props) => {
     <div
       key={page._id}
       data-testid="search-result-content"
-      className={`dynamic-layout-root ${growiLayoutFluidClass} search-result-content ${styles['search-result-content']}`}
+      className={`dynamic-layout-root ${growiLayoutFluidClass} ${moduleClass}`}
     >
       <RightComponent />
 

+ 46 - 0
apps/app/src/components/Sidebar/PageCreateButton/CreateButton.module.scss

@@ -0,0 +1,46 @@
+@use '~/styles/variables' as var;
+
+@use '../button-styles';
+
+.btn-create :global {
+  @extend %btn-basis;
+
+  // centering
+  .icon {
+    top: 50%;
+    left: 50%;
+    transform: translateX(-50%) translateY(-50%);
+  }
+}
+
+// pointer-events
+.btn-create :global {
+  pointer-events: none;
+
+  svg .background {
+    pointer-events: fill;
+  }
+}
+
+// == Colors
+.btn-create {
+  background-color: transparent !important;
+}
+
+.btn-create :global {
+  svg {
+    fill: var(--bs-btn-bg);
+  }
+}
+
+.btn-create:hover :global {
+  svg {
+    fill: var(--bs-btn-hover-bg);
+  }
+}
+
+.btn-create:active :global {
+  svg {
+    fill: var(--bs-btn-active-bg);
+  }
+}

+ 24 - 0
apps/app/src/components/Sidebar/PageCreateButton/CreateButton.tsx

@@ -0,0 +1,24 @@
+import type { ButtonHTMLAttributes, DetailedHTMLProps } from 'react';
+
+import { Hexagon } from './Hexagon';
+
+import styles from './CreateButton.module.scss';
+
+const moduleClass = styles['btn-create'];
+
+
+type Props = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
+
+export const CreateButton = (props: Props): JSX.Element => {
+  return (
+    <button
+      type="button"
+      {...props}
+      className={`${moduleClass} btn btn-primary ${props.className ?? ''}`}
+      data-testid="grw-sidebar-nav-page-create-button"
+    >
+      <Hexagon />
+      <span className="icon material-symbols-outlined position-absolute">edit</span>
+    </button>
+  );
+};

+ 3 - 3
apps/app/src/components/Sidebar/PageCreateButton/PageCreateButtonDropdownMenu.tsx → apps/app/src/components/Sidebar/PageCreateButton/DropendMenu.tsx

@@ -2,7 +2,7 @@ import React from 'react';
 
 import { useTranslation } from 'react-i18next';
 
-type PageCreateButtonDropdownMenuProps = {
+type DropendMenuProps = {
   todaysPath: string,
   onClickCreateNewPageButtonHandler: () => Promise<void>
   onClickCreateTodaysButtonHandler: () => Promise<void>
@@ -10,7 +10,7 @@ type PageCreateButtonDropdownMenuProps = {
   onClickTemplateForDescendantsButtonHandler: () => Promise<void>
 }
 
-export const PageCreateButtonDropdownMenu = React.memo((props: PageCreateButtonDropdownMenuProps): JSX.Element => {
+export const DropendMenu = React.memo((props: DropendMenuProps): JSX.Element => {
   const {
     todaysPath,
     onClickCreateNewPageButtonHandler,
@@ -66,4 +66,4 @@ export const PageCreateButtonDropdownMenu = React.memo((props: PageCreateButtonD
     </ul>
   );
 });
-PageCreateButtonDropdownMenu.displayName = 'PageCreateButtonDropdownMenu';
+DropendMenu.displayName = 'DropendMenu';

+ 60 - 0
apps/app/src/components/Sidebar/PageCreateButton/DropendToggle.module.scss

@@ -0,0 +1,60 @@
+@use '~/styles/variables' as var;
+
+@use '../button-styles';
+
+.btn-toggle :global {
+  @extend %btn-basis;
+
+  left: 12px;
+  padding: 0;
+
+  .icon {
+    top: 50%;
+    right: 0px;
+    font-size: 22px;
+    transform: translateY(-50%);
+  }
+}
+
+// no caret
+.btn-toggle {
+  &:global {
+    // no caret
+    &::after {
+      display: none !important;
+    }
+  }
+}
+
+// hitarea
+.btn-toggle :global {
+  .hitarea {
+    top: 0;
+    right: -10px;
+    bottom: 0;
+    left: 0;
+  }
+}
+
+// == Colors
+.btn-toggle {
+  background-color: transparent !important;
+}
+
+.btn-toggle :global {
+  svg {
+    fill: var(--grw-primary-400);
+  }
+}
+
+.btn-toggle:hover :global {
+  svg {
+    fill: var(--grw-primary-400);
+  }
+}
+
+.btn-toggle:active :global {
+  svg {
+    fill: var(--grw-primary-600);
+  }
+}

+ 24 - 0
apps/app/src/components/Sidebar/PageCreateButton/DropendToggle.tsx

@@ -0,0 +1,24 @@
+import type { ButtonHTMLAttributes, DetailedHTMLProps } from 'react';
+
+import { Hexagon } from './Hexagon';
+
+import styles from './DropendToggle.module.scss';
+
+const moduleClass = styles['btn-toggle'];
+
+
+type Props = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
+
+export const DropendToggle = (props: Props): JSX.Element => {
+  return (
+    <button
+      type="button"
+      {...props}
+      className={`${moduleClass} btn btn-primary ${props.className ?? ''}`}
+    >
+      <Hexagon />
+      <div className="hitarea position-absolute" />
+      <span className="icon material-symbols-outlined position-absolute">chevron_right</span>
+    </button>
+  );
+};

+ 18 - 0
apps/app/src/components/Sidebar/PageCreateButton/Hexagon.tsx

@@ -0,0 +1,18 @@
+import React from 'react';
+
+type Props = {
+  className?: string,
+}
+
+export const Hexagon = React.memo((props: Props): JSX.Element => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    viewBox="0 0 27.691 23.999"
+    height="36px"
+    className={props.className}
+  >
+    <g className="background" transform="translate(0 0)">
+      <path d="M20.768,0l6.923,12L20.768,24H6.923L0,12,6.923,0Z" transform="translate(0)"></path>
+    </g>
+  </svg>
+));

+ 2 - 0
apps/app/src/components/Sidebar/PageCreateButton/PageCreateButton.module.scss

@@ -0,0 +1,2 @@
+.grw-page-create-button :global {
+}

+ 12 - 17
apps/app/src/components/Sidebar/PageCreateButton/PageCreateButton.tsx

@@ -10,7 +10,9 @@ import { useCurrentUser } from '~/stores/context';
 import { useSWRxCurrentPage } from '~/stores/page';
 import loggerFactory from '~/utils/logger';
 
-import { PageCreateButtonDropdownMenu } from './PageCreateButtonDropdownMenu';
+import { DropendMenu } from './DropendMenu';
+import { CreateButton } from './CreateButton';
+import { DropendToggle } from './DropendToggle';
 
 const logger = loggerFactory('growi:cli:PageCreateButton');
 
@@ -175,27 +177,21 @@ export const PageCreateButton = React.memo((): JSX.Element => {
       onMouseEnter={onMouseEnterHandler}
       onMouseLeave={onMouseLeaveHandler}
     >
-      <div className="btn-group">
-        <button
-          className="d-block btn btn-primary"
+      <div className="btn-group flex-grow-1">
+        <CreateButton
+          className="z-2"
           onClick={onClickCreateNewPageButtonHandler}
-          type="button"
-          data-testid="grw-sidebar-nav-page-create-button"
           disabled={isCreating}
-        >
-          <i className="material-symbols-outlined">edit</i>
-        </button>
+        />
       </div>
-      {isHovered && (
-        <div className="btn-group dropend">
-          <button
-            className="btn btn-secondary dropdown-toggle dropdown-toggle-split position-absolute"
-            type="button"
+      { isHovered && (
+        <div className="btn-group dropend position-absolute">
+          <DropendToggle
+            className="dropdown-toggle dropdown-toggle-split"
             data-bs-toggle="dropdown"
             aria-expanded="false"
-            disabled={isCreating}
           />
-          <PageCreateButtonDropdownMenu
+          <DropendMenu
             todaysPath={todaysPath}
             onClickCreateNewPageButtonHandler={onClickCreateNewPageButtonHandler}
             onClickCreateTodaysButtonHandler={onClickCreateTodaysButtonHandler}
@@ -207,4 +203,3 @@ export const PageCreateButton = React.memo((): JSX.Element => {
     </div>
   );
 });
-PageCreateButton.displayName = 'PageCreateButton';

+ 1 - 1
apps/app/src/components/Sidebar/SidebarHead/ToggleCollapseButton.module.scss

@@ -5,7 +5,7 @@
 @use '../button-styles';
 
 .btn-toggle-collapse :global {
-  @extend %btn-primary-basis;
+  @extend %btn-basis;
 
   $height: var.$grw-sidebar-nav-width; // declare $height with the same value as the sidebar nav width
   height: $height;

+ 3 - 6
apps/app/src/components/Sidebar/SidebarNav/PrimaryItems.module.scss

@@ -1,15 +1,12 @@
 @use '@growi/core/scss/bootstrap/init' as bs;
 
-@use '~/styles/variables' as var;
 @use '../button-styles';
 
-@use './variables' as sidebarNavVar;
+@use '../variables' as sidebarVar;
 
 .grw-primary-items :global {
   .btn {
-    @extend %btn-primary-basis;
-
-    height: sidebarNavVar.$grw-sidebar-primary-button-height;
+    @extend %btn-basis;
 
     i {
       opacity: 0.7;
@@ -24,7 +21,7 @@
 
 // Add indicator
 .grw-primary-items :global {
-  $btn-height: sidebarNavVar.$grw-sidebar-primary-button-height;
+  $btn-height: sidebarVar.$grw-sidebar-button-height;
   $btn-active-indicator-height: 34px;
 
   .btn {

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

@@ -74,7 +74,7 @@ const PrimaryItem: FC<PrimaryItemProps> = (props: PrimaryItemProps) => {
     <button
       type="button"
       data-testid={`grw-sidebar-nav-primary-${labelForTestId}`}
-      className={`d-block btn btn-primary ${indicatorClass}`}
+      className={`btn btn-primary ${indicatorClass}`}
       onClick={itemClickedHandler}
       onMouseEnter={mouseEnteredHandler}
     >

+ 2 - 5
apps/app/src/components/Sidebar/SidebarNav/SecondaryItems.module.scss

@@ -2,15 +2,12 @@
 
 @use '../button-styles';
 
-@use './variables' as sidebarNavVar;
 
 .grw-secondary-items :global {
   .btn {
-    @extend %btn-primary-basis;
+    @extend %btn-basis;
 
-    height: sidebarNavVar.$grw-sidebar-primary-button-height;
-
-    i {
+    span {
       opacity: 0.6;
 
       &:hover,

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

@@ -29,11 +29,11 @@ const SecondaryItem: FC<SecondaryItemProps> = (props: SecondaryItemProps) => {
   return (
     <Link
       href={href}
-      className="d-block btn btn-primary"
+      className="d-block btn btn-primary d-flex align-items-center justify-content-center"
       target={`${isBlank ? '_blank' : ''}`}
       prefetch={false}
     >
-      <i className="material-symbols-outlined">{iconName}</i>
+      <span className="material-symbols-outlined">{iconName}</span>
     </Link>
   );
 };

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

@@ -1,9 +1,9 @@
 @use '@growi/core/scss/bootstrap/init' as bs;
 
-@use './variables' as sidebarNavVar;
+@use '../variables' as sidebarVar;
 
 .grw-skeleton-item :global {
-  height: sidebarNavVar.$grw-sidebar-primary-button-height;
+  height: sidebarVar.$grw-sidebar-button-height;
   padding: .75rem;
 
   .grw-skeleton {

+ 0 - 1
apps/app/src/components/Sidebar/SidebarNav/_variables.scss

@@ -1 +0,0 @@
-$grw-sidebar-primary-button-height: 50px;

+ 10 - 3
apps/app/src/components/Sidebar/_button-styles.scss

@@ -1,8 +1,15 @@
 @use '~/styles/variables' as var;
 
-%btn-primary-basis {
-  padding-top: .75rem;
-  padding-bottom: .75rem;
+@use './variables' as sidebarVar;
+
+
+%btn-basis {
+  --bs-btn-padding-x: 0;
+  --bs-btn-padding-y: 0;
+
+  width: var.$grw-sidebar-nav-width;
+  height: sidebarVar.$grw-sidebar-button-height;
+
   line-height: 1em;
   border: 0;
   border-radius: 0;

+ 1 - 0
apps/app/src/components/Sidebar/_variables.scss

@@ -0,0 +1 @@
+$grw-sidebar-button-height: 50px;

+ 2 - 1
apps/app/src/styles/_editor.scss

@@ -1,4 +1,5 @@
 @use '@growi/core/scss/bootstrap/init' as bs;
+
 @use './variables' as var;
 
 @import './organisms/wiki-custom-sidebar';
@@ -27,7 +28,7 @@
    *****************/
   .dynamic-layout-root {
     width: calc(100vw - var.$grw-sidebar-nav-width);
-    height: 100vh;
+    @extend .flex-expand-vh-100;
   }
 
 

+ 1 - 11
apps/app/src/styles/_layout.scss

@@ -1,19 +1,9 @@
 @use '@growi/core/scss/bootstrap/init' as bs;
-@use '@growi/core/scss/flex-expand';
 
 @use './variables' as var;
 
-.flex-expand-horiz {
-  @extend %flex-expand-horiz;
-}
-
-.flex-expand-vert {
-  @extend %flex-expand-vert;
-}
-
 .dynamic-layout-root {
-  @extend %flex-expand-vert;
-  overflow-y: unset;
+  @extend .flex-expand-vert;
 }
 
 .dynamic-layout-root.growi-layout-fluid .grw-container-convertible {

+ 17 - 4
packages/core/scss/_flex-expand.scss

@@ -1,9 +1,22 @@
-@use './placeholders/flex-expand';
-
 .flex-expand-horiz {
-  @extend %flex-expand-horiz;
+  display: flex;
+  flex-direction: row;
+  flex-grow: 1;
+  height: 100%;
 }
 
 .flex-expand-vert {
-  @extend %flex-expand-vert;
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  height: 100%;
+}
+
+.flex-expand-vh-100 {
+  height: 100vh;
+
+  .flex-expand-horiz,
+  .flex-expand-vert {
+    overflow-y: auto;
+  }
 }

+ 0 - 17
packages/core/scss/placeholders/_flex-expand.scss

@@ -1,17 +0,0 @@
-// ref: https://discuss.codemirror.net/t/how-to-fit-the-codemirror-6-widget-into-a-flex-div/4207/4
-%flex-expand-horiz {
-  display: flex;
-  flex-direction: row;
-  flex-grow: 1;
-  height: 100%;
-  overflow-y: auto;
-}
-
-// ref: https://discuss.codemirror.net/t/how-to-fit-the-codemirror-6-widget-into-a-flex-div/4207/4
-%flex-expand-vert {
-  display: flex;
-  flex: 1;
-  flex-direction: column;
-  height: 100%;
-  overflow-y: auto;
-}

+ 1 - 1
packages/editor/src/components/playground/Playground.tsx

@@ -49,7 +49,7 @@ export const Playground = (): JSX.Element => {
   }, [codeMirrorEditor]);
 
   return (
-    <div className="d-flex flex-column vw-100 vh-100">
+    <div className="d-flex flex-column vw-100 flex-expand-vh-100">
       <div className="flex-expand-vert justify-content-center align-items-center bg-dark" style={{ minHeight: '83px' }}>
         <div className="text-white">GrowiSubNavigation</div>
       </div>