Refactor: replace react-select with react-dropdown-select

This commit is contained in:
IRBorisov 2023-07-30 15:49:30 +03:00
parent 29239590ba
commit cdf4ee8aca
12 changed files with 94 additions and 90 deletions

View File

@ -22,9 +22,10 @@ This readme file is used mostly to document project dependencies
- react-tabs - react-tabs
- react-intl - react-intl
- react-data-table-component - react-data-table-component
- react-select - react-dropdown-select
- react-error-boundary - react-error-boundary
- reagraph - reagraph
- react-tooltip
</pre> </pre>
</details> </details>
<details> <details>

View File

@ -13,13 +13,14 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-data-table-component": "^7.5.3", "react-data-table-component": "^7.5.3",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-dropdown-select": "^4.10.0",
"react-error-boundary": "^4.0.10", "react-error-boundary": "^4.0.10",
"react-intl": "^6.4.4", "react-intl": "^6.4.4",
"react-loader-spinner": "^5.3.4", "react-loader-spinner": "^5.3.4",
"react-router-dom": "^6.14.2", "react-router-dom": "^6.14.2",
"react-select": "^5.7.4",
"react-tabs": "^6.0.2", "react-tabs": "^6.0.2",
"react-toastify": "^9.1.3", "react-toastify": "^9.1.3",
"react-tooltip": "^5.19.0",
"reagraph": "^4.11.1" "reagraph": "^4.11.1"
}, },
"devDependencies": { "devDependencies": {
@ -2147,6 +2148,28 @@
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
"integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA=="
}, },
"node_modules/@emotion/styled": {
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz",
"integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==",
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.11.0",
"@emotion/is-prop-valid": "^1.2.1",
"@emotion/serialize": "^1.1.2",
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
"@emotion/utils": "^1.2.1"
},
"peerDependencies": {
"@emotion/react": "^11.0.0-rc.0",
"react": ">=16.8.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@emotion/stylis": { "node_modules/@emotion/stylis": {
"version": "0.8.5", "version": "0.8.5",
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
@ -3105,14 +3128,6 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"node_modules/@types/react-transition-group": {
"version": "4.4.6",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
"integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==",
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/scheduler": { "node_modules/@types/scheduler": {
"version": "0.16.3", "version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
@ -4156,15 +4171,6 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/dom-helpers": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
"dependencies": {
"@babel/runtime": "^7.8.7",
"csstype": "^3.0.2"
}
},
"node_modules/draco3d": { "node_modules/draco3d": {
"version": "1.5.6", "version": "1.5.6",
"resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.6.tgz", "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.6.tgz",
@ -5287,11 +5293,6 @@
"semver": "bin/semver" "semver": "bin/semver"
} }
}, },
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
"node_modules/merge2": { "node_modules/merge2": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@ -5887,6 +5888,20 @@
"react": "^18.2.0" "react": "^18.2.0"
} }
}, },
"node_modules/react-dropdown-select": {
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/react-dropdown-select/-/react-dropdown-select-4.10.0.tgz",
"integrity": "sha512-GiUeZZqN8Z/PQFWyihFeuLwlUQ2IJxiu4ep8Y6bonF8ynUk8dAdLgjg3O4YIa3gtS8/Paeli8AtH46AcaPzWVg==",
"dependencies": {
"@emotion/react": "11.11.1",
"@emotion/styled": "11.11.0"
},
"peerDependencies": {
"prop-types": ">=15.7.2",
"react": ">=16.x",
"react-dom": ">=16.x"
}
},
"node_modules/react-error-boundary": { "node_modules/react-error-boundary": {
"version": "4.0.10", "version": "4.0.10",
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.10.tgz", "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.10.tgz",
@ -6053,26 +6068,6 @@
"react-dom": ">=16.8" "react-dom": ">=16.8"
} }
}, },
"node_modules/react-select": {
"version": "5.7.4",
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.4.tgz",
"integrity": "sha512-NhuE56X+p9QDFh4BgeygHFIvJJszO1i1KSkg/JPcIJrbovyRtI+GuOEa4XzFCEpZRAEoEI8u/cAHK+jG/PgUzQ==",
"dependencies": {
"@babel/runtime": "^7.12.0",
"@emotion/cache": "^11.4.0",
"@emotion/react": "^11.8.1",
"@floating-ui/dom": "^1.0.1",
"@types/react-transition-group": "^4.4.0",
"memoize-one": "^6.0.0",
"prop-types": "^15.6.0",
"react-transition-group": "^4.3.0",
"use-isomorphic-layout-effect": "^1.1.2"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-tabs": { "node_modules/react-tabs": {
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-6.0.2.tgz", "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-6.0.2.tgz",
@ -6105,19 +6100,17 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/react-transition-group": { "node_modules/react-tooltip": {
"version": "4.4.5", "version": "5.19.0",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.19.0.tgz",
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "integrity": "sha512-NSUk77GMpxYKHFKJVNHL++QQXRuH2QW1qDrXPtJnp2s/MJvUnU73N5TTADwDyrO2+xGlr0xHhjvQphkF60cMEA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.5.5", "@floating-ui/dom": "^1.0.0",
"dom-helpers": "^5.0.1", "classnames": "^2.3.0"
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2"
}, },
"peerDependencies": { "peerDependencies": {
"react": ">=16.6.0", "react": ">=16.14.0",
"react-dom": ">=16.6.0" "react-dom": ">=16.14.0"
} }
}, },
"node_modules/react-use-gesture": { "node_modules/react-use-gesture": {
@ -6939,19 +6932,6 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"node_modules/use-isomorphic-layout-effect": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
"integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/use-sync-external-store": { "node_modules/use-sync-external-store": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",

View File

@ -15,13 +15,14 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-data-table-component": "^7.5.3", "react-data-table-component": "^7.5.3",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-dropdown-select": "^4.10.0",
"react-error-boundary": "^4.0.10", "react-error-boundary": "^4.0.10",
"react-intl": "^6.4.4", "react-intl": "^6.4.4",
"react-loader-spinner": "^5.3.4", "react-loader-spinner": "^5.3.4",
"react-router-dom": "^6.14.2", "react-router-dom": "^6.14.2",
"react-select": "^5.7.4",
"react-tabs": "^6.0.2", "react-tabs": "^6.0.2",
"react-toastify": "^9.1.3", "react-toastify": "^9.1.3",
"react-tooltip": "^5.19.0",
"reagraph": "^4.11.1" "reagraph": "^4.11.1"
}, },
"devDependencies": { "devDependencies": {

View File

@ -38,7 +38,7 @@ createTheme('customDark', {
} }
}, 'dark'); }, 'dark');
function DataTableThemed<T>({ theme, ...props }: TableProps<T>) { function ConceptDataTable<T>({ theme, ...props }: TableProps<T>) {
const { darkMode } = useConceptTheme(); const { darkMode } = useConceptTheme();
return ( return (
@ -49,4 +49,4 @@ function DataTableThemed<T>({ theme, ...props }: TableProps<T>) {
); );
} }
export default DataTableThemed; export default ConceptDataTable;

View File

@ -4,13 +4,13 @@ import { darkTheme, GraphCanvas, GraphCanvasProps, GraphCanvasRef, lightTheme }
import { useConceptTheme } from '../../context/ThemeContext'; import { useConceptTheme } from '../../context/ThemeContext';
import { resources } from '../../utils/constants'; import { resources } from '../../utils/constants';
interface GraphThemedProps interface ConceptGraphProps
extends Omit<GraphCanvasProps, 'theme' | 'labelFontUrl'> { extends Omit<GraphCanvasProps, 'theme' | 'labelFontUrl'> {
ref?: Ref<GraphCanvasRef> ref?: Ref<GraphCanvasRef>
sizeClass: string sizeClass: string
} }
function GraphThemed({ sizeClass, ...props }: GraphThemedProps) { function ConceptGraph({ sizeClass, ...props }: ConceptGraphProps) {
const { darkMode } = useConceptTheme(); const { darkMode } = useConceptTheme();
return ( return (
@ -26,4 +26,4 @@ function GraphThemed({ sizeClass, ...props }: GraphThemedProps) {
); );
} }
export default GraphThemed; export default ConceptGraph;

View File

@ -0,0 +1,18 @@
import { PropsWithRef } from 'react';
import Select, { SelectProps } from 'react-dropdown-select';
interface ConceptSelectProps<T>
extends Omit<PropsWithRef<SelectProps<T>>, 'noDataLabel'> {
}
function ConceptSelect<T extends object | string>({ ...props }: ConceptSelectProps<T>) {
return (
<Select
{...props}
noDataLabel='Список пуст'
/>
);
}
export default ConceptSelect;

View File

@ -14,6 +14,10 @@
color-scheme: light; color-scheme: light;
} }
.react-dropdown-select-item {
@apply bg-gray-100 dark:bg-gray-600 dark:text-zinc-200 hover:bg-gray-50 hover:text-gray-700 dark:hover:text-white dark:hover:bg-gray-500
}
@layer components { @layer components {
.border { .border {
@apply clr-border rounded @apply clr-border rounded

View File

@ -2,7 +2,7 @@ import { useMemo } from 'react';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import DataTableThemed from '../../components/Common/DataTableThemed'; import ConceptDataTable from '../../components/Common/ConceptDataTable';
import { useUsers } from '../../context/UsersContext'; import { useUsers } from '../../context/UsersContext';
import { IRSFormMeta } from '../../utils/models' import { IRSFormMeta } from '../../utils/models'
@ -59,7 +59,7 @@ function ViewLibrary({ schemas }: ViewLibraryProps) {
); );
return ( return (
<DataTableThemed <ConceptDataTable
columns={columns} columns={columns}
data={schemas} data={schemas}
defaultSortFieldId='time_update' defaultSortFieldId='time_update'

View File

@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import Select from 'react-select';
import ConceptSelect from '../../components/Common/ConceptSelect';
import Modal from '../../components/Common/Modal'; import Modal from '../../components/Common/Modal';
import { type CstType } from '../../utils/models'; import { type CstType } from '../../utils/models';
import { CstTypeSelector, getCstTypeLabel } from '../../utils/staticUI'; import { CstTypeSelector, getCstTypeLabel } from '../../utils/staticUI';
@ -35,12 +35,11 @@ function DlgCreateCst({ hideWindow, defaultType, onCreate }: DlgCreateCstProps)
canSubmit={validated} canSubmit={validated}
onSubmit={handleSubmit} onSubmit={handleSubmit}
> >
<Select <ConceptSelect
options={CstTypeSelector} options={CstTypeSelector}
placeholder='Выберите тип' placeholder='Выберите тип'
filterOption={null} values={selectedType ? [{ value: selectedType, label: getCstTypeLabel(selectedType) }] : []}
value={selectedType && { value: selectedType, label: getCstTypeLabel(selectedType) }} onChange={data => { setSelectedType(data[0].value); }}
onChange={(data) => { setSelectedType(data?.value); }}
/> />
</Modal> </Modal>
); );

View File

@ -2,7 +2,7 @@ import { useCallback, useMemo, useState } from 'react';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import Button from '../../components/Common/Button'; import Button from '../../components/Common/Button';
import DataTableThemed from '../../components/Common/DataTableThemed'; import ConceptDataTable from '../../components/Common/ConceptDataTable';
import Divider from '../../components/Common/Divider'; import Divider from '../../components/Common/Divider';
import { ArrowDownIcon, ArrowsRotateIcon, ArrowUpIcon, DumpBinIcon, SmallPlusIcon } from '../../components/Icons'; import { ArrowDownIcon, ArrowsRotateIcon, ArrowUpIcon, DumpBinIcon, SmallPlusIcon } from '../../components/Icons';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
@ -54,6 +54,7 @@ function EditorItems({ onOpenEdit, onShowCreateCst }: EditorItemsProps) {
cstDelete(data, () => { cstDelete(data, () => {
toast.success(`Конституенты удалены: ${deletedNames}`); toast.success(`Конституенты удалены: ${deletedNames}`);
setToggledClearRows(prev => !prev); setToggledClearRows(prev => !prev);
setSelected([]);
}); });
}, [selected, schema?.items, cstDelete]); }, [selected, schema?.items, cstDelete]);
@ -339,7 +340,7 @@ function EditorItems({ onOpenEdit, onShowCreateCst }: EditorItemsProps) {
tabIndex={0} tabIndex={0}
title='Горячие клавиши:&#013;Двойной клик / Alt + клик - редактирование конституенты&#013;Alt + вверх/вниз - движение конституент&#013;Delete - удаление выбранных&#013;Alt + 1-6, Q,W - добавление конституент' title='Горячие клавиши:&#013;Двойной клик / Alt + клик - редактирование конституенты&#013;Alt + вверх/вниз - движение конституент&#013;Delete - удаление выбранных&#013;Alt + 1-6, Q,W - добавление конституент'
> >
<DataTableThemed <ConceptDataTable
data={schema?.items ?? []} data={schema?.items ?? []}
columns={columns} columns={columns}
keyField='id' keyField='id'

View File

@ -1,8 +1,8 @@
import { useMemo, useRef } from 'react'; import { useMemo, useRef } from 'react';
import Select from 'react-select';
import { GraphCanvasRef, GraphEdge, GraphNode, LayoutTypes, useSelection } from 'reagraph'; import { GraphCanvasRef, GraphEdge, GraphNode, LayoutTypes, useSelection } from 'reagraph';
import GraphThemed from '../../components/Common/GraphThemed'; import ConceptGraph from '../../components/Common/ConceptGraph';
import ConceptSelect from '../../components/Common/ConceptSelect';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import useLocalStorage from '../../hooks/useLocalStorage'; import useLocalStorage from '../../hooks/useLocalStorage';
import { GraphLayoutSelector } from '../../utils/staticUI'; import { GraphLayoutSelector } from '../../utils/staticUI';
@ -56,16 +56,16 @@ function EditorTermGraph() {
<div> <div>
<div className='relative w-full'> <div className='relative w-full'>
<div className='absolute top-0 left-0 z-20 px-3 py-2'> <div className='absolute top-0 left-0 z-20 px-3 py-2'>
<Select <ConceptSelect
className='w-[10rem]' className='w-[10rem]'
options={GraphLayoutSelector} options={GraphLayoutSelector}
placeholder='Выберите тип' placeholder='Выберите тип'
value={layout && { value: layout, label: String(layout) }} values={layout ? [{ value: layout, label: String(layout) }] : []}
onChange={data => { data && setLayout(data.value); }} onChange={data => { data && setLayout(data[0].value); }}
/> />
</div> </div>
</div> </div>
<GraphThemed ref={graphRef} <ConceptGraph ref={graphRef}
sizeClass='w-[1240px] h-[800px] 2xl:w-[1880px] 2xl:h-[800px]' sizeClass='w-[1240px] h-[800px] 2xl:w-[1880px] 2xl:h-[800px]'
nodes={nodes} nodes={nodes}
edges={edges} edges={edges}

View File

@ -1,7 +1,7 @@
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react';
import Checkbox from '../../../components/Common/Checkbox'; import Checkbox from '../../../components/Common/Checkbox';
import DataTableThemed from '../../../components/Common/DataTableThemed'; import ConceptDataTable from '../../../components/Common/ConceptDataTable';
import { useRSForm } from '../../../context/RSFormContext'; import { useRSForm } from '../../../context/RSFormContext';
import useLocalStorage from '../../../hooks/useLocalStorage'; import useLocalStorage from '../../../hooks/useLocalStorage';
import { CstType, extractGlobals,type IConstituenta, matchConstituenta } from '../../../utils/models'; import { CstType, extractGlobals,type IConstituenta, matchConstituenta } from '../../../utils/models';
@ -123,7 +123,7 @@ function ViewSideConstituents({ expression }: ViewSideConstituentsProps) {
/> />
</div> </div>
</div> </div>
<DataTableThemed <ConceptDataTable
data={filteredData} data={filteredData}
columns={columns} columns={columns}
keyField='id' keyField='id'