Skip to content

Commit

Permalink
chore: add eslint-plugin-react (#251)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcalexiei authored Dec 23, 2024
1 parent b8b39e6 commit 2434231
Show file tree
Hide file tree
Showing 13 changed files with 690 additions and 302 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ export default function MdxTitle(props: TitleProps): JSX.Element {
)
}

export const h =
(order: 1 | 2 | 3 | 4 | 5 | 6) =>
(props: TitleProps): JSX.Element => <MdxTitle order={order} {...props} />
export const h = (
order: 1 | 2 | 3 | 4 | 5 | 6,
): React.ElementType<TitleProps> => {
function render(props: TitleProps): JSX.Element {
return <MdxTitle order={order} {...props} />
}
render.displayName = 'H'
return render
}
15 changes: 10 additions & 5 deletions apps/documentation/src/components/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,30 @@ function SidebarElements({ close }: SidebarProps): JSX.Element {
<AppShell.Section component={ScrollArea}>
{sidebarElements.map((el, i) => {
if (el.type === 'divider') {
return <Divider my="md" mx={10} />
return <Divider key={`${el.type}-${i}`} my="md" mx={10} />
}

if (el.type === 'title') {
return (
<Text
key={`${el.type}-${i}`}
size="xs"
fw={700}
fz={12}
pl={12}
py={5}
children={el.label}
/>
>
{el.label}
</Text>
)
}

if (el.children?.length) {
return (
<SidebarLink
key={`${el.type}-${i}`}
href={el.href}
label={el.label}
key={i}
leftSection={el.leftIcon}
>
{el.children.map((child, index) => (
Expand All @@ -83,12 +87,13 @@ function SidebarElements({ close }: SidebarProps): JSX.Element {
</SidebarLink>
)
}

return (
<SidebarLink
key={`${el.type}-${i}`}
href={el.href}
label={el.label}
onClick={close}
key={i}
/>
)
})}
Expand Down
30 changes: 18 additions & 12 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import eslint from '@eslint/js'
import tseslint from 'typescript-eslint'
// @ts-expect-error no types are available for this plugin
import eslintPluginImport from 'eslint-plugin-import'
import eslintPluginReact from 'eslint-plugin-react'
// @ts-expect-error no types are available for this plugin
import eslintPluginReactHooks from 'eslint-plugin-react-hooks'

Expand Down Expand Up @@ -38,6 +39,23 @@ export default tseslint.config(
// eslint-disable-next-line import/no-named-as-default-member
tseslint.configs.strictTypeChecked,

// @ts-expect-error flat is optional but always defined on runtime
eslintPluginReact.configs.flat.recommended,
// @ts-expect-error flat is optional but always defined on runtime
eslintPluginReact.configs.flat['jsx-runtime'],

{
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
plugins: {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
'react-hooks': eslintPluginReactHooks,
},
rules: {
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
},
},

{
languageOptions: {
parserOptions: {
Expand Down Expand Up @@ -142,18 +160,6 @@ export default tseslint.config(
},
},

{
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
plugins: {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
'react-hooks': eslintPluginReactHooks,
},
rules: {
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
},
},

{
files: ['apps/documentation/**'],
settings: {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"eslint": "^9.15.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-react": "7.37.2",
"eslint-plugin-react-hooks": "5.1.0",
"prettier": "^3.2.4",
"turbo": "^2.2.3",
Expand Down
44 changes: 28 additions & 16 deletions packages/router/src/components/Link.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,61 @@
import * as React from 'react'
import type { AnchorHTMLAttributes } from 'react'
import type * as React from 'react'
import { useInView } from 'react-intersection-observer'

import { useRouter } from '../hooks/useRouter'
import useRoute from '../hooks/useRoute'

interface TuonoLinkProps {
interface TuonoLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
/**
* If "true" the route gets loaded when the link enters the viewport. Default "true"
* If "true" the route gets loaded when the link enters the viewport.
* @default true
*/
preload?: boolean

/**
* If "false" the scroll offset will be kept across page navigation. Default "true"
* If "false" the scroll offset will be kept across page navigation.
* @default true
*/
scroll?: boolean
}

export default function Link(
componentProps: AnchorHTMLAttributes<HTMLAnchorElement> & TuonoLinkProps,
componentProps: TuonoLinkProps,
): React.JSX.Element {
const { preload = true, scroll = true, ...props } = componentProps
const {
preload = true,
scroll = true,
children,
href,
onClick,
...rest
} = componentProps

const router = useRouter()
const route = useRoute(props.href)
const route = useRoute(href)
const { ref } = useInView({
onChange(inView) {
if (inView && preload) route?.component.preload()
},
triggerOnce: true,
})

const handleTransition: React.MouseEventHandler<HTMLAnchorElement> = (e) => {
e.preventDefault()
props.onClick?.(e)
const handleTransition: React.MouseEventHandler<HTMLAnchorElement> = (
event,
) => {
event.preventDefault()
onClick?.(event)

if (props.href?.startsWith('#')) {
window.location.hash = props.href
if (href?.startsWith('#')) {
window.location.hash = href
return
}

router.push(props.href || '', { scroll })
router.push(href || '', { scroll })
}

return (
<a {...props} ref={ref} onClick={handleTransition}>
{props.children}
<a {...rest} href={href} ref={ref} onClick={handleTransition}>
{children}
</a>
)
}
2 changes: 1 addition & 1 deletion packages/router/src/components/Matches.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from 'react'
import type * as React from 'react'

import { useRouterStore } from '../hooks/useRouterStore'
import useRoute from '../hooks/useRoute'
Expand Down
2 changes: 1 addition & 1 deletion packages/router/src/components/NotFound.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from 'react'
import type * as React from 'react'

import { useInternalRouter } from '../hooks/useInternalRouter'

Expand Down
2 changes: 1 addition & 1 deletion packages/router/src/components/RouteMatch.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from 'react'
import type * as React from 'react'
import { afterEach, describe, expect, test, vi } from 'vitest'

import { cleanup, render, screen } from '@testing-library/react'
Expand Down
1 change: 1 addition & 0 deletions packages/router/src/components/RouteMatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const TraverseRootComponents = React.memo(
return <>{children}</>
},
)
TraverseRootComponents.displayName = 'TraverseRootComponents'

const loadParentComponents = (
route: Route,
Expand Down
2 changes: 1 addition & 1 deletion packages/router/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"jsx": "react"
"jsx": "react-jsx"
},
"include": ["src", "tests", "vite.config.ts"]
}
1 change: 0 additions & 1 deletion packages/tuono/src/ssr/server.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'fast-text-encoding' // Mandatory for React18
import type { ReadableStream } from 'node:stream/web'

import * as React from 'react'
import { renderToStaticMarkup, renderToReadableStream } from 'react-dom/server'
import type { HelmetServerState } from 'react-helmet-async'
import { HelmetProvider } from 'react-helmet-async'
Expand Down
2 changes: 1 addition & 1 deletion packages/tuono/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"jsx": "react"
"jsx": "react-jsx"
},
"include": ["src", "tests", "vite.config.ts"]
}
Loading

0 comments on commit 2434231

Please sign in to comment.