このコミットが含まれているのは:
2026-07-05 01:51:07 +09:00
コミット d0ea329887
14個のファイルの変更1208行の追加645行の削除
+18 -12
ファイルの表示
@@ -1,9 +1,8 @@
import PrefetchLink from '@/components/PrefetchLink'
import ResponsiveMarqueeText from '@/components/ResponsiveMarqueeText'
import { LIGHT_COLOUR_SHADE, DARK_COLOUR_SHADE, TAG_COLOUR } from '@/consts'
import { cn } from '@/lib/utils'
import type { ComponentProps, FC, HTMLAttributes } from 'react'
import type { ComponentProps, CSSProperties, FC, HTMLAttributes } from 'react'
import type { Tag } from '@/types'
@@ -36,15 +35,16 @@ const TagLink: FC<Props> = ({ tag,
withWiki = true,
withCount = true,
className,
style,
title,
...props }) => {
const spanClass = cn (
`text-${ TAG_COLOUR[tag.category] }-${ LIGHT_COLOUR_SHADE }`,
`dark:text-${ TAG_COLOUR[tag.category] }-${ DARK_COLOUR_SHADE }`)
const linkClass = cn (
spanClass,
`hover:text-${ TAG_COLOUR[tag.category] }-${ LIGHT_COLOUR_SHADE - 200 }`,
`dark:hover:text-${ TAG_COLOUR[tag.category] }-${ DARK_COLOUR_SHADE - 200 }`)
const colourStyle = {
'--tag-link-colour': `var(--tag-colour-${ tag.category })`,
'--tag-link-hover-colour': `var(--tag-colour-${ tag.category }-hover)`,
...style,
} as CSSProperties
const spanClass = 'tag-link-colour'
const linkClass = 'tag-link-colour tag-link-hover-colour'
const textClass = 'group min-w-0 max-w-full overflow-hidden align-bottom'
const rootClass =
'inline-flex min-w-0 max-w-full flex-nowrap items-stretch align-baseline gap-x-1 md:items-baseline'
@@ -63,7 +63,8 @@ const TagLink: FC<Props> = ({ tag,
? (
<PrefetchLink
to={`/wiki/${ encodeURIComponent (tag.name) }`}
className={linkClass}>
className={linkClass}
style={colourStyle}>
?
</PrefetchLink>)
: (
@@ -71,13 +72,15 @@ const TagLink: FC<Props> = ({ tag,
? (
<PrefetchLink
to={`/materials/${ tag.materialId }`}
className={linkClass}>
className={linkClass}
style={colourStyle}>
?
</PrefetchLink>)
: (
<PrefetchLink
to={`/tags/${ tag.id }/deerjikists`}
className={linkClass}>
className={linkClass}
style={colourStyle}>
?
</PrefetchLink>)))
: (
@@ -120,6 +123,7 @@ const TagLink: FC<Props> = ({ tag,
<span
title={textTitle}
className={cn (spanClass, textClass, className)}
style={colourStyle}
{...props}>
<ResponsiveMarqueeText
text={tag.matchedAlias}
@@ -134,6 +138,7 @@ const TagLink: FC<Props> = ({ tag,
to={`/posts?${ (new URLSearchParams ({ tags: tag.name })).toString () }`}
title={textTitle}
className={cn (linkClass, textClass, className)}
style={colourStyle}
{...props}>
<ResponsiveMarqueeText
text={tag.name}
@@ -144,6 +149,7 @@ const TagLink: FC<Props> = ({ tag,
<span
title={textTitle}
className={cn (spanClass, textClass, className)}
style={colourStyle}
{...props}>
<ResponsiveMarqueeText
text={tag.name}
+22 -13
ファイルの表示
@@ -7,12 +7,15 @@ type TabProps = { name: string
init?: boolean
children: React.ReactNode }
type Props = { children: React.ReactNode }
type Props = {
children: React.ReactNode
rightAddon?: React.ReactNode
}
export const Tab = ({ children }: TabProps) => <>{children}</>
const TabGroup: FC<Props> = ({ children }) => {
const TabGroup: FC<Props> = ({ children, rightAddon }) => {
const tabs = React.Children.toArray (children) as React.ReactElement<TabProps>[]
const [current, setCurrent] = useState<number> (() => {
@@ -22,17 +25,23 @@ const TabGroup: FC<Props> = ({ children }) => {
return (
<div className="mt-4">
<div className="flex gap-4">
{tabs.map ((tab, i) => (
<a key={i}
href="#"
className={cn (i === current && 'font-bold')}
onClick={ev => {
ev.preventDefault ()
setCurrent (i)
}}>
{tab.props.name}
</a>))}
<div className="flex items-center justify-between gap-4">
<div className="flex min-w-0 gap-4">
{tabs.map ((tab, i) => (
<a key={i}
href="#"
className={cn (i === current && 'font-bold')}
onClick={ev => {
ev.preventDefault ()
setCurrent (i)
}}>
{tab.props.name}
</a>))}
</div>
{rightAddon && (
<div className="shrink-0">
{rightAddon}
</div>)}
</div>
<div className="mt-2">
{tabs[current]}
+9 -25
ファイルの表示
@@ -1,6 +1,10 @@
import { createContext, useContext, useEffect, useMemo, useState } from 'react'
import { DEFAULT_USER_SETTINGS, fetchUserSettings } from '@/lib/settings'
import {
applyClientAppearance,
DEFAULT_USER_SETTINGS,
fetchUserSettings,
} from '@/lib/settings'
import type { Dispatch, FC, ReactNode, SetStateAction } from 'react'
@@ -16,29 +20,6 @@ type ContextValue = {
const UserSettingsContext = createContext<ContextValue | null> (null)
const applyTheme = (theme: UserSettings['theme']) => {
const root = document.documentElement
const media = window.matchMedia ('(prefers-color-scheme: dark)')
const sync = () => {
const dark = theme === 'dark' || (theme === 'system' && media.matches)
root.classList.toggle ('dark', dark)
root.style.colorScheme = dark ? 'dark' : 'light'
}
sync ()
if (theme !== 'system')
return () => { }
const onChange = () => sync ()
media.addEventListener ('change', onChange)
return () => {
media.removeEventListener ('change', onChange)
}
}
export const UserSettingsProvider: FC<{
children: ReactNode
user: User | null }> = ({ children, user }) => {
@@ -87,7 +68,10 @@ export const UserSettingsProvider: FC<{
}
}, [user])
useEffect (() => applyTheme (settings.theme), [settings.theme])
useEffect (() => {
void settings.theme
applyClientAppearance ()
}, [settings.theme])
const value = useMemo<ContextValue> (() => ({
error,