mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-30 03:16:25 +02:00
chore: linting
This commit is contained in:
parent
23b4f91754
commit
64c913baa3
47 changed files with 908 additions and 895 deletions
|
|
@ -18,7 +18,7 @@ import {
|
|||
import * as React from "react";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { Tooltip, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const UNDRAGGABLE_KEYS = [KEYS.column, KEYS.tr, KEYS.td];
|
||||
|
|
@ -94,23 +94,24 @@ function Draggable(props: PlateElementProps) {
|
|||
};
|
||||
|
||||
// clear up virtual multiple preview when drag end
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: resetPreview is stable; intentionally only run on isDragging change
|
||||
React.useEffect(() => {
|
||||
if (!isDragging) {
|
||||
resetPreview();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isDragging]);
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: previewRef is a stable ref; only run on isAboutToDrag change
|
||||
React.useEffect(() => {
|
||||
if (isAboutToDrag) {
|
||||
previewRef.current?.classList.remove("opacity-0");
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isAboutToDrag]);
|
||||
|
||||
const [dragButtonTop, setDragButtonTop] = React.useState(0);
|
||||
|
||||
return (
|
||||
// biome-ignore lint/a11y/noStaticElementInteractions: plate editor block wrapper requires mouse events
|
||||
<div
|
||||
className={cn(
|
||||
"relative",
|
||||
|
|
@ -158,6 +159,7 @@ function Draggable(props: PlateElementProps) {
|
|||
contentEditable={false}
|
||||
/>
|
||||
|
||||
{/* biome-ignore lint/a11y/noStaticElementInteractions: plate editor context menu handler */}
|
||||
<div
|
||||
ref={nodeRef}
|
||||
className="slate-blockWrapper flow-root"
|
||||
|
|
@ -215,8 +217,10 @@ const DragHandle = React.memo(function DragHandle({
|
|||
return (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
{/* biome-ignore lint/a11y/useSemanticElements: drag handle requires div for plate editor integration */}
|
||||
<div
|
||||
className="flex size-full items-center justify-center"
|
||||
tabIndex={0}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
editor.getApi(BlockSelectionPlugin).blockSelection.focus();
|
||||
|
|
@ -291,6 +295,12 @@ const DragHandle = React.memo(function DragHandle({
|
|||
onMouseUp={() => {
|
||||
resetPreview();
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
editor.getApi(BlockSelectionPlugin).blockSelection.focus();
|
||||
}
|
||||
}}
|
||||
data-plate-prevent-deselect
|
||||
role="button"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -43,10 +43,16 @@ export function EquationElement({ children, ...props }: PlateElementProps<TEquat
|
|||
props.className
|
||||
)}
|
||||
>
|
||||
{/* biome-ignore lint/a11y/useSemanticElements: contentEditable context requires div */}
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="flex cursor-pointer items-center justify-center"
|
||||
contentEditable={false}
|
||||
onDoubleClick={() => setIsEditing(true)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") setIsEditing(true);
|
||||
}}
|
||||
>
|
||||
{element.texExpression ? (
|
||||
<div ref={katexRef} className="text-center" />
|
||||
|
|
@ -123,10 +129,16 @@ export function InlineEquationElement({ children, ...props }: PlateElementProps<
|
|||
as="span"
|
||||
className={cn("inline rounded-sm px-0.5", selected && "bg-brand/15", props.className)}
|
||||
>
|
||||
{/* biome-ignore lint/a11y/useSemanticElements: inline contentEditable context requires span */}
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="cursor-pointer"
|
||||
contentEditable={false}
|
||||
onDoubleClick={() => setIsEditing(true)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") setIsEditing(true);
|
||||
}}
|
||||
>
|
||||
{element.texExpression ? (
|
||||
<span ref={katexRef} />
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ function HeroCarouselCard({
|
|||
observer.observe(video);
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, [src]);
|
||||
}, []);
|
||||
|
||||
const handleCanPlay = useCallback(() => {
|
||||
setHasLoaded(true);
|
||||
|
|
@ -114,7 +114,19 @@ function HeroCarouselCard({
|
|||
<p className="text-sm text-neutral-500 dark:text-neutral-400">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="cursor-pointer bg-neutral-50 p-2 sm:p-3 dark:bg-neutral-950" onClick={open}>
|
||||
{/* biome-ignore lint/a11y/useSemanticElements: div wraps video element, button would break layout */}
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="cursor-pointer bg-neutral-50 p-2 sm:p-3 dark:bg-neutral-950"
|
||||
onClick={open}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
open();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="relative">
|
||||
<video
|
||||
ref={videoRef}
|
||||
|
|
@ -185,45 +197,45 @@ function HeroCarousel() {
|
|||
</AnimatePresence>
|
||||
</div>
|
||||
|
||||
<div className="relative z-5 mt-4 flex items-center justify-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => !isGifExpanded && goToPrev()}
|
||||
className="flex size-11 items-center justify-center rounded-full border border-neutral-200 bg-white text-neutral-700 shadow-sm transition-colors hover:bg-neutral-100 touch-manipulation dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-200 dark:hover:bg-neutral-700"
|
||||
aria-label="Previous slide"
|
||||
>
|
||||
<ChevronLeft className="size-5" />
|
||||
</button>
|
||||
<div className="relative z-5 mt-4 flex items-center justify-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => !isGifExpanded && goToPrev()}
|
||||
className="flex size-11 items-center justify-center rounded-full border border-neutral-200 bg-white text-neutral-700 shadow-sm transition-colors hover:bg-neutral-100 touch-manipulation dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-200 dark:hover:bg-neutral-700"
|
||||
aria-label="Previous slide"
|
||||
>
|
||||
<ChevronLeft className="size-5" />
|
||||
</button>
|
||||
|
||||
<div className="flex items-center">
|
||||
{carouselItems.map((_, i) => (
|
||||
<button
|
||||
key={`dot_${i}`}
|
||||
type="button"
|
||||
onClick={() => !isGifExpanded && goTo(i)}
|
||||
className="flex h-11 min-w-[28px] items-center justify-center touch-manipulation"
|
||||
aria-label={`Go to slide ${i + 1}`}
|
||||
>
|
||||
<span
|
||||
className={`block h-2.5 rounded-full transition-all duration-300 ${
|
||||
i === activeIndex
|
||||
? "w-6 bg-neutral-900 dark:bg-white"
|
||||
: "w-2.5 bg-neutral-300 hover:bg-neutral-400 dark:bg-neutral-600 dark:hover:bg-neutral-500"
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
))}
|
||||
<div className="flex items-center">
|
||||
{carouselItems.map((_, i) => (
|
||||
<button
|
||||
key={`dot_${i}`}
|
||||
type="button"
|
||||
onClick={() => !isGifExpanded && goTo(i)}
|
||||
className="flex h-11 min-w-[28px] items-center justify-center touch-manipulation"
|
||||
aria-label={`Go to slide ${i + 1}`}
|
||||
>
|
||||
<span
|
||||
className={`block h-2.5 rounded-full transition-all duration-300 ${
|
||||
i === activeIndex
|
||||
? "w-6 bg-neutral-900 dark:bg-white"
|
||||
: "w-2.5 bg-neutral-300 hover:bg-neutral-400 dark:bg-neutral-600 dark:hover:bg-neutral-500"
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => !isGifExpanded && goToNext()}
|
||||
className="flex size-11 items-center justify-center rounded-full border border-neutral-200 bg-white text-neutral-700 shadow-sm transition-colors hover:bg-neutral-100 touch-manipulation dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-200 dark:hover:bg-neutral-700"
|
||||
aria-label="Next slide"
|
||||
>
|
||||
<ChevronRight className="size-5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => !isGifExpanded && goToNext()}
|
||||
className="flex size-11 items-center justify-center rounded-full border border-neutral-200 bg-white text-neutral-700 shadow-sm transition-colors hover:bg-neutral-100 touch-manipulation dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-200 dark:hover:bg-neutral-700"
|
||||
aria-label="Next slide"
|
||||
>
|
||||
<ChevronRight className="size-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,22 +160,21 @@ function LinkOpenButton() {
|
|||
const editor = useEditorRef();
|
||||
const selection = useEditorSelection();
|
||||
|
||||
const attributes = React.useMemo(
|
||||
() => {
|
||||
const entry = editor.api.node<TLinkElement>({
|
||||
match: { type: editor.getType(KEYS.link) },
|
||||
});
|
||||
if (!entry) {
|
||||
return {};
|
||||
}
|
||||
const [element] = entry;
|
||||
return getLinkAttributes(editor, element);
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[editor, selection]
|
||||
);
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: selection triggers recalculation of link attributes
|
||||
const attributes = React.useMemo(() => {
|
||||
const entry = editor.api.node<TLinkElement>({
|
||||
match: { type: editor.getType(KEYS.link) },
|
||||
});
|
||||
if (!entry) {
|
||||
return {};
|
||||
}
|
||||
const [element] = entry;
|
||||
return getLinkAttributes(editor, element);
|
||||
}, [editor, selection]);
|
||||
|
||||
return (
|
||||
// biome-ignore lint/a11y/noStaticElementInteractions: <a> with spread attributes has dynamic href
|
||||
// biome-ignore lint/a11y/useAriaPropsSupportedByRole: aria-label needed for icon-only link
|
||||
<a
|
||||
{...attributes}
|
||||
className={buttonVariants({
|
||||
|
|
@ -185,6 +184,9 @@ function LinkOpenButton() {
|
|||
onMouseOver={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onFocus={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
aria-label="Open link in a new tab"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
|
|
|
|||
|
|
@ -219,7 +219,8 @@ export function ToolbarSplitButtonSecondary({
|
|||
...props
|
||||
}: React.ComponentPropsWithoutRef<"span"> & VariantProps<typeof dropdownArrowVariants>) {
|
||||
return (
|
||||
<span
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
dropdownArrowVariants({
|
||||
size,
|
||||
|
|
@ -229,11 +230,10 @@ export function ToolbarSplitButtonSecondary({
|
|||
className
|
||||
)}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
role="button"
|
||||
{...props}
|
||||
{...(props as React.ComponentPropsWithoutRef<"button">)}
|
||||
>
|
||||
<ChevronDown className="size-3.5 text-muted-foreground" data-icon />
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue