diff --git a/src/app/robots.tsx b/src/app/robots.tsx
deleted file mode 100644
index 414f911..0000000
--- a/src/app/robots.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import type { MetadataRoute } from 'next'
-
-import { CONFIG } from '~/app.config'
-
-export default function robots(): MetadataRoute.Robots {
- return {
- rules: {
- userAgent: '*',
- allow: '/',
- },
- sitemap: `${CONFIG.urlBase}/sitemap.xml`,
- }
-}
diff --git a/src/atoms/index.ts b/src/atoms/index.ts
index 83e30eb..78f6776 100644
--- a/src/atoms/index.ts
+++ b/src/atoms/index.ts
@@ -1,3 +1,3 @@
-export * from './viewport'
export * from './css-media'
export * from './is-interactive'
+export * from './viewport'
diff --git a/src/components/banner/Banner.tsx b/src/components/banner/Banner.tsx
index a814c5b..c58f629 100644
--- a/src/components/banner/Banner.tsx
+++ b/src/components/banner/Banner.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import { clsx } from 'clsx'
import type { FC } from 'react'
diff --git a/src/components/button/MotionButton.tsx b/src/components/button/MotionButton.tsx
index b37a77b..7331f53 100644
--- a/src/components/button/MotionButton.tsx
+++ b/src/components/button/MotionButton.tsx
@@ -1,6 +1,7 @@
'use client'
-import React, { forwardRef } from 'react'
+import * as React from 'react'
+import { forwardRef } from 'react'
import { m } from 'framer-motion'
import type { HTMLMotionProps } from 'framer-motion'
diff --git a/src/components/button/StyledButton.tsx b/src/components/button/StyledButton.tsx
index 2f0887a..39a0fc4 100644
--- a/src/components/button/StyledButton.tsx
+++ b/src/components/button/StyledButton.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
import { Fragment } from 'react'
import clsx from 'clsx'
import Link from 'next/link'
diff --git a/src/components/code-highlighter/CodeBlockWrapper.tsx b/src/components/code-highlighter/CodeBlockWrapper.tsx
index 9d0a5ae..f959d3d 100644
--- a/src/components/code-highlighter/CodeBlockWrapper.tsx
+++ b/src/components/code-highlighter/CodeBlockWrapper.tsx
@@ -61,7 +61,7 @@ export const CodeBlockWrapper: FC
= (props) => {
const $hightlighted = $el.querySelector('.highlighted, .diff')
if ($hightlighted) {
- const lineHeight = parseInt(
+ const lineHeight = Number.parseInt(
getComputedStyle($hightlighted).height || '0',
10,
)
diff --git a/src/components/code-highlighter/CodeHighlighter.tsx b/src/components/code-highlighter/CodeHighlighter.tsx
index 08903d5..812a9e9 100644
--- a/src/components/code-highlighter/CodeHighlighter.tsx
+++ b/src/components/code-highlighter/CodeHighlighter.tsx
@@ -1,4 +1,7 @@
-import { bundledLanguages, getHighlighter } from 'shiki/bundle-full.mjs'
+import {
+ bundledLanguages,
+ getSingletonHighlighter,
+} from 'shiki/bundle-full.mjs'
import type { FC } from 'react'
import {
@@ -46,16 +49,15 @@ const languageToIconMap = {
}
export const HighLighter: FC = async (props) => {
- const highlighter = await getHighlighter({
+ const { lang: language, content: value, attrs } = props
+
+ const highlighter = await getSingletonHighlighter({
themes: [
import('shiki/themes/github-light.mjs'),
import('shiki/themes/github-dark.mjs'),
],
langs: Object.keys(bundledLanguages),
})
-
- const { lang: language, content: value, attrs } = props
-
return (
void
- className?: string
- onReady?: (api: ExcalidrawImperativeAPI) => void
-
- ////
- data?: object
- refUrl?: string
-}
-
-export const Excalidraw = forwardRef<
- {},
- Omit & {
- data: string
- }
->((props, ref) => {
- const { data, ...rest } = props
- const transformedProps: {
- data?: ExcalidrawElement
- refUrl?: string
- } = useMemo(() => {
- if (!data) return {}
- const tryParseJson = safeJsonParse(data)
- if (!tryParseJson) {
- // 1. data 是 string,取第一行判断
- const splittedLines = data.split('\n')
- const firstLine = splittedLines[0]
-
- const props = {} as any
- // 第一行是地址
- if (firstLine.startsWith('/')) {
- props.refUrl = firstLine
- }
-
- return props
- } else {
- return {
- data: tryParseJson as ExcalidrawElement,
- }
- }
- }, [data])
-
- const internalRef = useRef(null)
-
- return
-})
-
-Excalidraw.displayName = 'Excalidraw'
-
-interface InternelExcalidrawRefObject {
- getRemoteData(): ExcalidrawElement | null | undefined
-}
-
-const ExcalidrawImpl = forwardRef(
- ({
- data,
-
- viewModeEnabled = true,
- zenModeEnabled = true,
- onChange,
- className,
-
- onReady,
- showExtendButton,
- refUrl,
- }) => {
- const excalidrawAPIRef = React.useRef()
-
- const isDarkMode = useIsDark()
-
- const [finalData, setFinalData] = React.useState(
- null,
- )
-
- const [loading, setLoading] = useState(false)
-
- useEffect(() => {
- let isMounted = true
- if (refUrl) {
- setLoading(true)
- fetch(refUrl)
- .then((res) => res.text())
- .then((text) => {
- if (!isMounted) return
- const tryParseJson = safeJsonParse(text)
- if (tryParseJson) {
- setFinalData(tryParseJson as ExcalidrawElement)
- }
-
- setLoading(false)
- })
- } else {
- setFinalData(data as ExcalidrawElement)
- setLoading(false)
- }
-
- return () => {
- setLoading(false)
- isMounted = false
- }
- }, [data, refUrl])
- const modal = useModalStack()
- return (
-
- {loading && (
-
- )}
-
{
- excalidrawAPIRef.current = api
-
- setTimeout(() => {
- api.scrollToContent(undefined, {
- fitToContent: true,
- })
- }, 300)
-
- onReady?.(api)
- }}
- />
-
- {viewModeEnabled && showExtendButton && (
- {
- if (!excalidrawAPIRef.current) {
- return
- }
-
- const elements = excalidrawAPIRef.current.getSceneElements()
- if (currentIsMobile()) {
- const win = window.open()
- const blob = exportToBlob({
- elements,
- files: null,
- })
- blob.then((blob) => {
- win?.location.replace(URL.createObjectURL(blob))
- })
- } else {
- modal.present({
- title: 'Preview',
- content: () => (
-
- ),
-
- max: true,
- })
- }
- }}
- className={clsxm(
- 'absolute bottom-2 right-2 z-10 box-content flex size-5 rounded-md border p-2 center',
- 'border-zinc-200 bg-base-100 text-zinc-600',
- 'dark:border-neutral-800 dark:text-zinc-500',
- )}
- >
-
-
- )}
-
- )
- },
-)
-ExcalidrawImpl.displayName = 'ExcalidrawImpl'
diff --git a/src/components/excalidraw/ExcalidrawClient.tsx b/src/components/excalidraw/ExcalidrawClient.tsx
deleted file mode 100644
index 44fb926..0000000
--- a/src/components/excalidraw/ExcalidrawClient.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-'use client'
-
-import { lazy, Suspense, useState } from 'react'
-import { useIsomorphicLayoutEffect } from 'foxact/use-isomorphic-layout-effect'
-import type { ReactNode } from 'react'
-
-import { ExcalidrawLoading } from './ExcalidrawLoading'
-
-export const ExcalidrawLazy = ({ data }: any) => {
- const [Excalidraw, setComponent] = useState(null as ReactNode)
-
- useIsomorphicLayoutEffect(() => {
- const Component = lazy(() =>
- import('~/components/excalidraw').then((mod) => ({
- default: mod.Excalidraw,
- })),
- )
-
- setComponent()
- }, [data])
-
- return (
- }>
- {Excalidraw ?? }
-
- )
-}
diff --git a/src/components/excalidraw/ExcalidrawLoading.tsx b/src/components/excalidraw/ExcalidrawLoading.tsx
deleted file mode 100644
index 3264f6e..0000000
--- a/src/components/excalidraw/ExcalidrawLoading.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import React from 'react'
-
-import { BlockLoading } from '../shared/BlockLoading'
-
-export const ExcalidrawLoading = () => {
- return Excalidraw Loading...
-}
diff --git a/src/components/excalidraw/index.ts b/src/components/excalidraw/index.ts
deleted file mode 100644
index 317f0a8..0000000
--- a/src/components/excalidraw/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './Excalidraw'
diff --git a/src/components/fab/FABContainer.tsx b/src/components/fab/FABContainer.tsx
index 11e75ec..fab0523 100644
--- a/src/components/fab/FABContainer.tsx
+++ b/src/components/fab/FABContainer.tsx
@@ -1,7 +1,7 @@
-/* eslint-disable tailwindcss/no-contradicting-classname */
'use client'
-import React, { useEffect, useId, useRef } from 'react'
+import * as React from 'react'
+import { useEffect, useId, useRef } from 'react'
import clsx from 'clsx'
import { typescriptHappyForwardRef } from 'foxact/typescript-happy-forward-ref'
import { AnimatePresence, m } from 'framer-motion'
diff --git a/src/components/float-popover/FloatPopover.tsx b/src/components/float-popover/FloatPopover.tsx
index 14380d0..fba8a43 100644
--- a/src/components/float-popover/FloatPopover.tsx
+++ b/src/components/float-popover/FloatPopover.tsx
@@ -7,7 +7,8 @@ import {
shift,
useFloating,
} from '@floating-ui/react-dom'
-import React, {
+import * as React from 'react'
+import {
createContext,
createElement,
useCallback,
@@ -146,24 +147,27 @@ export const FloatPopover = function FloatPopover(
// onBlur: doPopoverDisappear,
}
switch (trigger) {
- case 'click':
+ case 'click': {
return {
...baseListener,
onClick: doPopoverShow,
}
- case 'hover':
+ }
+ case 'hover': {
return {
...baseListener,
onMouseOver: doPopoverShow,
onMouseOut: doPopoverDisappear,
}
- case 'both':
+ }
+ case 'both': {
return {
...baseListener,
onClick: doPopoverShow,
onMouseOver: doPopoverShow,
onMouseOut: handleMouseOut,
}
+ }
}
}, [doPopoverDisappear, doPopoverShow, handleMouseOut, trigger])
diff --git a/src/components/icons/arrow.tsx b/src/components/icons/arrow.tsx
index 71e31c9..c6082ea 100644
--- a/src/components/icons/arrow.tsx
+++ b/src/components/icons/arrow.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import type { SVGProps } from 'react'
export function IcRoundKeyboardDoubleArrowRight(
diff --git a/src/components/icons/calendar.tsx b/src/components/icons/calendar.tsx
index 1ae9985..4f4066c 100644
--- a/src/components/icons/calendar.tsx
+++ b/src/components/icons/calendar.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import type { SVGProps } from 'react'
export function MdiCalendar(props: SVGProps) {
diff --git a/src/components/icons/comment.tsx b/src/components/icons/comment.tsx
index 4a8fb50..c115f64 100644
--- a/src/components/icons/comment.tsx
+++ b/src/components/icons/comment.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import type { SVGProps } from 'react'
export function SiGlyphGlobal(props: SVGProps) {
diff --git a/src/components/icons/emoji.tsx b/src/components/icons/emoji.tsx
index 584abfe..dba7797 100644
--- a/src/components/icons/emoji.tsx
+++ b/src/components/icons/emoji.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
export function EmojiSmile() {
return (
diff --git a/src/components/icons/menu-collection.tsx b/src/components/icons/menu-collection.tsx
index b1ef623..50e45f3 100644
--- a/src/components/icons/menu-collection.tsx
+++ b/src/components/icons/menu-collection.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import type { SVGProps } from 'react'
export function FaSolidCircleNotch(props: SVGProps) {
diff --git a/src/components/icons/platform/MailIcon.tsx b/src/components/icons/platform/MailIcon.tsx
index f9179ad..edb5c31 100644
--- a/src/components/icons/platform/MailIcon.tsx
+++ b/src/components/icons/platform/MailIcon.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
export function MailIcon(props: React.SVGAttributes) {
return (
diff --git a/src/components/icons/status.tsx b/src/components/icons/status.tsx
index 22f8a51..cd0a111 100644
--- a/src/components/icons/status.tsx
+++ b/src/components/icons/status.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import type { SVGProps } from 'react'
export function FluentWarning28Regular(props: SVGProps) {
diff --git a/src/components/icons/weather.tsx b/src/components/icons/weather.tsx
index 4fbd578..ea38d81 100644
--- a/src/components/icons/weather.tsx
+++ b/src/components/icons/weather.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import type { SVGProps } from 'react'
export function RiSunCloudyFill(props: SVGProps) {
diff --git a/src/components/link-card/LinkCard.tsx b/src/components/link-card/LinkCard.tsx
index 95a3e92..06cda9f 100644
--- a/src/components/link-card/LinkCard.tsx
+++ b/src/components/link-card/LinkCard.tsx
@@ -1,6 +1,7 @@
'use client'
-import React, { useCallback, useMemo, useState } from 'react'
+import * as React from 'react'
+import { useCallback, useMemo, useState } from 'react'
import { useInView } from 'react-intersection-observer'
import camelcaseKeys from 'camelcase-keys'
import clsx from 'clsx'
@@ -88,7 +89,7 @@ const LinkCardImpl: FC = (props) => {
setLoading(true)
await fetchFn(id, setCardInfo, setFullUrl).catch((err) => {
- console.log('fetch card info error: ', err)
+ console.log('fetch card info error:', err)
setIsError(true)
})
setLoading(false)
@@ -113,7 +114,7 @@ const LinkCardImpl: FC = (props) => {
const bounds = currentTarget.getBoundingClientRect()
mouseX.set(clientX - bounds.left)
mouseY.set(clientY - bounds.top)
- radius.set(Math.sqrt(bounds.width ** 2 + bounds.height ** 2) * 1.3)
+ radius.set(Math.hypot(bounds.width, bounds.height) * 1.3)
},
[mouseX, mouseY, radius],
)
diff --git a/src/components/link-card/index.ts b/src/components/link-card/index.ts
index be56435..3695302 100644
--- a/src/components/link-card/index.ts
+++ b/src/components/link-card/index.ts
@@ -1,3 +1,2 @@
-export * from './LinkCard'
-
export * from './enums'
+export * from './LinkCard'
diff --git a/src/components/loading/index.tsx b/src/components/loading/index.tsx
index 4ce6f16..c5e178e 100644
--- a/src/components/loading/index.tsx
+++ b/src/components/loading/index.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import { clsxm } from '~/lib/helper'
diff --git a/src/components/markdown/Markdown.tsx b/src/components/markdown/Markdown.tsx
index ddcb362..2788bd2 100644
--- a/src/components/markdown/Markdown.tsx
+++ b/src/components/markdown/Markdown.tsx
@@ -1,5 +1,5 @@
-/* eslint-disable react-hooks/rules-of-hooks */
-import React, { Fragment } from 'react'
+import * as React from 'react'
+import { Fragment } from 'react'
import { clsx } from 'clsx'
import MarkdownJSX, { sanitizeUrl } from 'markdown-to-jsx'
import Script from 'next/script'
@@ -43,7 +43,7 @@ export interface MdProps {
value?: string
style?: React.CSSProperties
- readonly renderers?: { [key: string]: Partial }
+ readonly renderers?: Record>
wrapperProps?: React.DetailedHTMLProps<
React.HTMLAttributes,
HTMLDivElement
@@ -151,12 +151,12 @@ const options: MarkdownToJSX.Options = {
const thisUrl = new URL(footnote?.footnote?.replace(': ', ''))
const isCurrentHost = thisUrl.hostname === window.location.hostname
if (!isCurrentHost && !isDev) {
- return undefined
+ return
}
- const pathname = thisUrl.pathname
+ const { pathname } = thisUrl
return pathname.slice(1)
} catch {
- return undefined
+ return
}
})()
@@ -185,7 +185,7 @@ const options: MarkdownToJSX.Options = {
)}
type="tooltip"
>
- {footnote?.footnote?.substring(1)}
+ {footnote?.footnote?.slice(1)}
{linkCardId && (
diff --git a/src/components/markdown/index.ts b/src/components/markdown/index.ts
index 0cc9bef..68b4bd6 100644
--- a/src/components/markdown/index.ts
+++ b/src/components/markdown/index.ts
@@ -1,3 +1,2 @@
export * from './Markdown'
-
export * from 'markdown-to-jsx'
diff --git a/src/components/markdown/parsers/alert.tsx b/src/components/markdown/parsers/alert.tsx
index 8f43d77..ad93077 100644
--- a/src/components/markdown/parsers/alert.tsx
+++ b/src/components/markdown/parsers/alert.tsx
@@ -34,7 +34,7 @@ const typedIconMap = {
* > Highlights information that users should take into account, even when skimming.
*/
const ALERT_BLOCKQUOTE_R =
- /^(> \[!(?NOTE|IMPORTANT|WARNING)\].*?)(?(?:\n *>.*?)*)(?=\n{2,}|$)/
+ /^(> \[!(?NOTE|IMPORTANT|WARNING)\].*)(?(?:\n *>.*)*)(?=\n{2,}|$)/
export const AlertsRule: MarkdownToJSX.Rule = {
match: blockRegex(ALERT_BLOCKQUOTE_R),
@@ -49,7 +49,7 @@ export const AlertsRule: MarkdownToJSX.Rule = {
},
react(node, output, state) {
const { type, body } = node.parsed
- const bodyClean = body.replace(/^> */gm, '')
+ const bodyClean = body.replaceAll(/^> */gm, '')
const typePrefix = type[0] + type.toLowerCase().slice(1)
diff --git a/src/components/markdown/parsers/container.tsx b/src/components/markdown/parsers/container.tsx
index 961c12f..45cb516 100644
--- a/src/components/markdown/parsers/container.tsx
+++ b/src/components/markdown/parsers/container.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import { Priority } from 'markdown-to-jsx'
import type { MarkdownToJSX } from 'markdown-to-jsx'
@@ -23,13 +23,13 @@ const shouldCatchContainerName = [
export const ContainerRule: MarkdownToJSX.Rule = {
match: (source: string) => {
const result =
- /^\s*::: *(?.*?) *(?:{(?.*?)})? *\n(?[\s\S]+?)\s*::: *(?:\n *)+\n?/.exec(
+ /^\s*::: *(?.*?) *(?:\{(?.*?)\} *)?\n(?[\s\S]+?)\s*::: *(?:\n *)+/.exec(
source,
)
if (!result) return null
- const type = result.groups!.type
+ const { type } = result.groups!
if (!type || !type.match(shouldCatchContainerName)) return null
return result
},
diff --git a/src/components/markdown/parsers/ins.tsx b/src/components/markdown/parsers/ins.tsx
index 2d2c060..cef5a8a 100644
--- a/src/components/markdown/parsers/ins.tsx
+++ b/src/components/markdown/parsers/ins.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import {
parseCaptureInline,
Priority,
diff --git a/src/components/markdown/parsers/katex.tsx b/src/components/markdown/parsers/katex.tsx
index 5864383..0689552 100644
--- a/src/components/markdown/parsers/katex.tsx
+++ b/src/components/markdown/parsers/katex.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import katex from 'katex'
import { blockRegex, Priority, simpleInlineRegex } from 'markdown-to-jsx'
import type { MarkdownToJSX } from 'markdown-to-jsx'
@@ -7,7 +7,7 @@ import type { FC } from 'react'
// $ c = \pm\sqrt{a^2 + b^2} $
export const KateXRule: MarkdownToJSX.Rule = {
match: simpleInlineRegex(
- /^\$\s{0,}((?:\[.*?\]|<.*?>(?:.*?<.*?>)?|`.*?`|.)*?)\s{0,}\$/,
+ /^\$\s*((?:\[.*?\]|<.*?>(?:.*?<.*?>)?|`.*?`|.)*?)\s*\$/,
),
order: Priority.MED,
parse(capture) {
diff --git a/src/components/markdown/parsers/mark.tsx b/src/components/markdown/parsers/mark.tsx
index 991827d..5423ceb 100644
--- a/src/components/markdown/parsers/mark.tsx
+++ b/src/components/markdown/parsers/mark.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import {
parseCaptureInline,
Priority,
diff --git a/src/components/markdown/parsers/mention.tsx b/src/components/markdown/parsers/mention.tsx
index c3c0b35..9d50024 100644
--- a/src/components/markdown/parsers/mention.tsx
+++ b/src/components/markdown/parsers/mention.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import { Priority, simpleInlineRegex } from 'markdown-to-jsx'
import type { MarkdownToJSX } from 'markdown-to-jsx'
diff --git a/src/components/markdown/parsers/spoiler.tsx b/src/components/markdown/parsers/spoiler.tsx
index a449341..1d29706 100644
--- a/src/components/markdown/parsers/spoiler.tsx
+++ b/src/components/markdown/parsers/spoiler.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import {
parseCaptureInline,
Priority,
diff --git a/src/components/markdown/renderers/LinkRenderer.tsx b/src/components/markdown/renderers/LinkRenderer.tsx
index ef0dc1a..52449dc 100644
--- a/src/components/markdown/renderers/LinkRenderer.tsx
+++ b/src/components/markdown/renderers/LinkRenderer.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import type { FC, PropsWithChildren, ReactNode } from 'react'
import { GitHubBrandIcon } from '~/components/icons/platform/GitHubBrandIcon'
diff --git a/src/components/markdown/renderers/collapse.tsx b/src/components/markdown/renderers/collapse.tsx
index 8bf8e77..3203f16 100644
--- a/src/components/markdown/renderers/collapse.tsx
+++ b/src/components/markdown/renderers/collapse.tsx
@@ -1,6 +1,7 @@
'use client'
-import React, { useCallback, useLayoutEffect, useState } from 'react'
+import * as React from 'react'
+import { useCallback, useLayoutEffect, useState } from 'react'
import clsx from 'clsx'
import type { FC, ReactNode } from 'react'
diff --git a/src/components/markdown/renderers/footnotes.tsx b/src/components/markdown/renderers/footnotes.tsx
index 930bdd9..200c0ae 100644
--- a/src/components/markdown/renderers/footnotes.tsx
+++ b/src/components/markdown/renderers/footnotes.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import * as React from 'react'
import type { FC, PropsWithChildren } from 'react'
import { KeyboardReturnRounded } from '~/components/icons/return'
@@ -14,7 +14,7 @@ export const MFootNote: FC = (props) => {
{React.Children.map(props.children, (child) => {
if (React.isValidElement(child)) {
- const id = child.props.id
+ const { id } = child.props
return (