diff --git a/app/components/Drawer/Drawer.tsx b/app/components/Drawer/Drawer.tsx index 98fafe1..b9b69dc 100644 --- a/app/components/Drawer/Drawer.tsx +++ b/app/components/Drawer/Drawer.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from 'react'; import { LanguageButton } from '../LanguageButton/LanguageButton'; import styles from './drawer.module.css'; import { useTranslation } from 'react-i18next'; +import { useLocation } from 'react-router'; export interface DrawerProps { links: Record<'label' | 'to', string>[]; @@ -26,6 +27,9 @@ export const Drawer = ({ }: DrawerProps) => { const [open, setOpen] = useState(false); const { t } = useTranslation(); + + const location = useLocation(); + const isHome = location.pathname === '/'; useEffect(() => { document.documentElement.style.overflow = open ? 'hidden' : ''; @@ -33,13 +37,19 @@ export const Drawer = ({ return (
-
setOpen(true)} className={[open ? styles.hidden : '', styles.trigger].join(" ")}> +
setOpen(true)} + className={[open ? styles.hidden : '', styles.trigger, isHome ? styles.isHome : styles.isOther].join(" ")} + > {children}
setOpen(false)}/> - + { + isHome && + }

{t("header.links")}

diff --git a/app/components/Drawer/drawer.module.css b/app/components/Drawer/drawer.module.css index 2fd2918..57d4e41 100644 --- a/app/components/Drawer/drawer.module.css +++ b/app/components/Drawer/drawer.module.css @@ -21,6 +21,14 @@ opacity: 0; } +.isHome { + color: var(--accent-color); +} + +.isOther { + color: var(--grey-text-color); +} + .button-container { width: auto; height: max-content; diff --git a/app/components/Header/Header.stories.ts b/app/components/Header/Header.stories.ts index 595f042..65eca80 100644 --- a/app/components/Header/Header.stories.ts +++ b/app/components/Header/Header.stories.ts @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Header } from './Header'; const meta = { - title: 'Example/Header', + title: 'Common/Header', component: Header, // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs tags: ['autodocs'], diff --git a/app/components/Header/Header.tsx b/app/components/Header/Header.tsx index f4c500b..3ce9982 100644 --- a/app/components/Header/Header.tsx +++ b/app/components/Header/Header.tsx @@ -2,7 +2,7 @@ import { faBars } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { useNavigate } from 'react-router'; +import { useLocation, useNavigate } from 'react-router'; import { useIsMobile } from '~/hooks/useIsMobile'; import { Drawer } from '../Drawer/Drawer'; import { HeaderLink } from '../HeaderLink/HeaderLink'; @@ -42,6 +42,9 @@ export const Header = () => { const ignoreScroll = useRef(false); const ignoreTimer = useRef | null>(null); + const location = useLocation(); + const isHome = location.pathname === '/'; + const navigate = useNavigate(); const handleScroll = useCallback(() => { @@ -129,7 +132,9 @@ export const Header = () => { to={header.to}/> )) } - + { + isHome && + } ) } diff --git a/app/components/Header/header.module.css b/app/components/Header/header.module.css index b1d0e9d..128ca31 100644 --- a/app/components/Header/header.module.css +++ b/app/components/Header/header.module.css @@ -36,5 +36,4 @@ header { .bars { font-size: 42px; transition: opacity 0.5s ease, transform 0.5s ease; - color: var(--accent-color); } \ No newline at end of file diff --git a/app/components/LinkedButton/LinkedButton.tsx b/app/components/LinkedButton/LinkedButton.tsx index a0378b7..1e92490 100644 --- a/app/components/LinkedButton/LinkedButton.tsx +++ b/app/components/LinkedButton/LinkedButton.tsx @@ -2,6 +2,7 @@ import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useTranslation } from "react-i18next"; import './LinkedButton.css'; +import type { ReactNode } from "react"; export interface LinkedButtonProps { url: string; @@ -9,6 +10,9 @@ export interface LinkedButtonProps { backgroundColor?: string; color?: string; style?: "default" | "outlined"; + children?: ReactNode; + buttonLocation?: "left" | "right"; + isNewTab?: boolean; } export type TemplateLabel = 'detail' | 'list'; @@ -24,11 +28,16 @@ export const LinkedButton = ({ backgroundColor = "var(--primery-color)", color = "var(--accent-color)", style = "default", + children, + buttonLocation, + isNewTab = true, ...props }: LinkedButtonProps) => { const { t } = useTranslation(); const displayLabel = label in templateLabel ? t(templateLabel[label as TemplateLabel]) : label + const targetProps = isNewTab ? { target: "_blank", rel: "noopener noreferrer" } : {}; + const linkStyle = { backgroundColor: style === "default" ? backgroundColor : "transparent", color: backgroundColor, @@ -46,9 +55,14 @@ export const LinkedButton = ({ }; return ( - + + { + (buttonLocation === "left" && children) ?? + } {displayLabel} - + { + ((buttonLocation ?? "right") === "right" && children) ?? + } ); } \ No newline at end of file diff --git a/app/routes/blog/$id.module.scss b/app/routes/blog/$id.module.scss index 29bf2f8..9e9d1a6 100644 --- a/app/routes/blog/$id.module.scss +++ b/app/routes/blog/$id.module.scss @@ -7,34 +7,147 @@ justify-content: center; background-color: #F5F5F5; - .article { - padding-top: 64px; - width: 100%; - max-width: 1200px; - } - .side { padding-top: 200px; width: 20%; + + &.mobile { + border-radius: 4px; + margin-top: 64px; + padding-top: 20px; + width: 100%; + + .h1-table { + color: #616161; + } + .h2-table { + color: #8a8a8a; + + & > li { + padding-left: 24px; + border-left: solid 1px #8a8a8a; + } + + &::before { + content: ""; + display: block; + position: absolute; + height: 50%; + width: 12px; + border-bottom: solid 1px #8a8a8a; + } + + &:not(:has(+ .h2-table)) { + + &::before { + border-left: solid 1px #8a8a8a; + } + + & li { + border-left: none; + } + } + } + } + + ul { + top: 200px; + list-style: none; + position: sticky; + + a { + position: relative; + + li { + margin: 0; + padding-top: 4px; + padding-bottom: 4px; + font-size: 16px; + } + } + } } - - ul { - top: 200px; - list-style: none; - position: sticky; - } - - li { - font-size: 16px; - } - + .h1-table { color: #616161; } .h2-table { color: #8a8a8a; - li { + + & > li { padding-left: 24px; + border-left: solid 1px #8a8a8a; + } + + &::before { + content: ""; + display: block; + position: absolute; + height: 50%; + width: 12px; + border-bottom: solid 1px #8a8a8a; + } + + &:not(:has(+ .h2-table)) { + + &::before { + border-left: solid 1px #8a8a8a; + } + + & li { + border-left: none; + } + } + } + + .article { + padding-top: 64px; + width: 100%; + max-width: 1200px; + + h1 { + color: var(--main-text-color); + font-weight: 900; + font-size: 52px; + } + + h2 { + color: var(--main-text-color); + font-weight: 700; + font-size: 32px; + } + + h3 { + color: var(--main-text-color); + font-weight: 600; + font-size: 24px; + } + + h1, h2, h3, h4, h5, h6 { + padding-left: 8px; + padding-bottom: 4px; + margin-bottom: 24px; + margin-top: 24px; + position: relative; + color: var(--main-text-color); + text-box-edge: cap alphabetic; + } + + h1::before, h2::before { + content: ""; + position: absolute; + display: block; + left: -24px; + width: 12px; + height: 100%; + background-color: var(--primery-color); + } + + p { + color: var(--main-text-color); + letter-spacing: 2px; + font-size: 20px; + margin: 20px 0; } } @@ -47,6 +160,13 @@ justify-content: center; align-items: center; flex-direction: column; + + .backButton { + width: 100%; + display: flex; + justify-content: start; + margin-bottom: 24px; + } } .header-img { @@ -56,51 +176,6 @@ border-radius: 12px; box-shadow: 0 10px 10px #20202011; } - - h1 { - color: var(--main-text-color); - font-weight: 900; - font-size: 52px; - } - - h2 { - color: var(--main-text-color); - font-weight: 700; - font-size: 32px; - } - - h3 { - color: var(--main-text-color); - font-weight: 600; - font-size: 24px; - } - - h1, h2, h3, h4, h5, h6 { - padding-left: 8px; - padding-bottom: 4px; - margin-bottom: 24px; - margin-top: 24px; - position: relative; - color: var(--main-text-color); - text-box-edge: cap alphabetic; - } - - h1::before, h2::before { - content: ""; - position: absolute; - display: block; - left: -24px; - width: 12px; - height: 100%; - background-color: var(--primery-color); - } - - p { - color: var(--main-text-color); - letter-spacing: 2px; - font-size: 20px; - margin: 20px 0; - } } @media screen and (max-width: 700px) { diff --git a/app/routes/blog/$id.tsx b/app/routes/blog/$id.tsx index 4595bf4..2a205de 100644 --- a/app/routes/blog/$id.tsx +++ b/app/routes/blog/$id.tsx @@ -7,6 +7,9 @@ import styles from "./$id.module.scss" import { useParams } from "react-router"; import { useIsMobile } from "~/hooks/useIsMobile"; import { custom_markdown_convert } from "~/utils/convert"; +import { LinkedButton } from "~/components/LinkedButton/LinkedButton"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faArrowAltCircleLeft } from "@fortawesome/free-solid-svg-icons"; export default function Blog(): JSX.Element { const { id } = useParams(); @@ -89,7 +92,23 @@ export default function Blog(): JSX.Element {
}
+
+ + + +
+ { + isMobile && +
+ 目次 +
    + { + table + } +
+
+ }