mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-20 15:19:10 +00:00
Merge pull request #539 from spacedriveapp/eslint-overhaul
Eslint overhaul
This commit is contained in:
commit
ef9fe5b75f
24
.github/workflows/ci.yml
vendored
24
.github/workflows/ci.yml
vendored
|
@ -37,6 +37,30 @@ jobs:
|
||||||
- name: Perform typechecks
|
- name: Perform typechecks
|
||||||
run: pnpm typecheck
|
run: pnpm typecheck
|
||||||
|
|
||||||
|
eslint:
|
||||||
|
name: ESLint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v2.2.2
|
||||||
|
with:
|
||||||
|
version: 7.x.x
|
||||||
|
|
||||||
|
- name: Install Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
cache: 'pnpm'
|
||||||
|
|
||||||
|
- name: Install pnpm dependencies
|
||||||
|
run: pnpm i --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Perform linting
|
||||||
|
run: pnpm lint
|
||||||
|
|
||||||
rustfmt:
|
rustfmt:
|
||||||
name: rustfmt
|
name: rustfmt
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...require('@sd/config/eslint-react.js'),
|
extends: [require.resolve('@sd/config/eslint/web.js')],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
project: './tsconfig.json'
|
project: './tsconfig.json'
|
||||||
},
|
}
|
||||||
ignorePatterns: ['**/*.js', '**/*.json', 'node_modules', 'public', 'dist', 'vite.config.ts']
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"server": "ts-node ./server",
|
"server": "ts-node ./server",
|
||||||
"server:prod": "cross-env NODE_ENV=production ts-node ./server",
|
"server:prod": "cross-env NODE_ENV=production ts-node ./server",
|
||||||
"lint": "eslint src/**/*.{ts,tsx} && tsc --noEmit",
|
"lint": "eslint src",
|
||||||
"typecheck": "tsc -b"
|
"typecheck": "tsc -b"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...require('@sd/config/eslint-react-native.js'),
|
extends: [require.resolve('@sd/config/eslint/reactNative.js')],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
project: './tsconfig.json'
|
project: './tsconfig.json'
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"ios": "expo run:ios",
|
"ios": "expo run:ios",
|
||||||
"xcode": "open ios/spacedrive.xcworkspace",
|
"xcode": "open ios/spacedrive.xcworkspace",
|
||||||
"android-studio": "open -a '/Applications/Android Studio.app' ./android",
|
"android-studio": "open -a '/Applications/Android Studio.app' ./android",
|
||||||
"lint": "eslint src/**/*.{ts,tsx} && tsc --noEmit",
|
"lint": "eslint src",
|
||||||
"postinstall": "node scripts/postinstall.js",
|
"postinstall": "node scripts/postinstall.js",
|
||||||
"typecheck": "tsc -b"
|
"typecheck": "tsc -b"
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"prisma": "cd core && cargo prisma",
|
"prisma": "cd core && cargo prisma",
|
||||||
"codegen": "cargo test -p sd-core api::tests::test_and_export_rspc_bindings -- --exact",
|
"codegen": "cargo test -p sd-core api::tests::test_and_export_rspc_bindings -- --exact",
|
||||||
"typecheck": "turbo run typecheck",
|
"typecheck": "turbo run typecheck",
|
||||||
|
"lint": "turbo run lint",
|
||||||
"clean": "rimraf node_modules/ **/node_modules/ target/ **/.build/ **/.next/ **/dist/**"
|
"clean": "rimraf node_modules/ **/node_modules/ target/ **/.build/ **/.next/ **/dist/**"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...require('@sd/config/eslint-react.js'),
|
extends: [require.resolve('@sd/config/eslint/web.js')],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
project: './tsconfig.json'
|
project: './tsconfig.json'
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"lint": "eslint src/**/*.{ts,tsx} && tsc --noEmit",
|
"lint": "eslint src",
|
||||||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
|
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
|
||||||
"typecheck": "tsc -b",
|
"typecheck": "tsc -b",
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
declare global {
|
declare global {
|
||||||
|
// eslint-disable-next-line
|
||||||
var isDev: boolean;
|
var isDev: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
env: {
|
|
||||||
'react-native/react-native': true
|
|
||||||
},
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
parserOptions: {
|
|
||||||
ecmaFeatures: {
|
|
||||||
jsx: true
|
|
||||||
},
|
|
||||||
ecmaVersion: 12,
|
|
||||||
sourceType: 'module'
|
|
||||||
},
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:react/recommended',
|
|
||||||
'plugin:react-hooks/recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended'
|
|
||||||
],
|
|
||||||
plugins: ['react', 'react-native'],
|
|
||||||
rules: {
|
|
||||||
'react/display-name': 'off',
|
|
||||||
'react/prop-types': 'off',
|
|
||||||
'react/no-unescaped-entities': 'off',
|
|
||||||
'react/react-in-jsx-scope': 'off',
|
|
||||||
'react-hooks/rules-of-hooks': 'error',
|
|
||||||
'react-hooks/exhaustive-deps': 'warn',
|
|
||||||
'@typescript-eslint/no-unused-vars': 'off',
|
|
||||||
'@typescript-eslint/ban-ts-comment': 'off',
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'@typescript-eslint/no-var-requires': 'off',
|
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
||||||
'no-control-regex': 'off',
|
|
||||||
'no-mixed-spaces-and-tabs': ['warn', 'smart-tabs'],
|
|
||||||
'no-restricted-imports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
paths: [
|
|
||||||
{
|
|
||||||
name: 'react-native',
|
|
||||||
importNames: ['SafeAreaView'],
|
|
||||||
message: 'Import SafeAreaView from react-native-safe-area-context instead'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'react-native',
|
|
||||||
importNames: ['Button'],
|
|
||||||
message: 'Import Button from ~/components instead.'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
ignorePatterns: ['**/*.js', '**/*.json', 'node_modules', 'android', 'ios', '.expo'],
|
|
||||||
settings: {
|
|
||||||
react: {
|
|
||||||
version: 'detect'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,8 +1,4 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
node: true
|
|
||||||
},
|
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
ecmaFeatures: {
|
ecmaFeatures: {
|
||||||
|
@ -16,7 +12,8 @@ module.exports = {
|
||||||
'plugin:react/recommended',
|
'plugin:react/recommended',
|
||||||
'plugin:react-hooks/recommended',
|
'plugin:react-hooks/recommended',
|
||||||
'plugin:@typescript-eslint/recommended',
|
'plugin:@typescript-eslint/recommended',
|
||||||
'prettier'
|
'prettier',
|
||||||
|
'turbo'
|
||||||
],
|
],
|
||||||
plugins: ['react'],
|
plugins: ['react'],
|
||||||
rules: {
|
rules: {
|
||||||
|
@ -24,7 +21,7 @@ module.exports = {
|
||||||
'react/prop-types': 'off',
|
'react/prop-types': 'off',
|
||||||
'react/no-unescaped-entities': 'off',
|
'react/no-unescaped-entities': 'off',
|
||||||
'react/react-in-jsx-scope': 'off',
|
'react/react-in-jsx-scope': 'off',
|
||||||
'react-hooks/rules-of-hooks': 'error',
|
'react-hooks/rules-of-hooks': 'warn',
|
||||||
'react-hooks/exhaustive-deps': 'warn',
|
'react-hooks/exhaustive-deps': 'warn',
|
||||||
'@typescript-eslint/no-unused-vars': 'off',
|
'@typescript-eslint/no-unused-vars': 'off',
|
||||||
'@typescript-eslint/ban-ts-comment': 'off',
|
'@typescript-eslint/ban-ts-comment': 'off',
|
||||||
|
@ -32,10 +29,12 @@ module.exports = {
|
||||||
'@typescript-eslint/no-var-requires': 'off',
|
'@typescript-eslint/no-var-requires': 'off',
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
'@typescript-eslint/no-empty-interface': 'off',
|
||||||
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
'no-control-regex': 'off',
|
'no-control-regex': 'off',
|
||||||
'no-mixed-spaces-and-tabs': ['warn', 'smart-tabs']
|
'no-mixed-spaces-and-tabs': ['warn', 'smart-tabs']
|
||||||
},
|
},
|
||||||
ignorePatterns: ['**/*.js', '**/*.json', 'node_modules'],
|
ignorePatterns: ['dist', '**/*.js', '**/*.json', 'node_modules'],
|
||||||
settings: {
|
settings: {
|
||||||
react: {
|
react: {
|
||||||
version: 'detect'
|
version: 'detect'
|
27
packages/config/eslint/reactNative.js
Normal file
27
packages/config/eslint/reactNative.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: [require.resolve('./base.js')],
|
||||||
|
env: {
|
||||||
|
'react-native/react-native': true
|
||||||
|
},
|
||||||
|
plugins: ['react-native'],
|
||||||
|
ignorePatterns: ['android', 'ios', '.expo'],
|
||||||
|
rules: {
|
||||||
|
'no-restricted-imports': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
paths: [
|
||||||
|
{
|
||||||
|
name: 'react-native',
|
||||||
|
importNames: ['SafeAreaView'],
|
||||||
|
message: 'Import SafeAreaView from react-native-safe-area-context instead'
|
||||||
|
}
|
||||||
|
// {
|
||||||
|
// name: 'react-native',
|
||||||
|
// importNames: ['Button'],
|
||||||
|
// message: 'Import Button from ~/components instead.'
|
||||||
|
// }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
8
packages/config/eslint/web.js
Normal file
8
packages/config/eslint/web.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: [require.resolve('./base.js')],
|
||||||
|
ignorePatterns: ['public', 'vite.config.ts'],
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
node: true
|
||||||
|
}
|
||||||
|
};
|
3
packages/config/index.js
Normal file
3
packages/config/index.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
vite: require('./vite')
|
||||||
|
};
|
|
@ -3,16 +3,18 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
"./*": "./*",
|
||||||
"./vite": "./vite/index.js"
|
"./vite": "./vite/index.js"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"eslint-react.js"
|
"eslint-react.js"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^5.39.0",
|
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||||
"@typescript-eslint/parser": "^5.39.0",
|
"@typescript-eslint/parser": "^5.48.2",
|
||||||
"eslint": "^8.24.0",
|
"eslint": "^8.24.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-config-turbo": "^0.0.7",
|
||||||
"eslint-plugin-react": "^7.31.8",
|
"eslint-plugin-react": "^7.31.8",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0"
|
"eslint-plugin-react-hooks": "^4.6.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...require('@sd/config/eslint-react.js'),
|
extends: [require.resolve('@sd/config/eslint/web.js')],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
project: './tsconfig.json'
|
project: './tsconfig.json'
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"icons": "./scripts/generateSvgImports.mjs",
|
"icons": "./scripts/generateSvgImports.mjs",
|
||||||
"lint": "eslint src/**/*.{ts,tsx} && tsc --noEmit",
|
"lint": "eslint src",
|
||||||
"typecheck": "tsc -b",
|
"typecheck": "tsc -b",
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
"@splinetool/runtime": "^0.9.128",
|
"@splinetool/runtime": "^0.9.128",
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
"@tanstack/react-query": "^4.12.0",
|
"@tanstack/react-query": "^4.12.0",
|
||||||
"@tanstack/react-query-devtools": "^4.12.0",
|
"@tanstack/react-query-devtools": "^4.22.0",
|
||||||
"@tanstack/react-virtual": "3.0.0-beta.18",
|
"@tanstack/react-virtual": "3.0.0-beta.18",
|
||||||
"@vitejs/plugin-react": "^2.1.0",
|
"@vitejs/plugin-react": "^2.1.0",
|
||||||
"@zxcvbn-ts/core": "^2.1.0",
|
"@zxcvbn-ts/core": "^2.1.0",
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Input, useZodForm, z } from '@sd/ui/src/forms';
|
||||||
|
|
||||||
const schema = z.object({ path: z.string() });
|
const schema = z.object({ path: z.string() });
|
||||||
|
|
||||||
interface Props extends UseDialogProps {}
|
type Props = UseDialogProps;
|
||||||
|
|
||||||
export default function AddLocationDialog(props: Props) {
|
export default function AddLocationDialog(props: Props) {
|
||||||
const dialog = useDialog(props);
|
const dialog = useDialog(props);
|
||||||
|
|
|
@ -14,7 +14,7 @@ const schema = z.object({
|
||||||
filePath: z.string()
|
filePath: z.string()
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface BackupRestorationDialogProps extends UseDialogProps {}
|
export type BackupRestorationDialogProps = UseDialogProps;
|
||||||
|
|
||||||
export const BackupRestoreDialog = (props: BackupRestorationDialogProps) => {
|
export const BackupRestoreDialog = (props: BackupRestorationDialogProps) => {
|
||||||
const platform = usePlatform();
|
const platform = usePlatform();
|
||||||
|
|
|
@ -20,7 +20,7 @@ const schema = z.object({
|
||||||
hashing_algorithm: z.string()
|
hashing_algorithm: z.string()
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props extends UseDialogProps {}
|
type Props = UseDialogProps;
|
||||||
|
|
||||||
export default function CreateLibraryDialog(props: Props) {
|
export default function CreateLibraryDialog(props: Props) {
|
||||||
const dialog = useDialog(props);
|
const dialog = useDialog(props);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { useZodForm, z } from '@sd/ui/src/forms';
|
||||||
import { getHashingAlgorithmString } from '~/screens/settings/library/KeysSetting';
|
import { getHashingAlgorithmString } from '~/screens/settings/library/KeysSetting';
|
||||||
import { SelectOptionKeyList } from '../key/KeyList';
|
import { SelectOptionKeyList } from '../key/KeyList';
|
||||||
|
|
||||||
interface KeyViewerDialogProps extends UseDialogProps {}
|
type KeyViewerDialogProps = UseDialogProps;
|
||||||
|
|
||||||
export const KeyUpdater = (props: {
|
export const KeyUpdater = (props: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { showAlertDialog } from '~/util/dialog';
|
||||||
import { generatePassword } from '../key/KeyMounter';
|
import { generatePassword } from '../key/KeyMounter';
|
||||||
import { PasswordMeter } from '../key/PasswordMeter';
|
import { PasswordMeter } from '../key/PasswordMeter';
|
||||||
|
|
||||||
export interface MasterPasswordChangeDialogProps extends UseDialogProps {}
|
export type MasterPasswordChangeDialogProps = UseDialogProps;
|
||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
masterPassword: z.string(),
|
masterPassword: z.string(),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { ExplorerData, rspc, useCurrentLibrary } from '@sd/client';
|
import { ExplorerData, rspc, useCurrentLibrary } from '@sd/client';
|
||||||
import { useExplorerStore } from '~/hooks/useExplorerStore';
|
import { useExplorerStore } from '~/hooks/useExplorerStore';
|
||||||
import { Inspector } from '../explorer/Inspector';
|
import { Inspector } from '../explorer/Inspector';
|
||||||
|
@ -32,50 +32,50 @@ export default function Explorer(props: Props) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
const onScroll = useCallback((y: number) => {
|
||||||
<>
|
setScrollSegments((old) => {
|
||||||
<div className="relative">
|
return {
|
||||||
<ExplorerContextMenu>
|
...old,
|
||||||
<div className="relative flex flex-col w-full">
|
mainList: y
|
||||||
<TopBar showSeparator={separateTopBar} />
|
};
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
<ExplorerContextMenu>
|
||||||
|
<div className="relative flex flex-col w-full">
|
||||||
|
<TopBar showSeparator={separateTopBar} />
|
||||||
|
|
||||||
|
<div className="relative flex flex-row w-full max-h-full app-background">
|
||||||
|
{props.data && (
|
||||||
|
<VirtualizedList
|
||||||
|
data={props.data.items}
|
||||||
|
context={props.data.context}
|
||||||
|
onScroll={onScroll}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{expStore.showInspector && (
|
||||||
|
<div className="flex min-w-[260px] max-w-[260px]">
|
||||||
|
<Inspector
|
||||||
|
onScroll={(e) => {
|
||||||
|
const y = (e.target as HTMLElement).scrollTop;
|
||||||
|
|
||||||
<div className="relative flex flex-row w-full max-h-full app-background">
|
|
||||||
{props.data && (
|
|
||||||
<VirtualizedList
|
|
||||||
data={props.data.items || []}
|
|
||||||
context={props.data.context}
|
|
||||||
onScroll={(y) => {
|
|
||||||
setScrollSegments((old) => {
|
setScrollSegments((old) => {
|
||||||
return {
|
return {
|
||||||
...old,
|
...old,
|
||||||
mainList: y
|
inspector: y
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
key={props.data?.items[expStore.selectedRowIndex]?.id}
|
||||||
|
data={props.data?.items[expStore.selectedRowIndex]}
|
||||||
/>
|
/>
|
||||||
)}
|
</div>
|
||||||
{expStore.showInspector && (
|
)}
|
||||||
<div className="flex min-w-[260px] max-w-[260px]">
|
|
||||||
<Inspector
|
|
||||||
onScroll={(e) => {
|
|
||||||
const y = (e.target as HTMLElement).scrollTop;
|
|
||||||
|
|
||||||
setScrollSegments((old) => {
|
|
||||||
return {
|
|
||||||
...old,
|
|
||||||
inspector: y
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
key={props.data?.items[expStore.selectedRowIndex]?.id}
|
|
||||||
data={props.data?.items[expStore.selectedRowIndex]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</ExplorerContextMenu>
|
</div>
|
||||||
</div>
|
</ExplorerContextMenu>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
import { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { useKey, useOnWindowResize } from 'rooks';
|
import { useKey, useOnWindowResize } from 'rooks';
|
||||||
import { ExplorerContext, ExplorerItem } from '@sd/client';
|
import { ExplorerContext, ExplorerItem } from '@sd/client';
|
||||||
|
@ -17,7 +17,7 @@ interface Props {
|
||||||
onScroll?: (posY: number) => void;
|
onScroll?: (posY: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VirtualizedList: React.FC<Props> = ({ data, context, onScroll }) => {
|
export const VirtualizedList = memo(({ data, context, onScroll }: Props) => {
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
const innerRef = useRef<HTMLDivElement>(null);
|
const innerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ export const VirtualizedList: React.FC<Props> = ({ data, context, onScroll }) =>
|
||||||
el.addEventListener('scroll', onElementScroll);
|
el.addEventListener('scroll', onElementScroll);
|
||||||
|
|
||||||
return () => el.removeEventListener('scroll', onElementScroll);
|
return () => el.removeEventListener('scroll', onElementScroll);
|
||||||
}, [scrollRef, onScroll]);
|
}, [onScroll]);
|
||||||
|
|
||||||
const rowVirtualizer = useVirtualizer({
|
const rowVirtualizer = useVirtualizer({
|
||||||
count: amountOfRows,
|
count: amountOfRows,
|
||||||
|
@ -169,7 +169,7 @@ export const VirtualizedList: React.FC<Props> = ({ data, context, onScroll }) =>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
interface WrappedItemProps {
|
interface WrappedItemProps {
|
||||||
item: ExplorerItem;
|
item: ExplorerItem;
|
||||||
|
@ -179,7 +179,7 @@ interface WrappedItemProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap either list item or grid item with click logic as it is the same for both
|
// Wrap either list item or grid item with click logic as it is the same for both
|
||||||
const WrappedItem: React.FC<WrappedItemProps> = ({ item, index, isSelected, kind }) => {
|
const WrappedItem = memo(({ item, index, isSelected, kind }: WrappedItemProps) => {
|
||||||
const [_, setSearchParams] = useSearchParams();
|
const [_, setSearchParams] = useSearchParams();
|
||||||
|
|
||||||
const onDoubleClick = useCallback(() => {
|
const onDoubleClick = useCallback(() => {
|
||||||
|
@ -191,6 +191,7 @@ const WrappedItem: React.FC<WrappedItemProps> = ({ item, index, isSelected, kind
|
||||||
}, [isSelected, index]);
|
}, [isSelected, index]);
|
||||||
|
|
||||||
const ItemComponent = kind === 'list' ? FileRow : FileItem;
|
const ItemComponent = kind === 'list' ? FileRow : FileItem;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ItemComponent
|
<ItemComponent
|
||||||
data={item}
|
data={item}
|
||||||
|
@ -200,18 +201,4 @@ const WrappedItem: React.FC<WrappedItemProps> = ({ item, index, isSelected, kind
|
||||||
selected={isSelected}
|
selected={isSelected}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
});
|
||||||
// // Memorize the item so that it doesn't get re-rendered when the selection changes
|
|
||||||
// return useMemo(() => {
|
|
||||||
// const ItemComponent = kind === 'list' ? FileRow : FileItem;
|
|
||||||
// return (
|
|
||||||
// <ItemComponent
|
|
||||||
// data={item}
|
|
||||||
// index={index}
|
|
||||||
// onClick={onClick}
|
|
||||||
// onDoubleClick={onDoubleClick}
|
|
||||||
// selected={isSelected}
|
|
||||||
// />
|
|
||||||
// );
|
|
||||||
// }, [item, index, isSelected]);
|
|
||||||
};
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ function LibraryListItem(props: { library: LibraryConfigWrapped; current: boolea
|
||||||
<p className="mt-0.5 text-xs text-ink-dull">{props.library.uuid}</p>
|
<p className="mt-0.5 text-xs text-ink-dull">{props.library.uuid}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row items-center space-x-2">
|
<div className="flex flex-row items-center space-x-2">
|
||||||
<Button className="!p-1.5" onClick={() => {}} variant="gray">
|
<Button className="!p-1.5" variant="gray">
|
||||||
<Tooltip label="TODO">
|
<Tooltip label="TODO">
|
||||||
<Database className="w-4 h-4" />
|
<Database className="w-4 h-4" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"types": ["vite-plugin-svgr/client", "vite/client"]
|
"types": ["vite-plugin-svgr/client", "vite/client"]
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
|
"exclude": ["dist"],
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
"path": "../ui"
|
"path": "../ui"
|
||||||
|
|
7
packages/ui/.eslintrc.js
Normal file
7
packages/ui/.eslintrc.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: [require.resolve('@sd/config/eslint/web.js')],
|
||||||
|
parserOptions: {
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
project: './tsconfig.json'
|
||||||
|
}
|
||||||
|
};
|
|
@ -16,6 +16,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"storybook": "start-storybook -p 6006",
|
"storybook": "start-storybook -p 6006",
|
||||||
"storybook:build": "build-storybook",
|
"storybook:build": "build-storybook",
|
||||||
|
"lint": "eslint src",
|
||||||
"typecheck": "tsc -b",
|
"typecheck": "tsc -b",
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
},
|
},
|
||||||
|
|
|
@ -75,7 +75,7 @@ function Remover({ id }: { id: number }) {
|
||||||
() => () => {
|
() => () => {
|
||||||
dialogManager.remove(id);
|
dialogManager.remove(id);
|
||||||
},
|
},
|
||||||
[]
|
[id]
|
||||||
);
|
);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -39,7 +39,7 @@ type DropdownItemProps =
|
||||||
VariantProps<typeof itemStyles>;
|
VariantProps<typeof itemStyles>;
|
||||||
|
|
||||||
export const Item = ({ to, className, icon: Icon, children, ...props }: DropdownItemProps) => {
|
export const Item = ({ to, className, icon: Icon, children, ...props }: DropdownItemProps) => {
|
||||||
let content = (
|
const content = (
|
||||||
<>
|
<>
|
||||||
{Icon && <Icon weight="bold" className={itemIconStyles(props)} />}
|
{Icon && <Icon weight="bold" className={itemIconStyles(props)} />}
|
||||||
<span className="text-left">{children}</span>
|
<span className="text-left">{children}</span>
|
||||||
|
|
|
@ -17,6 +17,7 @@ type TailwindFactory = {
|
||||||
<T>(c: T): ClassnameFactory<T>;
|
<T>(c: T): ClassnameFactory<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// eslint-ignore-next-line
|
||||||
export const tw = new Proxy((() => {}) as unknown as TailwindFactory, {
|
export const tw = new Proxy((() => {}) as unknown as TailwindFactory, {
|
||||||
get: (_, property: string) => twFactory(property),
|
get: (_, property: string) => twFactory(property),
|
||||||
apply: (_, __, [el]: [React.ReactElement]) => twFactory(el)
|
apply: (_, __, [el]: [React.ReactElement]) => twFactory(el)
|
||||||
|
|
|
@ -390,10 +390,11 @@ importers:
|
||||||
|
|
||||||
packages/config:
|
packages/config:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@typescript-eslint/eslint-plugin': ^5.39.0
|
'@typescript-eslint/eslint-plugin': ^5.48.2
|
||||||
'@typescript-eslint/parser': ^5.39.0
|
'@typescript-eslint/parser': ^5.48.2
|
||||||
eslint: ^8.24.0
|
eslint: ^8.24.0
|
||||||
eslint-config-prettier: ^8.5.0
|
eslint-config-prettier: ^8.5.0
|
||||||
|
eslint-config-turbo: ^0.0.7
|
||||||
eslint-plugin-react: ^7.31.8
|
eslint-plugin-react: ^7.31.8
|
||||||
eslint-plugin-react-hooks: ^4.6.0
|
eslint-plugin-react-hooks: ^4.6.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
@ -401,6 +402,7 @@ importers:
|
||||||
'@typescript-eslint/parser': 5.48.2_eslint@8.32.0
|
'@typescript-eslint/parser': 5.48.2_eslint@8.32.0
|
||||||
eslint: 8.32.0
|
eslint: 8.32.0
|
||||||
eslint-config-prettier: 8.6.0_eslint@8.32.0
|
eslint-config-prettier: 8.6.0_eslint@8.32.0
|
||||||
|
eslint-config-turbo: 0.0.7_eslint@8.32.0
|
||||||
eslint-plugin-react: 7.32.1_eslint@8.32.0
|
eslint-plugin-react: 7.32.1_eslint@8.32.0
|
||||||
eslint-plugin-react-hooks: 4.6.0_eslint@8.32.0
|
eslint-plugin-react-hooks: 4.6.0_eslint@8.32.0
|
||||||
|
|
||||||
|
@ -423,7 +425,7 @@ importers:
|
||||||
'@splinetool/runtime': ^0.9.128
|
'@splinetool/runtime': ^0.9.128
|
||||||
'@tailwindcss/forms': ^0.5.3
|
'@tailwindcss/forms': ^0.5.3
|
||||||
'@tanstack/react-query': ^4.12.0
|
'@tanstack/react-query': ^4.12.0
|
||||||
'@tanstack/react-query-devtools': ^4.12.0
|
'@tanstack/react-query-devtools': ^4.22.0
|
||||||
'@tanstack/react-virtual': 3.0.0-beta.18
|
'@tanstack/react-virtual': 3.0.0-beta.18
|
||||||
'@types/babel-core': ^6.25.7
|
'@types/babel-core': ^6.25.7
|
||||||
'@types/byte-size': ^8.1.0
|
'@types/byte-size': ^8.1.0
|
||||||
|
@ -8264,7 +8266,7 @@ packages:
|
||||||
'@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.12
|
'@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.12
|
||||||
magic-string: 0.26.7
|
magic-string: 0.26.7
|
||||||
react-refresh: 0.14.0
|
react-refresh: 0.14.0
|
||||||
vite: 4.0.4_sass@1.57.1
|
vite: 4.0.4_@types+node@18.11.18
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
@ -11609,6 +11611,15 @@ packages:
|
||||||
eslint: 8.32.0
|
eslint: 8.32.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint-config-turbo/0.0.7_eslint@8.32.0:
|
||||||
|
resolution: {integrity: sha512-WbrGlyfs94rOXrhombi1wjIAYGdV2iosgJRndOZtmDQeq5GLTzYmBUCJQZWtLBEBUPCj96RxZ2OL7Cn+xv/Azg==}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: '>6.6.0'
|
||||||
|
dependencies:
|
||||||
|
eslint: 8.32.0
|
||||||
|
eslint-plugin-turbo: 0.0.7_eslint@8.32.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-react-hooks/4.6.0_eslint@8.32.0:
|
/eslint-plugin-react-hooks/4.6.0_eslint@8.32.0:
|
||||||
resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
|
resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
@ -11657,6 +11668,14 @@ packages:
|
||||||
string.prototype.matchall: 4.0.8
|
string.prototype.matchall: 4.0.8
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint-plugin-turbo/0.0.7_eslint@8.32.0:
|
||||||
|
resolution: {integrity: sha512-iajOH8eD4jha3duztGVBD1BEmvNrQBaA/y3HFHf91vMDRYRwH7BpHSDFtxydDpk5ghlhRxG299SFxz7D6z4MBQ==}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: '>6.6.0'
|
||||||
|
dependencies:
|
||||||
|
eslint: 8.32.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint-scope/4.0.3:
|
/eslint-scope/4.0.3:
|
||||||
resolution: {integrity: sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==}
|
resolution: {integrity: sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==}
|
||||||
engines: {node: '>=4.0.0'}
|
engines: {node: '>=4.0.0'}
|
||||||
|
@ -20748,7 +20767,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/pluginutils': 5.0.2
|
'@rollup/pluginutils': 5.0.2
|
||||||
'@svgr/core': 6.5.1
|
'@svgr/core': 6.5.1
|
||||||
vite: 4.0.4_sass@1.57.1
|
vite: 4.0.4_@types+node@18.11.18
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- rollup
|
- rollup
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -20844,7 +20863,6 @@ packages:
|
||||||
rollup: 3.10.0
|
rollup: 3.10.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
|
||||||
|
|
||||||
/vite/4.0.4_ovmyjmuuyckt3r3gpaexj2onji:
|
/vite/4.0.4_ovmyjmuuyckt3r3gpaexj2onji:
|
||||||
resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==}
|
resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==}
|
||||||
|
@ -20912,6 +20930,7 @@ packages:
|
||||||
sass: 1.57.1
|
sass: 1.57.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/vlq/1.0.1:
|
/vlq/1.0.1:
|
||||||
resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==}
|
resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==}
|
||||||
|
|
Loading…
Reference in a new issue