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

Merge pull request #7984 from weseek/support/reactstrap-version-up

support: Upgrade to reactstrap v9
Yuki Takei 2 лет назад
Родитель
Сommit
b4a430044f
38 измененных файлов с 80 добавлено и 438 удалено
  1. 15 13
      apps/app/_obsolete/src/components/PageEditor/ConflictDiffModal.tsx
  2. 1 1
      apps/app/package.json
  3. 1 1
      apps/app/src/components/Admin/Users/UserMenu.tsx
  4. 4 4
      apps/app/src/components/BookmarkButtons.tsx
  5. 0 1
      apps/app/src/components/Bookmarks/BookmarkFolderItemControl.tsx
  6. 2 5
      apps/app/src/components/Bookmarks/BookmarkFolderMenu.tsx
  7. 0 1
      apps/app/src/components/Bookmarks/BookmarkItem.tsx
  8. 4 7
      apps/app/src/components/Common/Dropdown/PageItemControl.tsx
  9. 3 6
      apps/app/src/components/DescendantsPageListModal.tsx
  10. 1 3
      apps/app/src/components/ExpandOrContractButton.tsx
  11. 2 2
      apps/app/src/components/InAppNotification/InAppNotificationDropdown.tsx
  12. 1 1
      apps/app/src/components/Navbar/SubNavButtons.tsx
  13. 1 2
      apps/app/src/components/Page/CopyDropdown.jsx
  14. 3 5
      apps/app/src/components/PageAccessoriesModal/PageAccessoriesModal.tsx
  15. 1 4
      apps/app/src/components/PageEditor/HandsontableModal.tsx
  16. 3 4
      apps/app/src/components/PageList/PageListItemL.tsx
  17. 1 1
      apps/app/src/components/RevisionComparer/RevisionComparer.tsx
  18. 1 1
      apps/app/src/components/SavePageControls.tsx
  19. 4 6
      apps/app/src/components/SearchPage/OperateAllControl.tsx
  20. 1 1
      apps/app/src/components/Sidebar/PageTree/PageTreeSubstance.tsx
  21. 1 1
      apps/app/src/components/Sidebar/SidebarBrandLogo.tsx
  22. 1 1
      packages/ui/package.json
  23. 0 13
      packages/ui/src/interfaces/popper-data.ts
  24. 0 1
      packages/ui/src/utils/index.ts
  25. 0 34
      packages/ui/src/utils/reactstrap-modifiers.ts
  26. 0 14
      tools/replacer/.eslintrc.cjs
  27. 0 24
      tools/replacer/.gitignore
  28. 0 13
      tools/replacer/index.html
  29. 0 28
      tools/replacer/package.json
  30. 0 49
      tools/replacer/src/App.css
  31. 0 47
      tools/replacer/src/App.tsx
  32. 0 69
      tools/replacer/src/index.css
  33. 0 10
      tools/replacer/src/main.tsx
  34. 0 1
      tools/replacer/src/vite-env.d.ts
  35. 0 24
      tools/replacer/tsconfig.json
  36. 0 10
      tools/replacer/tsconfig.node.json
  37. 0 7
      tools/replacer/vite.config.ts
  38. 29 23
      yarn.lock

+ 15 - 13
apps/app/_obsolete/src/components/PageEditor/ConflictDiffModal.tsx

@@ -130,18 +130,19 @@ const ConflictDiffModalCore = (props: ConflictDiffModalCoreProps): JSX.Element =
 
   }, [afterResolvedHandler, close, currentPagePath, currentPathname, optionsToSave, pageId, remoteRevisionId, saveOrUpdate, setRemoteLatestPageData]);
 
-  const resizeAndCloseButtons = useMemo(() => (
-    <div className="d-flex flex-nowrap">
-      <ExpandOrContractButton
-        isWindowExpanded={isModalExpanded}
-        expandWindow={() => setIsModalExpanded(true)}
-        contractWindow={() => setIsModalExpanded(false)}
-      />
-      <button type="button" className="close text-white" onClick={close} aria-label="Close">
-        <span aria-hidden="true">&times;</span>
-      </button>
-    </div>
-  ), [isModalExpanded, close]);
+  // TODO: No longer support custom close icon in bootstrap v5
+  // const resizeAndCloseButtons = useMemo(() => (
+  //   <div className="d-flex flex-nowrap">
+  //     <ExpandOrContractButton
+  //       isWindowExpanded={isModalExpanded}
+  //       expandWindow={() => setIsModalExpanded(true)}
+  //       contractWindow={() => setIsModalExpanded(false)}
+  //     />
+  //     <button type="button" className="close text-white" onClick={close} aria-label="Close">
+  //       <span aria-hidden="true">&times;</span>
+  //     </button>
+  //   </div>
+  // ), [isModalExpanded, close]);
 
   const isOpen = props.isOpen ?? false;
 
@@ -153,7 +154,8 @@ const ConflictDiffModalCore = (props: ConflictDiffModalCoreProps): JSX.Element =
       className={`${isModalExpanded ? ' grw-modal-expanded' : ''}`}
       size="xl"
     >
-      <ModalHeader tag="h4" toggle={onClose} className="bg-primary text-light align-items-center py-3" close={resizeAndCloseButtons}>
+      {/* <ModalHeader tag="h4" toggle={onClose} className="bg-primary text-light align-items-center py-3" close={resizeAndCloseButtons}> */}
+      <ModalHeader tag="h4" toggle={onClose} className="bg-primary text-light align-items-center py-3">
         <i className="icon-fw icon-exclamation" />{t('modal_resolve_conflict.resolve_conflict')}
       </ModalHeader>
       <ModalBody className="mx-4 my-1">

+ 1 - 1
apps/app/package.json

@@ -174,7 +174,7 @@
     "react-syntax-highlighter": "^15.5.0",
     "react-toastify": "^9.1.1",
     "react-use-ripple": "^1.5.2",
-    "reactstrap": "^8.10.1",
+    "reactstrap": "^9.2.0",
     "reconnecting-websocket": "^4.4.0",
     "redis": "^3.0.2",
     "rehype-katex": "^6.0.2",

+ 1 - 1
apps/app/src/components/Admin/Users/UserMenu.tsx

@@ -99,7 +99,7 @@ const UserMenu = (props: UserMenuProps) => {
         {(user.status === USER_STATUS.INVITED && !isInvitationEmailSended)
         && <i className={`fa fa-circle text-danger grw-usermenu-notification-icon ${styles['grw-usermenu-notification-icon']}`} />}
       </DropdownToggle>
-      <DropdownMenu positionFixed>
+      <DropdownMenu strategy="fixed">
         {renderEditMenu()}
         {user.status !== USER_STATUS.DELETED && renderStatusMenu()}
         {user.status === USER_STATUS.ACTIVE && renderAdminMenu()}

+ 4 - 4
apps/app/src/components/BookmarkButtons.tsx

@@ -3,10 +3,10 @@ import React, {
 } from 'react';
 
 import { useTranslation } from 'next-i18next';
-import DropdownToggle from 'reactstrap/es/DropdownToggle';
-import Popover from 'reactstrap/es/Popover';
-import PopoverBody from 'reactstrap/es/PopoverBody';
-import UncontrolledTooltip from 'reactstrap/es/UncontrolledTooltip';
+import DropdownToggle from 'reactstrap/esm/DropdownToggle';
+import Popover from 'reactstrap/esm/Popover';
+import PopoverBody from 'reactstrap/esm/PopoverBody';
+import UncontrolledTooltip from 'reactstrap/esm/UncontrolledTooltip';
 
 import { useSWRxBookmarkedUsers } from '~/stores/bookmark';
 import { useIsGuestUser } from '~/stores/context';

+ 0 - 1
apps/app/src/components/Bookmarks/BookmarkFolderItemControl.tsx

@@ -27,7 +27,6 @@ export const BookmarkFolderItemControl: React.FC<{
         </DropdownToggle>
       ) }
       <DropdownMenu
-        modifiers={{ preventOverflow: { boundariesElement: 'viewport' } }}
         container="body"
         style={{ zIndex: 1055 }} /* make it larger than $zindex-modal of bootstrap */
       >

+ 2 - 5
apps/app/src/components/Bookmarks/BookmarkFolderMenu.tsx

@@ -1,6 +1,5 @@
 import React, { useCallback, useMemo, useState } from 'react';
 
-// import { getCustomModifiers } from '@growi/ui/dist/utils';
 import { useTranslation } from 'next-i18next';
 import { DropdownItem, DropdownMenu, UncontrolledDropdown } from 'reactstrap';
 
@@ -191,12 +190,10 @@ export const BookmarkFolderMenu = (props: BookmarkFolderMenuProps): JSX.Element
     >
       {children}
       <DropdownMenu
-        right
+        end
         persist
-        positionFixed
+        strategy="fixed"
         className="grw-bookmark-folder-menu"
-        // TODO: activate (https://redmine.weseek.co.jp/issues/128468)
-        // modifiers={getCustomModifiers(true)}
       >
         { renderBookmarkMenuItem() }
       </DropdownMenu>

+ 0 - 1
apps/app/src/components/Bookmarks/BookmarkItem.tsx

@@ -186,7 +186,6 @@ export const BookmarkItem = (props: Props): JSX.Element => {
         </div>
 
         <UncontrolledTooltip
-          modifiers={{ preventOverflow: { boundariesElement: 'window' } }}
           autohide={false}
           placement="right"
           target={bookmarkItemId}

+ 4 - 7
apps/app/src/components/Common/Dropdown/PageItemControl.tsx

@@ -5,7 +5,6 @@ import React, {
 import {
   type IPageInfoAll, isIPageInfoForOperation,
 } from '@growi/core';
-// import { getCustomModifiers } from '@growi/ui/dist/utils';
 import { useTranslation } from 'next-i18next';
 import {
   Dropdown, DropdownMenu, DropdownToggle, DropdownItem,
@@ -51,7 +50,7 @@ type CommonProps = {
   additionalMenuItemOnTopRenderer?: React.FunctionComponent<AdditionalMenuItemsRendererProps>,
   additionalMenuItemRenderer?: React.FunctionComponent<AdditionalMenuItemsRendererProps>,
   isInstantRename?: boolean,
-  alignRight?: boolean,
+  alignEnd?: boolean,
 }
 
 
@@ -70,7 +69,7 @@ const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.E
     onClickRevertMenuItem, onClickPathRecoveryMenuItem,
     additionalMenuItemOnTopRenderer: AdditionalMenuItemsOnTop,
     additionalMenuItemRenderer: AdditionalMenuItems,
-    isInstantRename, alignRight,
+    isInstantRename, alignEnd,
   } = props;
 
   // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -252,11 +251,9 @@ const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.E
   return (
     <DropdownMenu
       data-testid="page-item-control-menu"
-      right={alignRight}
-      // TODO: activate (https://redmine.weseek.co.jp/issues/128468)
-      // modifiers={getCustomModifiers(alignRight)}
+      end={alignEnd}
       container="body"
-      persist={!!alignRight}
+      persist={!!alignEnd}
       style={{ zIndex: 1055 }} /* make it larger than $zindex-modal of bootstrap */
     >
       {contents}

+ 3 - 6
apps/app/src/components/DescendantsPageListModal.tsx

@@ -71,19 +71,16 @@ export const DescendantsPageListModal = (): JSX.Element => {
   }, [isSharedUser, status, t]);
 
   const buttons = useMemo(() => (
-    <div className="d-flex flex-nowrap">
+    <span className="me-3">
       <ExpandOrContractButton
         isWindowExpanded={isWindowExpanded}
         expandWindow={() => setIsWindowExpanded(true)}
         contractWindow={() => setIsWindowExpanded(false)}
       />
-      <button type="button" className="close" onClick={close} aria-label="Close">
-        <span aria-hidden="true">&times;</span>
-      </button>
-    </div>
+      <button type="button" className="btn btn-close" onClick={close} aria-label="Close"></button>
+    </span>
   ), [close, isWindowExpanded]);
 
-
   if (status == null) {
     return <></>;
   }

+ 1 - 3
apps/app/src/components/ExpandOrContractButton.tsx

@@ -1,6 +1,5 @@
 import React, { FC } from 'react';
 
-
 type Props = {
   isWindowExpanded: boolean,
   contractWindow?: () => void,
@@ -25,10 +24,9 @@ const ExpandOrContractButton: FC<Props> = (props: Props) => {
   return (
     <button
       type="button"
-      className="close"
+      className={`btn ${isWindowExpanded ? 'icon-size-actual' : 'icon-size-fullscreen'}`}
       onClick={isWindowExpanded ? clickContractButtonHandler : clickExpandButtonHandler}
     >
-      <i className={`${isWindowExpanded ? 'icon-size-actual' : 'icon-size-fullscreen'}`} style={{ fontSize: '0.8em' }} aria-hidden="true"></i>
     </button>
   );
 };

+ 2 - 2
apps/app/src/components/InAppNotification/InAppNotificationDropdown.tsx

@@ -82,11 +82,11 @@ export const InAppNotificationDropdown = (): JSX.Element => {
   }
 
   return (
-    <Dropdown className="notification-wrapper grw-notification-dropdown" isOpen={isOpen} toggle={toggleDropdownHandler} direction="right">
+    <Dropdown className="notification-wrapper grw-notification-dropdown" isOpen={isOpen} toggle={toggleDropdownHandler} direction="end">
       <DropdownToggle className="px-3 nav-link border-0 bg-transparent" innerRef={buttonRef}>
         <i className="icon-bell" /> {badge}
       </DropdownToggle>
-      <DropdownMenu right>
+      <DropdownMenu end>
         { inAppNotificationData != null && inAppNotificationData.docs.length === 0
           // no items
           ? <DropdownItem disabled>{t('in_app_notification.mark_all_as_read')}</DropdownItem>

+ 1 - 1
apps/app/src/components/Navbar/SubNavButtons.tsx

@@ -245,7 +245,7 @@ const SubNavButtonsSubstance = (props: SubNavButtonsSubstanceProps): JSX.Element
       ) }
       { showPageControlDropdown && (
         <PageItemControl
-          alignRight
+          alignEnd
           pageId={pageId}
           pageInfo={pageInfo}
           isEnableActions={!isGuestUser}

+ 1 - 2
apps/app/src/components/Page/CopyDropdown.jsx

@@ -119,8 +119,7 @@ const CopyDropdown = (props) => {
         </DropdownToggle>
 
         <DropdownMenu
-          positionFixed
-          modifiers={{ preventOverflow: { boundariesElement: 'viewport' } }}
+          strategy="fixed"
           style={{ zIndex: 1016 }} /* zIndex: 1016 // larger than z-index value of grw-subnav-fixed-container in GrowiSubNavigationSwitcher.module.scss */
         >
           <div className="d-flex align-items-center justify-content-between">

+ 3 - 5
apps/app/src/components/PageAccessoriesModal/PageAccessoriesModal.tsx

@@ -72,16 +72,14 @@ export const PageAccessoriesModal = (): JSX.Element => {
   }, [t, close, isGuestUser, isReadOnlyUser, isSharedUser, isLinkSharingDisabled]);
 
   const buttons = useMemo(() => (
-    <div className="d-flex flex-nowrap">
+    <span className="me-3">
       <ExpandOrContractButton
         isWindowExpanded={isWindowExpanded}
         expandWindow={() => setIsWindowExpanded(true)}
         contractWindow={() => setIsWindowExpanded(false)}
       />
-      <button type="button" className="close" onClick={close} aria-label="Close">
-        <span aria-hidden="true">&times;</span>
-      </button>
-    </div>
+      <button type="button" className="btn btn-close" onClick={close} aria-label="Close"></button>
+    </span>
   ), [close, isWindowExpanded]);
 
   if (status == null || status.activatedContents == null) {

+ 1 - 4
apps/app/src/components/PageEditor/HandsontableModal.tsx

@@ -430,15 +430,12 @@ export const HandsontableModal = (): JSX.Element => {
 
   const closeButton = (
     <span>
-      {/* change order because of `float: right` by '.close' class */}
-      <button type="button" className="close" onClick={cancel} aria-label="Close">
-        <span aria-hidden="true">&times;</span>
-      </button>
       <ExpandOrContractButton
         isWindowExpanded={isWindowExpanded}
         contractWindow={contractWindow}
         expandWindow={expandWindow}
       />
+      <button type="button" className="btn btn-close" onClick={cancel} aria-label="Close"></button>
     </span>
   );
 

+ 3 - 4
apps/app/src/components/PageList/PageListItemL.tsx

@@ -3,7 +3,6 @@ import React, {
   ForwardRefRenderFunction, memo, useCallback, useImperativeHandle, useRef, useEffect,
 } from 'react';
 
-
 import type {
   IPageInfoAll, IPageWithMeta, IPageInfoForListing,
 } from '@growi/core';
@@ -16,7 +15,7 @@ import { format } from 'date-fns';
 import { useTranslation } from 'next-i18next';
 import Link from 'next/link';
 import Clamp from 'react-multiline-clamp';
-import { CustomInput } from 'reactstrap';
+import { Input } from 'reactstrap';
 
 import { ISelectable } from '~/client/interfaces/selectable-all';
 import { unlink, bookmark, unbookmark } from '~/client/services/page-operation';
@@ -198,7 +197,7 @@ const PageListItemLSubstance: ForwardRefRenderFunction<ISelectable, Props> = (pr
           {/* checkbox */}
           {onCheckboxChanged != null && (
             <div className="d-flex align-items-center justify-content-center">
-              <CustomInput
+              <Input
                 type="checkbox"
                 id={`cbSelect-${pageData._id}`}
                 data-testid="cb-select"
@@ -260,7 +259,7 @@ const PageListItemLSubstance: ForwardRefRenderFunction<ISelectable, Props> = (pr
                 && (
                   <div className="ml-auto">
                     <PageItemControl
-                      alignRight
+                      alignEnd
                       pageId={pageData._id}
                       pageInfo={isIPageInfoForListing(pageMeta) ? pageMeta : undefined}
                       isEnableActions={isEnableActions}

+ 1 - 1
apps/app/src/components/RevisionComparer/RevisionComparer.tsx

@@ -77,7 +77,7 @@ export const RevisionComparer = (props: RevisionComparerProps): JSX.Element => {
           >
             <i className="ti ti-clipboard"></i>
           </DropdownToggle>
-          <DropdownMenu positionFixed right modifiers={{ preventOverflow: { boundariesElement: undefined } }}>
+          <DropdownMenu strategy="fixed" end>
             {/* Page path URL */}
             <CopyToClipboard text={generateURL(currentPagePath)}>
               <DropdownItem className="px-3">

+ 1 - 1
apps/app/src/components/SavePageControls.tsx

@@ -105,7 +105,7 @@ export const SavePageControls = (props: SavePageControlsProps): JSX.Element | nu
           {labelSubmitButton}
         </Button>
         <DropdownToggle caret color="primary" disabled={isWaitingSaveProcessing} />
-        <DropdownMenu right>
+        <DropdownMenu end>
           <DropdownItem onClick={saveAndOverwriteScopesOfDescendants}>
             {labelOverwriteScopes}
           </DropdownItem>

+ 4 - 6
apps/app/src/components/SearchPage/OperateAllControl.tsx

@@ -1,14 +1,15 @@
 import React, {
   ChangeEvent, forwardRef, ForwardRefRenderFunction, useImperativeHandle, useRef,
 } from 'react';
-import { CustomInput } from 'reactstrap';
+
+import { Input } from 'reactstrap';
+
 import { ISelectableAndIndeterminatable } from '~/client/interfaces/selectable-all';
 import { IndeterminateInputElement } from '~/interfaces/indeterminate-input-elm';
 
 type Props = {
   isCheckboxDisabled?: boolean,
   onCheckboxChanged?: (isChecked: boolean) => void,
-
   children?: React.ReactNode,
 }
 
@@ -16,7 +17,6 @@ const OperateAllControlSubstance: ForwardRefRenderFunction<ISelectableAndIndeter
   const {
     isCheckboxDisabled,
     onCheckboxChanged,
-
     children,
   } = props;
 
@@ -53,9 +53,8 @@ const OperateAllControlSubstance: ForwardRefRenderFunction<ISelectableAndIndeter
   };
 
   return (
-
     <div className="d-flex align-items-center">
-      <CustomInput
+      <Input
         type="checkbox"
         id="cb-check-all"
         data-testid="cb-select-all"
@@ -66,7 +65,6 @@ const OperateAllControlSubstance: ForwardRefRenderFunction<ISelectableAndIndeter
       {children}
     </div>
   );
-
 };
 
 export const OperateAllControl = React.memo(forwardRef(OperateAllControlSubstance));

+ 1 - 1
apps/app/src/components/Sidebar/PageTree/PageTreeSubstance.tsx

@@ -23,7 +23,7 @@ export const PageTreeHeader = memo(() => {
 
   return (
     <>
-      <SidebarHeaderReloadButton onClick={() => mutate()}/>
+      <SidebarHeaderReloadButton onClick={() => mutate()} />
     </>
   );
 });

+ 1 - 1
apps/app/src/components/Sidebar/SidebarBrandLogo.tsx

@@ -12,7 +12,7 @@ export const SidebarBrandLogo = memo((props: SidebarBrandLogoProps) => {
   return isDefaultLogo
     ? <GrowiLogo />
     // eslint-disable-next-line @next/next/no-img-element
-    : (<img src='/attachment/brand-logo' alt="custom logo" className="picture picture-lg p-2 mx-2" id="settingBrandLogo" width="32" />);
+    : (<img src="/attachment/brand-logo" alt="custom logo" className="picture picture-lg p-2 mx-2" id="settingBrandLogo" width="32" />);
 });
 
 SidebarBrandLogo.displayName = 'SidebarBrandLogo';

+ 1 - 1
packages/ui/package.json

@@ -24,7 +24,7 @@
     "@growi/core": "link:../core"
   },
   "devDependencies": {
-    "reactstrap": "8.10.1"
+    "reactstrap": "^9.2.0"
   },
   "peerDependencies": {
     "next": "^13",

+ 0 - 13
packages/ui/src/interfaces/popper-data.ts

@@ -13,16 +13,3 @@ export interface PopperData {
     arrow: { top: number; left: number };
   };
 }
-
-export interface CustomModifiers {
-  applyStyle?: {
-    enabled: boolean
-  }
-  computeStyle?: {
-    enabled: boolean,
-    fn: (data: PopperData) => PopperData
-  }
-  preventOverflow: {
-    boundariesElement: string
-  }
-}

+ 0 - 1
packages/ui/src/utils/index.ts

@@ -1,3 +1,2 @@
 export * from './browser-utils';
 export * from './use-fullscreen';
-export * from './reactstrap-modifiers';

+ 0 - 34
packages/ui/src/utils/reactstrap-modifiers.ts

@@ -1,34 +0,0 @@
-import { PopperData, CustomModifiers } from '~/interfaces/popper-data';
-
-// Conditional modifiers
-// To prevent flickering. only happened when `right` is true and persist props should be enabled
-const modifiersForRightAlign: CustomModifiers = {
-  applyStyle: {
-    enabled: true,
-  },
-  computeStyle: {
-    enabled: true,
-    fn: (data: PopperData): PopperData => {
-      const popperRect = data.offsets.popper;
-      // Calculate transform styles
-      const newTransform = `translate3d(${popperRect.left - window.innerWidth + popperRect.width}px, ${popperRect.top}px, 0px)`;
-      const styles = {
-        top: '0px',
-        right: '0px',
-        willChange: 'transform',
-        transform: newTransform,
-      };
-      data.styles = { ...data.styles, ...styles };
-      return data;
-    },
-  },
-  preventOverflow: { boundariesElement: 'viewport' },
-};
-
-export const getCustomModifiers = (alignRight?: boolean): CustomModifiers => {
-  return (
-    alignRight
-      ? modifiersForRightAlign
-      : { preventOverflow: { boundariesElement: 'viewport' } }
-  );
-};

+ 0 - 14
tools/replacer/.eslintrc.cjs

@@ -1,14 +0,0 @@
-module.exports = {
-  env: { browser: true, es2020: true },
-  extends: [
-    'eslint:recommended',
-    'plugin:@typescript-eslint/recommended',
-    'plugin:react-hooks/recommended',
-  ],
-  parser: '@typescript-eslint/parser',
-  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
-  plugins: ['react-refresh'],
-  rules: {
-    'react-refresh/only-export-components': 'warn',
-  },
-}

+ 0 - 24
tools/replacer/.gitignore

@@ -1,24 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?

+ 0 - 13
tools/replacer/index.html

@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Vite + React + TS</title>
-  </head>
-  <body>
-    <div id="root"></div>
-    <script type="module" src="/src/main.tsx"></script>
-  </body>
-</html>

+ 0 - 28
tools/replacer/package.json

@@ -1,28 +0,0 @@
-{
-  "name": "replacer",
-  "private": true,
-  "version": "0.0.0",
-  "type": "module",
-  "scripts": {
-    "dev": "vite",
-    "build": "tsc && vite build",
-    "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
-    "preview": "vite preview"
-  },
-  "dependencies": {
-    "react": "^18.2.0",
-    "react-dom": "^18.2.0"
-  },
-  "devDependencies": {
-    "@types/react": "^18.0.28",
-    "@types/react-dom": "^18.0.11",
-    "@typescript-eslint/eslint-plugin": "^5.57.1",
-    "@typescript-eslint/parser": "^5.57.1",
-    "@vitejs/plugin-react-swc": "^3.0.0",
-    "eslint": "^8.38.0",
-    "eslint-plugin-react-hooks": "^4.6.0",
-    "eslint-plugin-react-refresh": "^0.3.4",
-    "typescript": "^5.0.2",
-    "vite": "^4.3.0"
-  }
-}

+ 0 - 49
tools/replacer/src/App.css

@@ -1,49 +0,0 @@
-#root {
-  max-width: 1280px;
-  padding: 2rem;
-  margin: 0 auto;
-  text-align: center;
-}
-
-.logo {
-  height: 6em;
-  padding: 1.5em;
-  will-change: filter;
-  transition: filter 300ms;
-}
-
-.logo:hover {
-  filter: drop-shadow(0 0 2em #646cffaa);
-}
-
-.logo.react:hover {
-  filter: drop-shadow(0 0 2em #61dafbaa);
-}
-
-@keyframes logo-spin {
-  from {
-    transform: rotate(0deg);
-  }
-  to {
-    transform: rotate(360deg);
-  }
-}
-
-@media (prefers-reduced-motion: no-preference) {
-  a:nth-of-type(2) .logo {
-    animation: logo-spin infinite 20s linear;
-  }
-}
-
-.card {
-  padding: 2em;
-}
-
-.card textarea {
-  width: 480px;
-}
-
-
-.read-the-docs {
-  color: #888;
-}

+ 0 - 47
tools/replacer/src/App.tsx

@@ -1,47 +0,0 @@
-import { ChangeEventHandler, useState } from 'react'
-import './App.css'
-
-
-
-function replaceImport(str: string): string {
-  const regex = /import {[\s\n]*([^}]+)[\s\n]*} from 'reactstrap';/;
-
-  return str.replace(regex, (_match, group: string) => {
-    const modules = group
-      .split(',')
-      .map(mod => mod.trim())
-      .filter(mod => mod.length > 0)
-
-    return modules.map((mod) => {
-      return `import ${mod} from 'reactstrap/es/${mod}';`
-    }).join('\n')
-  });
-}
-
-function App() {
-
-  const [output, setOutput] = useState('');
-
-  const changeHandler: ChangeEventHandler<HTMLTextAreaElement> = (e): void => {
-    const { value } = e.target;
-
-    const replacedValue = replaceImport(value);
-
-    setOutput(replacedValue);
-  }
-  return (
-    <>
-      <h1>Input</h1>
-      <div className="card">
-        <textarea rows={5} onChange={changeHandler} />
-      </div>
-
-      <h1>Output</h1>
-      <div className="card">
-        <textarea rows={5} value={output} />
-      </div>
-    </>
-  )
-}
-
-export default App

+ 0 - 69
tools/replacer/src/index.css

@@ -1,69 +0,0 @@
-:root {
-  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
-  line-height: 1.5;
-  font-weight: 400;
-
-  color-scheme: light dark;
-  color: rgba(255, 255, 255, 0.87);
-  background-color: #242424;
-
-  font-synthesis: none;
-  text-rendering: optimizeLegibility;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  -webkit-text-size-adjust: 100%;
-}
-
-a {
-  font-weight: 500;
-  color: #646cff;
-  text-decoration: inherit;
-}
-a:hover {
-  color: #535bf2;
-}
-
-body {
-  margin: 0;
-  display: flex;
-  place-items: center;
-  min-width: 320px;
-  min-height: 100vh;
-}
-
-h1 {
-  font-size: 3.2em;
-  line-height: 1.1;
-}
-
-button {
-  border-radius: 8px;
-  border: 1px solid transparent;
-  padding: 0.6em 1.2em;
-  font-size: 1em;
-  font-weight: 500;
-  font-family: inherit;
-  background-color: #1a1a1a;
-  cursor: pointer;
-  transition: border-color 0.25s;
-}
-button:hover {
-  border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
-  outline: 4px auto -webkit-focus-ring-color;
-}
-
-@media (prefers-color-scheme: light) {
-  :root {
-    color: #213547;
-    background-color: #ffffff;
-  }
-  a:hover {
-    color: #747bff;
-  }
-  button {
-    background-color: #f9f9f9;
-  }
-}

+ 0 - 10
tools/replacer/src/main.tsx

@@ -1,10 +0,0 @@
-import React from 'react'
-import ReactDOM from 'react-dom/client'
-import App from './App.tsx'
-import './index.css'
-
-ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
-  <React.StrictMode>
-    <App />
-  </React.StrictMode>,
-)

+ 0 - 1
tools/replacer/src/vite-env.d.ts

@@ -1 +0,0 @@
-/// <reference types="vite/client" />

+ 0 - 24
tools/replacer/tsconfig.json

@@ -1,24 +0,0 @@
-{
-  "compilerOptions": {
-    "target": "ESNext",
-    "lib": ["DOM", "DOM.Iterable", "ESNext"],
-    "module": "ESNext",
-    "skipLibCheck": true,
-
-    /* Bundler mode */
-    "moduleResolution": "bundler",
-    "allowImportingTsExtensions": true,
-    "resolveJsonModule": true,
-    "isolatedModules": true,
-    "noEmit": true,
-    "jsx": "react-jsx",
-
-    /* Linting */
-    "strict": true,
-    "noUnusedLocals": true,
-    "noUnusedParameters": true,
-    "noFallthroughCasesInSwitch": true
-  },
-  "include": ["src"],
-  "references": [{ "path": "./tsconfig.node.json" }]
-}

+ 0 - 10
tools/replacer/tsconfig.node.json

@@ -1,10 +0,0 @@
-{
-  "compilerOptions": {
-    "composite": true,
-    "skipLibCheck": true,
-    "module": "ESNext",
-    "moduleResolution": "bundler",
-    "allowSyntheticDefaultImports": true
-  },
-  "include": ["vite.config.ts"]
-}

+ 0 - 7
tools/replacer/vite.config.ts

@@ -1,7 +0,0 @@
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react-swc'
-
-// https://vitejs.dev/config/
-export default defineConfig({
-  plugins: [react()],
-})

+ 29 - 23
yarn.lock

@@ -2116,6 +2116,13 @@
   dependencies:
     regenerator-runtime "^0.13.11"
 
+"@babel/runtime@^7.5.5":
+  version "7.22.10"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682"
+  integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==
+  dependencies:
+    regenerator-runtime "^0.14.0"
+
 "@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3":
   version "7.20.7"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
@@ -3832,7 +3839,7 @@
   resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
   integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
 
-"@popperjs/core@^2.11.8":
+"@popperjs/core@^2.11.8", "@popperjs/core@^2.6.0":
   version "2.11.8"
   resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
   integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
@@ -7745,14 +7752,7 @@ dom-accessibility-api@^0.5.9:
   resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.10.tgz#caa6d08f60388d0bb4539dd75fe458a9a1d0014c"
   integrity sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==
 
-dom-helpers@^3.4.0:
-  version "3.4.0"
-  resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
-  integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
-  dependencies:
-    "@babel/runtime" "^7.1.2"
-
-dom-helpers@^5.2.0:
+dom-helpers@^5.0.1, dom-helpers@^5.2.0:
   version "5.2.1"
   resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
   integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
@@ -14422,7 +14422,7 @@ react-overlays@^5.1.0:
     uncontrollable "^7.2.1"
     warning "^4.0.3"
 
-react-popper@^1.0.0, react-popper@^1.3.6:
+react-popper@^1.0.0:
   version "1.3.11"
   resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd"
   integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==
@@ -14435,7 +14435,7 @@ react-popper@^1.0.0, react-popper@^1.3.6:
     typed-styles "^0.0.7"
     warning "^4.0.2"
 
-react-popper@^2.2.5:
+react-popper@^2.2.4, react-popper@^2.2.5:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba"
   integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==
@@ -14474,15 +14474,15 @@ react-toastify@^9.1.1:
   dependencies:
     clsx "^1.1.1"
 
-react-transition-group@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-3.0.0.tgz#36efa4db970d5eec5e3028e0c458931163fa3b9b"
-  integrity sha512-A9ojB/LWECbFj58SNfjK1X9aaAU+1olLS0DFSikvrr2KfMaiBELemHDa5dKNvcTk2t3gUtDL/PJpFrBKDfMpLg==
+react-transition-group@^4.4.2:
+  version "4.4.5"
+  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
+  integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
   dependencies:
-    dom-helpers "^3.4.0"
+    "@babel/runtime" "^7.5.5"
+    dom-helpers "^5.0.1"
     loose-envify "^1.4.0"
     prop-types "^15.6.2"
-    react-lifecycles-compat "^3.0.4"
 
 react-use-ripple@^1.5.2:
   version "1.5.2"
@@ -14496,16 +14496,17 @@ react@^18.2.0:
   dependencies:
     loose-envify "^1.1.0"
 
-reactstrap@8.10.1, reactstrap@^8.10.1:
-  version "8.10.1"
-  resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.10.1.tgz#43ea596c7f82f88997a9c8aae203417910262d3f"
-  integrity sha512-StjLADa/12yMNjafrSs+UD7sZAGtKpLO9fZp++2Dj0IzJinqY7eQhXlM3nFf0q40YsIcLvQdFc9pKF8PF4f0Qg==
+reactstrap@^9.2.0:
+  version "9.2.0"
+  resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-9.2.0.tgz#3bde2b2e39e91962676167ac60edea89f8584382"
+  integrity sha512-WWLTEG00qYav0E55PorWHReYTkz5IqkVmQNy0h6U81yqjSp9fOLFGV5pYSVeAUz+yRhU/RTE0oAWy22zr6sOIw==
   dependencies:
     "@babel/runtime" "^7.12.5"
+    "@popperjs/core" "^2.6.0"
     classnames "^2.2.3"
     prop-types "^15.5.8"
-    react-popper "^1.3.6"
-    react-transition-group "^3.0.0"
+    react-popper "^2.2.4"
+    react-transition-group "^4.4.2"
 
 read-pkg-up@^1.0.1:
   version "1.0.1"
@@ -14804,6 +14805,11 @@ regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.4:
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
   integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
 
+regenerator-runtime@^0.14.0:
+  version "0.14.0"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
+  integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
+
 regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0, regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3:
   version "1.4.3"
   resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"