mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-23 09:51:10 +01:00
Switch to BiomeJS (#306)
This commit is contained in:
@@ -11,9 +11,18 @@ import {
|
||||
import { type } from '@tauri-apps/plugin-os';
|
||||
import classNames from 'classnames';
|
||||
import type { ComponentType, MouseEvent, ReactElement, Ref, RefAttributes } from 'react';
|
||||
import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, } from 'react';
|
||||
import {
|
||||
forwardRef,
|
||||
memo,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useKey, useKeyPressEvent } from 'react-use';
|
||||
import type { HotkeyAction, HotKeyOptions } from '../../../hooks/useHotKey';
|
||||
import type { HotKeyOptions, HotkeyAction } from '../../../hooks/useHotKey';
|
||||
import { useHotKey } from '../../../hooks/useHotKey';
|
||||
import { computeSideForDragMove } from '../../../lib/dnd';
|
||||
import { jotaiStore } from '../../../lib/jotai';
|
||||
@@ -102,6 +111,7 @@ function TreeInner<T extends { id: string }>(
|
||||
}, []);
|
||||
|
||||
// Select the first item on first render
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: Only used for initial render
|
||||
useEffect(() => {
|
||||
const ids = jotaiStore.get(selectedIdsFamily(treeId));
|
||||
const fallback = selectableItems[0];
|
||||
@@ -112,7 +122,6 @@ function TreeInner<T extends { id: string }>(
|
||||
lastId: fallback.node.item.id,
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [treeId]);
|
||||
|
||||
const handleCloseContextMenu = useCallback(() => {
|
||||
@@ -129,11 +138,10 @@ function TreeInner<T extends { id: string }>(
|
||||
);
|
||||
if ($el == null) {
|
||||
return false;
|
||||
} else {
|
||||
$el.focus();
|
||||
$el.scrollIntoView({ block: 'nearest' });
|
||||
return true;
|
||||
}
|
||||
$el.focus();
|
||||
$el.scrollIntoView({ block: 'nearest' });
|
||||
return true;
|
||||
}, []);
|
||||
|
||||
const ensureTabbableItem = useCallback(() => {
|
||||
@@ -166,7 +174,7 @@ function TreeInner<T extends { id: string }>(
|
||||
useEffect(() => {
|
||||
const unsub = jotaiStore.sub(collapsedFamily(treeId), ensureTabbableItem);
|
||||
return unsub;
|
||||
}, [ensureTabbableItem, isTreeFocused, selectableItems, treeId, tryFocus]);
|
||||
}, [ensureTabbableItem, treeId]);
|
||||
|
||||
// Ensure there's always a tabbable item after render
|
||||
useEffect(() => {
|
||||
@@ -224,13 +232,12 @@ function TreeInner<T extends { id: string }>(
|
||||
if (isSelected) {
|
||||
// If right-clicked an item that was in the multiple-selection, use the entire selection
|
||||
return getContextMenu(items);
|
||||
} else {
|
||||
// If right-clicked an item that was NOT in the multiple-selection, just use that one
|
||||
// Also update the selection with it
|
||||
setSelected([item.id], false);
|
||||
jotaiStore.set(focusIdsFamily(treeId), (prev) => ({ ...prev, lastId: item.id }));
|
||||
return getContextMenu([item]);
|
||||
}
|
||||
// If right-clicked an item that was NOT in the multiple-selection, just use that one
|
||||
// Also update the selection with it
|
||||
setSelected([item.id], false);
|
||||
jotaiStore.set(focusIdsFamily(treeId), (prev) => ({ ...prev, lastId: item.id }));
|
||||
return getContextMenu([item]);
|
||||
};
|
||||
}, [getContextMenu, selectableItems, setSelected, treeId]);
|
||||
|
||||
@@ -728,6 +735,7 @@ function DropRegionAfterList({
|
||||
onContextMenu?: (e: MouseEvent<HTMLDivElement>) => void;
|
||||
}) {
|
||||
const { setNodeRef } = useDroppable({ id });
|
||||
// biome-ignore lint/a11y/noStaticElementInteractions: Meh
|
||||
return <div ref={setNodeRef} onContextMenu={onContextMenu} />;
|
||||
}
|
||||
|
||||
@@ -758,7 +766,7 @@ function TreeHotKey<T extends { id: string }>({
|
||||
enable: () => {
|
||||
if (enable == null) return true;
|
||||
if (typeof enable === 'function') return enable();
|
||||
else return enable;
|
||||
return enable;
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -19,7 +19,7 @@ export function TreeDragOverlay<T extends { id: string }>({
|
||||
return (
|
||||
<DragOverlay dropAnimation={null}>
|
||||
<TreeItemList
|
||||
treeId={treeId + '.dragging'}
|
||||
treeId={`${treeId}.dragging`}
|
||||
nodes={selectableItems.filter((i) => draggingItems.includes(i.node.item.id))}
|
||||
getItemKey={getItemKey}
|
||||
ItemInner={ItemInner}
|
||||
|
||||
@@ -19,6 +19,7 @@ export const TreeIndentGuide = memo(function TreeIndentGuide({
|
||||
<div className="flex">
|
||||
{Array.from({ length: depth }).map((_, i) => (
|
||||
<div
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
||||
key={i}
|
||||
className={classNames(
|
||||
'w-[calc(1rem+0.5px)] border-r border-r-text-subtlest',
|
||||
|
||||
@@ -3,14 +3,15 @@ import { useDndContext, useDndMonitor, useDraggable, useDroppable } from '@dnd-k
|
||||
import classNames from 'classnames';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { selectAtom } from 'jotai/utils';
|
||||
import type React from 'react';
|
||||
import type { MouseEvent, PointerEvent } from 'react';
|
||||
import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { computeSideForDragMove } from '../../../lib/dnd';
|
||||
import { jotaiStore } from '../../../lib/jotai';
|
||||
import type { ContextMenuProps, DropdownItem } from '../Dropdown';
|
||||
import { ContextMenu } from '../Dropdown';
|
||||
import { Icon } from '../Icon';
|
||||
import { collapsedFamily, isCollapsedFamily, isLastFocusedFamily, isSelectedFamily, } from './atoms';
|
||||
import { collapsedFamily, isCollapsedFamily, isLastFocusedFamily, isSelectedFamily } from './atoms';
|
||||
import type { TreeNode } from './common';
|
||||
import { getNodeKey } from './common';
|
||||
import type { TreeProps } from './Tree';
|
||||
@@ -84,7 +85,7 @@ function TreeItem_<T extends { id: string }>({
|
||||
},
|
||||
scrollIntoView: () => {
|
||||
listItemRef.current?.scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
},
|
||||
}),
|
||||
[editing, getEditOptions],
|
||||
);
|
||||
@@ -272,10 +273,6 @@ function TreeItem_<T extends { id: string }>({
|
||||
return (
|
||||
<li
|
||||
ref={listItemRef}
|
||||
role="treeitem"
|
||||
aria-level={depth + 1}
|
||||
aria-expanded={node.children == null ? undefined : !isCollapsed}
|
||||
aria-selected={isSelected}
|
||||
onContextMenu={handleContextMenu}
|
||||
className={classNames(
|
||||
className,
|
||||
@@ -304,6 +301,7 @@ function TreeItem_<T extends { id: string }>({
|
||||
)}
|
||||
{node.children != null ? (
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
className="h-full pl-[0.5rem] outline-none"
|
||||
onClick={toggleCollapsed}
|
||||
|
||||
@@ -29,7 +29,7 @@ export function TreeItemList<T extends { id: string }>({
|
||||
...props
|
||||
}: TreeItemListProps<T>) {
|
||||
return (
|
||||
<ul role="tree" style={style} className={className}>
|
||||
<ul style={style} className={className}>
|
||||
<TreeDropMarker node={null} treeId={treeId} index={0} />
|
||||
{nodes.map((child, i) => (
|
||||
<Fragment key={getItemKey(child.node.item)}>
|
||||
|
||||
@@ -21,7 +21,7 @@ export const focusIdsFamily = atomFamily((_treeId: string) => {
|
||||
|
||||
export const isLastFocusedFamily = atomFamily(
|
||||
({ treeId, itemId }: { treeId: string; itemId: string }) =>
|
||||
selectAtom(focusIdsFamily(treeId), (v) => v.lastId == itemId, Object.is),
|
||||
selectAtom(focusIdsFamily(treeId), (v) => v.lastId === itemId, Object.is),
|
||||
(a, b) => a.treeId === b.treeId && a.itemId === b.itemId,
|
||||
);
|
||||
|
||||
|
||||
@@ -35,8 +35,13 @@ export function equalSubtree<T extends { id: string }>(
|
||||
if (getNodeKey(a, getItemKey) !== getNodeKey(b, getItemKey)) return false;
|
||||
const ak = a.children ?? [];
|
||||
const bk = b.children ?? [];
|
||||
if (ak.length !== bk.length) return false;
|
||||
|
||||
if (ak.length !== bk.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < ak.length; i++) {
|
||||
// biome-ignore lint/style/noNonNullAssertion: none
|
||||
if (!equalSubtree(ak[i]!, bk[i]!, getItemKey)) return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ export function useSelectableItems<T extends { id: string }>(root: TreeNode<T>)
|
||||
const selectableItems: SelectableTreeNode<T>[] = [];
|
||||
|
||||
// Put requests and folders into a tree structure
|
||||
const next = (node: TreeNode<T>, depth: number = 0) => {
|
||||
const next = (node: TreeNode<T>, depth = 0) => {
|
||||
if (node.children == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user