Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement new linter rules in preparation for react compiler #961

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ui/admin/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = {
// React
{
files: ["**/*.{js,jsx,ts,tsx}"],
plugins: ["react", "jsx-a11y"],
plugins: ["react", "jsx-a11y", "react-compiler"],
extends: [
"plugin:react/recommended",
"plugin:react/jsx-runtime",
Expand All @@ -50,6 +50,7 @@ module.exports = {
},
rules: {
"react/prop-types": "off",
"react-compiler/react-compiler": "error",
"no-restricted-imports": [
"error",
{
Expand Down
21 changes: 17 additions & 4 deletions ui/admin/app/components/ui/multi-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ const CommandEmpty = forwardRef<

CommandEmpty.displayName = "CommandEmpty";

/**
* @deprecated This component is super bulky and has some weird bugs. We need to create a new one that behaves similarly to ComboBox
ivyjeong13 marked this conversation as resolved.
Show resolved Hide resolved
*/
const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
(
{
Expand Down Expand Up @@ -334,8 +337,13 @@ const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
};

void exec();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus]);
}, [
debouncedSearchTerm,
groupBy,
open,
triggerSearchOnFocus,
onSearchSync,
]);

useEffect(() => {
/** async search */
Expand All @@ -360,8 +368,13 @@ const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
};

void exec();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus]);
}, [
debouncedSearchTerm,
groupBy,
open,
triggerSearchOnFocus,
onSearch,
]);

const CreatableItem = () => {
if (!creatable) return undefined;
Expand Down
12 changes: 10 additions & 2 deletions ui/admin/app/components/ui/scroll-area.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ const ScrollArea = React.forwardRef<
...rootProps
} = props;

const [viewportEl, setViewportEl] = React.useState<HTMLDivElement | null>(
null
);
const viewportRef = React.useRef<HTMLDivElement | null>(null);
const [shouldStickToBottom, setShouldStickToBottom] = React.useState(
enableScrollStick === "bottom"
Expand All @@ -49,6 +52,11 @@ const ScrollArea = React.forwardRef<
}
}, [enableScrollStick, shouldStickToBottom, children]);

const initRef = React.useCallback((node: HTMLDivElement | null) => {
setViewportEl(node);
viewportRef.current = node;
}, []);

return (
<ScrollAreaPrimitive.Root
ref={ref}
Expand All @@ -57,7 +65,7 @@ const ScrollArea = React.forwardRef<
>
<ScrollAreaPrimitive.Viewport
className="h-full w-full rounded-[inherit] max-h-[inherit]"
ref={viewportRef}
ref={initRef}
onScroll={(e) =>
setShouldStickToBottom(isScrolledToBottom(e.currentTarget))
}
Expand All @@ -66,7 +74,7 @@ const ScrollArea = React.forwardRef<
{enableScrollTo === "bottom" && (
<ScrollToBottom
onClick={() => setShouldStickToBottom(true)}
scrollContainerEl={viewportRef.current}
scrollContainerEl={viewportEl}
disabled={shouldStickToBottom}
/>
)}
Expand Down
7 changes: 2 additions & 5 deletions ui/admin/app/components/ui/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import {
} from "~/components/ui/tooltip";
import { useIsMobile } from "~/hooks/use-mobile";

const SIDEBAR_COOKIE_NAME = "sidebar:state";
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
const _SIDEBAR_COOKIE_NAME = "sidebar:state";
const _SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
const SIDEBAR_WIDTH = "13rem";
const SIDEBAR_WIDTH_MOBILE = "18rem";
const SIDEBAR_WIDTH_ICON = "3rem";
Expand Down Expand Up @@ -81,9 +81,6 @@ const SidebarProvider = React.forwardRef<
}

_setOpen(value);

// This sets the cookie to keep the sidebar state.
document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
},
[setOpenProp, open]
);
Expand Down
38 changes: 19 additions & 19 deletions ui/admin/app/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,14 @@ const useAutosizeTextArea = ({
setInit(false);
}

node.style.height = `${
Math.min(Math.max(node.scrollHeight, minHeight), maxHeight) +
offsetBorder
}px`;
const newHeight = Math.min(
Math.max(node.scrollHeight, minHeight + offsetBorder),
maxHeight + offsetBorder
);

node.style.height = `${newHeight}px`;
},
// disable exhaustive deps because we don't want to rerun this after init is set to false
// eslint-disable-next-line react-hooks/exhaustive-deps
[maxHeight, minHeight]
[maxHeight, minHeight, setInit, init]
);

const initResizer = React.useCallback(
Expand All @@ -145,6 +145,7 @@ const useAutosizeTextArea = ({
node.oninput = () => resize(node);
node.onresize = () => resize(node);
node.onchange = () => resize(node);

resize(node);
},
[resize]
Expand All @@ -153,15 +154,14 @@ const useAutosizeTextArea = ({
React.useEffect(() => {
if (textAreaRef) {
initResizer(textAreaRef);
resize(textAreaRef);
}
}, [resize, initResizer, textAreaRef]);
}, [initResizer, textAreaRef]);

return { initResizer };
};

export type AutosizeTextAreaRef = {
textArea: HTMLTextAreaElement;
textArea: HTMLTextAreaElement | null;
maxHeight: number;
minHeight: number;
};
Expand All @@ -185,35 +185,35 @@ const AutosizeTextarea = React.forwardRef<
}: AutosizeTextAreaProps,
ref: React.Ref<AutosizeTextAreaRef>
) => {
const textAreaRef = React.useRef<HTMLTextAreaElement | null>(null);
const [textAreaEl, setTextAreaEl] =
React.useState<HTMLTextAreaElement | null>(null);

useImperativeHandle(ref, () => ({
textArea: textAreaRef.current as HTMLTextAreaElement,
focus: textAreaRef?.current?.focus,
textArea: textAreaEl,
focus: textAreaEl?.focus,
maxHeight,
minHeight,
}));

const { initResizer } = useAutosizeTextArea({
textAreaRef: textAreaRef.current,
textAreaRef: textAreaEl,
maxHeight,
minHeight,
});

const initRef = React.useCallback(
(node: HTMLTextAreaElement | null) => {
textAreaRef.current = node;

if (!node) return;
setTextAreaEl(node);

initResizer(node);
if (node) initResizer(node);
},
[initResizer]
);

return (
<Textarea
{...props}
rows={props.rows || 1}
ref={initRef}
className={cn("resize-none", className)}
onChange={onChange}
Expand All @@ -223,4 +223,4 @@ const AutosizeTextarea = React.forwardRef<
);
AutosizeTextarea.displayName = "AutosizeTextarea";

export { Textarea, AutosizeTextarea, useAutosizeTextArea };
export { AutosizeTextarea, Textarea, useAutosizeTextArea };
8 changes: 0 additions & 8 deletions ui/admin/app/hooks/useLogEffect.ts

This file was deleted.

1 change: 1 addition & 0 deletions ui/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.36.1",
"eslint-plugin-react-compiler": "19.0.0-beta-201e55d-20241215",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

"eslint-plugin-react-hooks": "^4.6.2",
"postcss": "^8.4.38",
"prettier": "^3.3.3",
Expand Down
58 changes: 58 additions & 0 deletions ui/admin/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.