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

replace wave effect with react-use-ripple

Yuki Takei 3 лет назад
Родитель
Сommit
da837dc05d

+ 1 - 0
packages/app/package.json

@@ -233,6 +233,7 @@
     "react-dropzone": "^11.2.4",
     "react-frame-component": "^4.0.0",
     "react-hotkeys": "^2.0.0",
+    "react-use-ripple": "^1.5.2",
     "react-waypoint": "^10.1.0",
     "reactstrap": "^8.9.0",
     "replacestream": "^4.0.3",

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/app/src/client/legacy/thirdparty-js/waves.js


+ 9 - 3
packages/app/src/components/Fab.jsx

@@ -1,8 +1,10 @@
-import React, { useState, useCallback, useEffect } from 'react';
+import React, {
+  useState, useCallback, useEffect, useRef,
+} from 'react';
 
+import { useRipple } from 'react-use-ripple';
 import StickyEvents from 'sticky-events';
 
-
 import { smoothScrollIntoView } from '~/client/util/smooth-scroll';
 import { useCurrentPagePath, useCurrentUser } from '~/stores/context';
 import { usePageCreateModal } from '~/stores/modal';
@@ -22,6 +24,9 @@ const Fab = () => {
   const [animateClasses, setAnimateClasses] = useState('invisible');
   const [buttonClasses, setButtonClasses] = useState('');
 
+  // ripple
+  const createBtnRef = useRef(null);
+  useRipple(createBtnRef, { rippleColor: 'rgba(255, 255, 255, 0.3)' });
 
   const stickyChangeHandler = useCallback((event) => {
     logger.debug('StickyEvents.CHANGE detected');
@@ -54,7 +59,8 @@ const Fab = () => {
         <div className={`rounded-circle position-absolute ${animateClasses}`} style={{ bottom: '2.3rem', right: '4rem' }}>
           <button
             type="button"
-            className={`btn btn-lg btn-create-page btn-primary rounded-circle p-0 waves-effect waves-light ${buttonClasses}`}
+            className={`btn btn-lg btn-create-page btn-primary rounded-circle p-0 ${buttonClasses}`}
+            ref={createBtnRef}
             onClick={() => openCreateModal(currentPath)}
           >
             <CreatePageIcon />

+ 7 - 4
packages/app/src/components/InAppNotification/InAppNotificationDropdown.tsx

@@ -1,12 +1,12 @@
-import React, {
-  useState, useEffect, FC, useCallback,
-} from 'react';
+import React, { useState, useEffect, useRef } from 'react';
 
 import { useTranslation } from 'next-i18next';
+import { useRipple } from 'react-use-ripple';
 import {
   Dropdown, DropdownToggle, DropdownMenu, DropdownItem,
 } from 'reactstrap';
 
+
 import { toastError } from '~/client/util/apiNotification';
 import { apiv3Post } from '~/client/util/apiv3-client';
 import { useSWRxInAppNotifications, useSWRxInAppNotificationStatus } from '~/stores/in-app-notification';
@@ -29,6 +29,9 @@ export const InAppNotificationDropdown = (): JSX.Element => {
   const { data: inAppNotificationData, mutate: mutateInAppNotificationData } = useSWRxInAppNotifications(limit);
   const { data: inAppNotificationUnreadStatusCount, mutate: mutateInAppNotificationUnreadStatusCount } = useSWRxInAppNotificationStatus();
 
+  // ripple
+  const buttonRef = useRef(null);
+  useRipple(buttonRef, { rippleColor: 'rgba(255, 255, 255, 0.3)' });
 
   const updateNotificationStatus = async() => {
     try {
@@ -77,7 +80,7 @@ export const InAppNotificationDropdown = (): JSX.Element => {
 
   return (
     <Dropdown className="notification-wrapper grw-notification-dropdown" isOpen={isOpen} toggle={toggleDropdownHandler}>
-      <DropdownToggle tag="a" className="px-3 nav-link border-0 bg-transparent waves-effect waves-light">
+      <DropdownToggle tag="a" className="px-3 nav-link border-0 bg-transparentt" innerRef={buttonRef}>
         <i className="icon-bell" /> {badge}
       </DropdownToggle>
       <DropdownMenu right>

+ 11 - 2
packages/app/src/components/Navbar/AppearanceModeDropdown.tsx

@@ -1,6 +1,9 @@
-import React, { FC, useState, useCallback } from 'react';
+import React, {
+  FC, useState, useCallback, useRef,
+} from 'react';
 
 import { useTranslation } from 'next-i18next';
+import { useRipple } from 'react-use-ripple';
 import { UncontrolledTooltip } from 'reactstrap';
 
 import { useUserUISettings } from '~/client/services/user-ui-settings';
@@ -35,6 +38,10 @@ export const AppearanceModeDropdown:FC<AppearanceModeDropdownProps> = (props: Ap
   const { data: isPreferDrawerModeOnEdit, mutate: mutatePreferDrawerModeOnEdit } = usePreferDrawerModeOnEditByUser();
   const { scheduleToPut } = useUserUISettings();
 
+  // ripple
+  const buttonRef = useRef(null);
+  useRipple(buttonRef, { rippleColor: 'rgba(255, 255, 255, 0.3)' });
+
   const preferDrawerModeSwitchModifiedHandler = useCallback((preferDrawerMode: boolean, isEditMode: boolean) => {
     if (isEditMode) {
       mutatePreferDrawerModeOnEdit(preferDrawerMode);
@@ -110,7 +117,9 @@ export const AppearanceModeDropdown:FC<AppearanceModeDropdownProps> = (props: Ap
   return (
     <>
       {/* setting button */}
-      <button className="bg-transparent border-0 nav-link" type="button" data-toggle="dropdown" aria-haspopup="true">
+      {/* remove .dropdown-toggle for hide caret */}
+      {/* See https://stackoverflow.com/a/44577512/13183572 */}
+      <button className="bg-transparent border-0 nav-link" type="button" data-toggle="dropdown" ref={buttonRef} aria-haspopup="true">
         <i className="icon-settings"></i>
       </button>
 

+ 10 - 2
packages/app/src/components/Navbar/GrowiNavbar.tsx

@@ -1,8 +1,11 @@
-import React, { FC, memo, useMemo } from 'react';
+import React, {
+  FC, memo, useMemo, useRef,
+} from 'react';
 
 import { isServer } from '@growi/core';
 import { useTranslation } from 'next-i18next';
 import dynamic from 'next/dynamic';
+import { useRipple } from 'react-use-ripple';
 import { UncontrolledTooltip } from 'reactstrap';
 
 import { HasChildren } from '~/interfaces/common';
@@ -36,6 +39,10 @@ const NavbarRight = memo((): JSX.Element => {
   const { data: currentPagePath } = useCurrentPagePath();
   const { data: isGuestUser } = useIsGuestUser();
 
+  // ripple
+  const newButtonRef = useRef(null);
+  useRipple(newButtonRef, { rippleColor: 'rgba(255, 255, 255, 0.3)' });
+
   const { open: openCreateModal } = usePageCreateModal();
 
   const isAuthenticated = isGuestUser === false;
@@ -51,6 +58,7 @@ const NavbarRight = memo((): JSX.Element => {
           <button
             className="px-md-3 nav-link btn-create-page border-0 bg-transparent"
             type="button"
+            ref={newButtonRef}
             data-testid="newPageBtn"
             onClick={() => openCreateModal(currentPagePath || '')}
           >
@@ -80,7 +88,7 @@ const NavbarRight = memo((): JSX.Element => {
         <li id="login-user" className="nav-item"><a className="nav-link" href="/login">Login</a></li>;
       </>
     );
-  }, []);
+  }, [AppearanceModeDropdown, isAuthenticated]);
 
   return (
     <>

+ 8 - 3
packages/app/src/components/Navbar/PersonalDropdown.jsx

@@ -1,7 +1,8 @@
-import React from 'react';
+import React, { useRef } from 'react';
 
 import { UserPicture } from '@growi/ui';
 import { useTranslation } from 'next-i18next';
+import { useRipple } from 'react-use-ripple';
 
 import { toastError } from '~/client/util/apiNotification';
 import { apiv3Post } from '~/client/util/apiv3-client';
@@ -11,6 +12,10 @@ const PersonalDropdown = () => {
   const { t } = useTranslation();
   const { data: currentUser } = useCurrentUser();
 
+  // ripple
+  const buttonRef = useRef(null);
+  useRipple(buttonRef, { rippleColor: 'rgba(255, 255, 255, 0.3)' });
+
   const user = currentUser || {};
 
   const logoutHandler = async() => {
@@ -28,9 +33,9 @@ const PersonalDropdown = () => {
       {/* Button */}
       {/* remove .dropdown-toggle for hide caret */}
       {/* See https://stackoverflow.com/a/44577512/13183572 */}
-      <a className="px-md-3 nav-link waves-effect waves-light" data-toggle="dropdown">
+      <button className="bg-transparent border-0 nav-link" type="button" ref={buttonRef} data-toggle="dropdown">
         <UserPicture user={user} noLink noTooltip /><span className="ml-1 d-none d-lg-inline-block">&nbsp;{user.name}</span>
-      </a>
+      </button>
 
       {/* Menu */}
       <div className="dropdown-menu dropdown-menu-right">

+ 4 - 4
packages/app/src/components/PageEditorByHackmd.jsx

@@ -1,7 +1,7 @@
 import React from 'react';
 
-import PropTypes from 'prop-types';
 import { useTranslation } from 'next-i18next';
+import PropTypes from 'prop-types';
 
 
 import AppContainer from '~/client/services/AppContainer';
@@ -311,7 +311,7 @@ class PageEditorByHackmd extends React.Component {
           { !isHackmdDocumentOutdated && (
             <div className="text-center hackmd-resume-button-container mb-3">
               <button
-                className="btn btn-success btn-lg waves-effect waves-light"
+                className="btn btn-success btn-lg"
                 type="button"
                 disabled={this.state.isInitializing}
                 onClick={() => { return this.resumeToEdit() }}
@@ -324,7 +324,7 @@ class PageEditorByHackmd extends React.Component {
 
           <div className="text-center hackmd-discard-button-container mb-3">
             <button
-              className="btn btn-outline-secondary btn-lg waves-effect waves-light"
+              className="btn btn-outline-secondary btn-lg"
               type="button"
               onClick={() => { return this.discardChanges() }}
             >
@@ -347,7 +347,7 @@ class PageEditorByHackmd extends React.Component {
           <p className="text-muted text-center hackmd-status-label"><i className="fa fa-file-text"></i> HackMD is READY!</p>
           <div className="text-center hackmd-start-button-container mb-3">
             <button
-              className="btn btn-info btn-lg waves-effect waves-light"
+              className="btn btn-info btn-lg"
               type="button"
               disabled={isRevisionOutdated || this.state.isInitializing}
               onClick={() => { return this.startToEdit() }}

+ 0 - 149
packages/app/src/styles/_waves.scss

@@ -1,149 +0,0 @@
-/*Wave Effeects*/
-$gradient: rgba(255, 255, 255, 0.2) 0, rgba(255, 255, 255, 0.3) 40%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0) 70%;
-
-@mixin waves-transition($transition) {
-  -webkit-transition: $transition;
-  -moz-transition: $transition;
-  -o-transition: $transition;
-  transition: $transition;
-}
-
-@mixin waves-transform($string) {
-  -webkit-transform: $string;
-  -moz-transform: $string;
-  -ms-transform: $string;
-  -o-transform: $string;
-  transform: $string;
-}
-
-@mixin waves-box-shadow($shadow) {
-  -webkit-box-shadow: $shadow;
-  box-shadow: $shadow;
-}
-
-.waves-effect {
-  position: relative;
-  display: inline-block;
-  overflow: hidden;
-  cursor: pointer;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-  -webkit-tap-highlight-color: transparent;
-
-  .waves-ripple {
-    position: absolute;
-    width: 20px;
-    height: 20px;
-    margin-top: -10px;
-    margin-left: -10px;
-    pointer-events: none;
-    background: rgba(0, 0, 0, 0.08);
-    border-radius: 50%;
-    opacity: 0;
-    -webkit-transition-property: -webkit-transform, opacity;
-    -moz-transition-property: -moz-transform, opacity;
-    -o-transition-property: -o-transform, opacity;
-    transition-property: transform, opacity;
-    -webkit-transform: scale(0);
-    -moz-transform: scale(0);
-    -ms-transform: scale(0);
-    -o-transform: scale(0);
-    transform: scale(0);
-    @include waves-transition(all 0.5s ease-out);
-    @include waves-transform(scale(0) translate(0, 0));
-  }
-
-  &.waves-light .waves-ripple {
-    background: rgba(255, 255, 255, 0.4);
-    background: -webkit-radial-gradient($gradient);
-    background: -o-radial-gradient($gradient);
-    background: -moz-radial-gradient($gradient);
-    background: radial-gradient($gradient);
-  }
-
-  &.waves-classic .waves-ripple {
-    background: rgba(0, 0, 0, 0.2);
-  }
-
-  &.waves-classic.waves-light .waves-ripple {
-    background: rgba(255, 255, 255, 0.4);
-  }
-}
-
-.waves-notransition {
-  @include waves-transition(none '!important');
-}
-
-.waves-button,
-.waves-circle {
-  @include waves-transform(translateZ(0));
-  -webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%);
-}
-
-.waves-button,
-.waves-button:hover,
-.waves-button:visited,
-.waves-button-input {
-  z-index: 1;
-  font-size: 1em;
-  line-height: 1em;
-  color: inherit;
-  text-align: center;
-  text-decoration: none;
-  white-space: nowrap;
-  vertical-align: middle;
-  cursor: pointer;
-  background-color: rgba(0, 0, 0, 0);
-  border: none;
-  outline: none;
-}
-
-.waves-button {
-  padding: 0.85em 1.1em;
-  border-radius: 0.2em;
-}
-
-.waves-button-input {
-  padding: 0.85em 1.1em;
-  margin: 0;
-}
-
-.waves-input-wrapper {
-  vertical-align: bottom;
-  border-radius: 0.2em;
-
-  &.waves-button {
-    padding: 0;
-  }
-
-  .waves-button-input {
-    position: relative;
-    top: 0;
-    left: 0;
-    z-index: 1;
-  }
-}
-
-.waves-circle {
-  width: 2.5em;
-  height: 2.5em;
-  line-height: 2.5em;
-  text-align: center;
-  border-radius: 50%;
-}
-
-.waves-float {
-  mask-image: none;
-  @include waves-box-shadow(0px 1px 1.5px 1px rgba(0, 0, 0, 0.12));
-  @include waves-transition(all 300ms);
-
-  &:active {
-    @include waves-box-shadow(0px 8px 20px 1px rgba(0, 0, 0, 0.3));
-  }
-}
-
-.waves-block {
-  display: block;
-}

+ 5 - 0
yarn.lock

@@ -16812,6 +16812,11 @@ react-transition-group@^2.2.1, react-transition-group@^2.3.1:
     prop-types "^15.6.2"
     react-lifecycles-compat "^3.0.4"
 
+react-use-ripple@^1.5.2:
+  version "1.5.2"
+  resolved "https://registry.yarnpkg.com/react-use-ripple/-/react-use-ripple-1.5.2.tgz#f42600a0c7729510c3dbba74e0c86ed6c55fd88e"
+  integrity sha512-pK7PLEaEGJ4xCM5acxW+ua7ba0lqxbhNzBHzEw+MoD0yVFT3r8SkfkG6aSpiEm4iLZO9HOeSnUz+1k7YVuYX5w==
+
 react-view-pager@^0.6.0:
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/react-view-pager/-/react-view-pager-0.6.0.tgz#6c6be04b0cc3b907b5ceafec7b2ab6e7228df650"

Некоторые файлы не были показаны из-за большого количества измененных файлов