mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-21 00:49:17 +01:00
Add React hooks eslint
This commit is contained in:
@@ -54,7 +54,7 @@ export function Dropdown({ children, items }: DropdownProps) {
|
||||
const handleClose = useCallback(() => {
|
||||
setOpen(false);
|
||||
ref.current?.focus();
|
||||
}, [ref.current]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
ref.current?.setAttribute('aria-expanded', open.toString());
|
||||
@@ -63,7 +63,7 @@ export function Dropdown({ children, items }: DropdownProps) {
|
||||
const triggerRect = useMemo(() => {
|
||||
if (!open) return null;
|
||||
return ref.current?.getBoundingClientRect();
|
||||
}, [ref.current, open]);
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -83,8 +83,6 @@ interface MenuProps {
|
||||
}
|
||||
|
||||
function Menu({ className, items, onClose, triggerRect }: MenuProps) {
|
||||
if (triggerRect === undefined) return null;
|
||||
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const [menuStyles, setMenuStyles] = useState<CSSProperties>({});
|
||||
|
||||
|
||||
@@ -88,12 +88,14 @@ const _Editor = forwardRef<EditorView | undefined, EditorProps>(function Editor(
|
||||
const { view, languageCompartment } = cm.current;
|
||||
const ext = getLanguageExtension({ contentType, useTemplating, autocomplete });
|
||||
view.dispatch({ effects: languageCompartment.reconfigure(ext) });
|
||||
}, [contentType, autocomplete]);
|
||||
}, [contentType, autocomplete, useTemplating]);
|
||||
|
||||
useEffect(() => {
|
||||
if (cm.current === null) return;
|
||||
const { view } = cm.current;
|
||||
view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: defaultValue ?? '' } });
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [forceUpdateKey]);
|
||||
|
||||
// Initialize the editor when ref mounts
|
||||
@@ -133,6 +135,8 @@ const _Editor = forwardRef<EditorView | undefined, EditorProps>(function Editor(
|
||||
} catch (e) {
|
||||
console.log('Failed to initialize Codemirror', e);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const cmContainer = (
|
||||
|
||||
@@ -36,7 +36,7 @@ const _IconButton = forwardRef<HTMLButtonElement, Props>(function IconButton(
|
||||
if (showConfirm) setConfirmed();
|
||||
onClick?.(e);
|
||||
},
|
||||
[onClick],
|
||||
[onClick, setConfirmed, showConfirm],
|
||||
);
|
||||
return (
|
||||
<Button
|
||||
|
||||
@@ -63,10 +63,13 @@ export function Input({
|
||||
return true;
|
||||
}, [currentValue, validate, require]);
|
||||
|
||||
const handleChange = useCallback((value: string) => {
|
||||
setCurrentValue(value);
|
||||
onChange?.(value);
|
||||
}, []);
|
||||
const handleChange = useCallback(
|
||||
(value: string) => {
|
||||
setCurrentValue(value);
|
||||
onChange?.(value);
|
||||
},
|
||||
[onChange],
|
||||
);
|
||||
|
||||
return (
|
||||
<VStack className="w-full">
|
||||
|
||||
@@ -62,6 +62,8 @@ export const PairEditor = memo(function PairEditor({
|
||||
const nonEmpty = originalPairs.filter((h) => !(h.name === '' && h.value === ''));
|
||||
const pairs = nonEmpty.map((pair) => newPairContainer(pair));
|
||||
setPairs([...pairs, newPairContainer()]);
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [forceUpdateKey]);
|
||||
|
||||
const setPairsAndSave = useCallback(
|
||||
@@ -99,19 +101,19 @@ export const PairEditor = memo(function PairEditor({
|
||||
return newPairs;
|
||||
});
|
||||
},
|
||||
[hoveredIndex],
|
||||
[hoveredIndex, setPairsAndSave],
|
||||
);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(pair: PairContainer) =>
|
||||
setPairsAndSave((pairs) => pairs.map((p) => (pair.id !== p.id ? p : pair))),
|
||||
[],
|
||||
[setPairsAndSave],
|
||||
);
|
||||
|
||||
const handleDelete = useCallback(
|
||||
(pair: PairContainer) =>
|
||||
setPairsAndSave((oldPairs) => oldPairs.filter((p) => p.id !== pair.id)),
|
||||
[],
|
||||
[setPairsAndSave],
|
||||
);
|
||||
|
||||
const handleFocus = useCallback(
|
||||
@@ -216,17 +218,17 @@ const FormRow = memo(function FormRow({
|
||||
|
||||
const handleChangeEnabled = useMemo(
|
||||
() => (enabled: boolean) => onChange({ id, pair: { ...pairContainer.pair, enabled } }),
|
||||
[onChange, pairContainer.pair.name, pairContainer.pair.value],
|
||||
[id, onChange, pairContainer.pair],
|
||||
);
|
||||
|
||||
const handleChangeName = useMemo(
|
||||
() => (name: string) => onChange({ id, pair: { ...pairContainer.pair, name } }),
|
||||
[onChange, pairContainer.pair.value, pairContainer.pair.enabled],
|
||||
[onChange, id, pairContainer.pair],
|
||||
);
|
||||
|
||||
const handleChangeValue = useMemo(
|
||||
() => (value: string) => onChange({ id, pair: { ...pairContainer.pair, value } }),
|
||||
[onChange, pairContainer.pair.name, pairContainer.pair.enabled],
|
||||
[onChange, id, pairContainer.pair],
|
||||
);
|
||||
|
||||
const handleFocus = useCallback(() => onFocus?.(pairContainer), [onFocus, pairContainer]);
|
||||
|
||||
@@ -39,7 +39,7 @@ export function RadioDropdown<T = string | null>({
|
||||
};
|
||||
}
|
||||
}),
|
||||
[value, items],
|
||||
[items, value, onChange],
|
||||
);
|
||||
|
||||
return <Dropdown items={dropdownItems}>{children}</Dropdown>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import classnames from 'classnames';
|
||||
import type { ReactNode } from 'react';
|
||||
import { memo, useEffect, useRef } from 'react';
|
||||
import { memo, useCallback, useEffect, useRef } from 'react';
|
||||
import { Button } from '../Button';
|
||||
import { Icon } from '../Icon';
|
||||
import type { RadioDropdownProps } from '../RadioDropdown';
|
||||
@@ -38,28 +38,31 @@ export function Tabs({
|
||||
}: Props) {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const handleTabChange = (value: string) => {
|
||||
const tabs = ref.current?.querySelectorAll<HTMLDivElement>(`[data-tab]`);
|
||||
for (const tab of tabs ?? []) {
|
||||
const v = tab.getAttribute('data-tab');
|
||||
if (v === value) {
|
||||
tab.setAttribute('tabindex', '-1');
|
||||
tab.setAttribute('data-state', 'active');
|
||||
tab.setAttribute('aria-hidden', 'false');
|
||||
tab.style.display = 'block';
|
||||
} else {
|
||||
tab.setAttribute('data-state', 'inactive');
|
||||
tab.setAttribute('aria-hidden', 'true');
|
||||
tab.style.display = 'none';
|
||||
const handleTabChange = useCallback(
|
||||
(value: string) => {
|
||||
const tabs = ref.current?.querySelectorAll<HTMLDivElement>(`[data-tab]`);
|
||||
for (const tab of tabs ?? []) {
|
||||
const v = tab.getAttribute('data-tab');
|
||||
if (v === value) {
|
||||
tab.setAttribute('tabindex', '-1');
|
||||
tab.setAttribute('data-state', 'active');
|
||||
tab.setAttribute('aria-hidden', 'false');
|
||||
tab.style.display = 'block';
|
||||
} else {
|
||||
tab.setAttribute('data-state', 'inactive');
|
||||
tab.setAttribute('aria-hidden', 'true');
|
||||
tab.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
onChangeValue(value);
|
||||
};
|
||||
onChangeValue(value);
|
||||
},
|
||||
[onChangeValue],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (value === undefined) return;
|
||||
handleTabChange(value);
|
||||
}, [value]);
|
||||
}, [handleTabChange, value]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -13,7 +13,7 @@ export function Webview({ body, url, contentType }: Props) {
|
||||
return body.replace(/<head>/gi, `<head><base href="${url}"/>`);
|
||||
}
|
||||
return body;
|
||||
}, [body, contentType]);
|
||||
}, [url, body, contentType]);
|
||||
|
||||
return (
|
||||
<div className="px-2 pb-2">
|
||||
|
||||
Reference in New Issue
Block a user