-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #346 from nekochans/feature/issue324/add-header
新デザイン(2024年)のHeaderComponentを作成
- Loading branch information
Showing
20 changed files
with
523 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import { Header } from './Header'; | ||
|
||
const meta = { | ||
component: Header, | ||
} satisfies Meta<typeof Header>; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const HeaderInJapanese: Story = { | ||
args: { | ||
language: 'ja', | ||
currentUrlPath: '/', | ||
}, | ||
}; | ||
|
||
export const HeaderInEnglish: Story = { | ||
args: { | ||
language: 'en', | ||
currentUrlPath: '/en', | ||
}, | ||
}; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import { HeaderLogo } from '@/app/_components/HeaderLogo'; | ||
import { DownIcon } from '@/app/_components/icons/DownIcon'; | ||
import { GlobeIcon } from '@/app/_components/icons/GlobeIcon'; | ||
import { RightIcon } from '@/app/_components/icons/RightIcon'; | ||
import { LoginButton } from '@/app/_components/LoginButton'; | ||
import { createExternalTransmissionPolicyLinksFromLanguages } from '@/features/externalTransmissionPolicy'; | ||
import { removeLanguageFromAppPath, type Language } from '@/features/language'; | ||
import { createPrivacyPolicyLinksFromLanguages } from '@/features/privacyPolicy'; | ||
import { createTermsOfUseLinksFromLanguages } from '@/features/termsOfUse'; | ||
import { appPathList, type IncludeLanguageAppPath } from '@/features/url'; | ||
import Link from 'next/link'; | ||
import type { JSX } from 'react'; | ||
import { | ||
Button, | ||
Menu, | ||
MenuItem, | ||
MenuTrigger, | ||
Popover, | ||
Header as ReactAriaHeader, | ||
Text, | ||
} from 'react-aria-components'; | ||
import { howToUseText, policyText, uploadText } from './HeaderI18n'; | ||
|
||
type Props = { | ||
language: Language; | ||
currentUrlPath: IncludeLanguageAppPath; | ||
}; | ||
|
||
export const Header = ({ language, currentUrlPath }: Props): JSX.Element => { | ||
const terms = createTermsOfUseLinksFromLanguages(language); | ||
const privacy = createPrivacyPolicyLinksFromLanguages(language); | ||
const externalTransmissionPolicy = | ||
createExternalTransmissionPolicyLinksFromLanguages(language); | ||
const removedLanguagePath = removeLanguageFromAppPath(currentUrlPath); | ||
|
||
return ( | ||
<ReactAriaHeader className="w-full border-b border-orange-300 bg-orange-500"> | ||
<div className="mx-auto flex h-16 max-w-screen-2xl items-center justify-between px-5"> | ||
<div className="flex w-full items-center justify-between pl-7"> | ||
<div className="flex items-center gap-24"> | ||
<HeaderLogo language={language} /> | ||
<nav className="flex items-center gap-6"> | ||
<Link | ||
href={appPathList.upload} | ||
className="flex items-center justify-center bg-orange-500 p-5 text-base font-medium text-orange-50 hover:text-orange-100" | ||
> | ||
<Text slot="label" className="text-base font-bold"> | ||
{uploadText(language)} | ||
</Text> | ||
</Link> | ||
<Link | ||
href="/how-to-use" | ||
className="flex items-center justify-center bg-orange-500 p-5 text-base font-medium text-orange-50 hover:text-orange-100" | ||
> | ||
<Text slot="label" className="text-base font-bold"> | ||
{howToUseText(language)} | ||
</Text> | ||
</Link> | ||
<Link | ||
href={terms.link} | ||
className="flex items-center justify-center bg-orange-500 p-5 text-base font-medium text-orange-50 hover:text-orange-100" | ||
> | ||
<Text slot="label" className="text-base font-bold"> | ||
{terms.text} | ||
</Text> | ||
</Link> | ||
<MenuTrigger> | ||
<Button className="flex items-center justify-center gap-2 bg-orange-500 px-5 py-2 text-base font-medium text-orange-50 hover:text-orange-100"> | ||
<Text className="text-base font-bold"> | ||
{policyText(language)} | ||
</Text> | ||
<DownIcon /> | ||
</Button> | ||
<Popover className="bg-orange-500 shadow-lg ring-1 ring-black/5"> | ||
<Menu className="min-w-[200px] max-w-[400px] whitespace-nowrap"> | ||
<MenuItem className="flex w-full items-center px-6 py-2 text-left text-base font-medium text-orange-50 hover:bg-orange-600"> | ||
<Link href={privacy.link} className="w-full"> | ||
<Text slot="label" className="text-base font-bold"> | ||
{privacy.text} | ||
</Text> | ||
</Link> | ||
</MenuItem> | ||
<MenuItem className="flex w-full items-center px-6 py-2 text-left text-base font-medium text-orange-50 hover:bg-orange-600"> | ||
<Link | ||
href={externalTransmissionPolicy.link} | ||
className="w-full" | ||
> | ||
<Text slot="label" className="text-base font-bold"> | ||
{externalTransmissionPolicy.text} | ||
</Text> | ||
</Link> | ||
</MenuItem> | ||
</Menu> | ||
</Popover> | ||
</MenuTrigger> | ||
</nav> | ||
</div> | ||
<div className="flex items-center gap-4 px-7"> | ||
<MenuTrigger> | ||
<Button className="flex items-center justify-center gap-2 bg-orange-500 px-5 py-2 text-base font-medium text-orange-50 hover:text-orange-100"> | ||
<span className="flex size-5 items-center justify-center"> | ||
<GlobeIcon /> | ||
</span> | ||
<Text className="text-base font-bold">language</Text> | ||
<span className="flex size-4 items-center justify-center"> | ||
<DownIcon /> | ||
</span> | ||
</Button> | ||
<Popover className="bg-orange-500 shadow-lg ring-1 ring-black/5"> | ||
<Menu className="min-w-[180px] whitespace-nowrap"> | ||
<MenuItem | ||
className={`flex w-full items-center px-5 py-2 text-left text-base font-medium ${ | ||
language === 'ja' | ||
? 'bg-orange-400 text-orange-50' | ||
: 'bg-orange-500 text-orange-50 hover:bg-orange-600' | ||
}`} | ||
> | ||
<Link | ||
href={removedLanguagePath} | ||
className="flex w-full items-center" | ||
> | ||
<span className="flex items-center gap-2"> | ||
{language === 'ja' && <RightIcon />} | ||
<Text slot="label" className="text-base font-bold"> | ||
日本語 | ||
</Text> | ||
</span> | ||
</Link> | ||
</MenuItem> | ||
<MenuItem | ||
className={`flex w-full items-center px-5 py-2 text-left text-base font-medium ${ | ||
language === 'en' | ||
? 'bg-orange-400 text-orange-50' | ||
: 'bg-orange-500 text-orange-50 hover:bg-orange-600' | ||
}`} | ||
> | ||
<Link | ||
href={`/en${removedLanguagePath}`} | ||
className="flex w-full items-center" | ||
> | ||
<span className="flex items-center gap-2"> | ||
{language === 'en' && <RightIcon />} | ||
<Text slot="label" className="text-base font-bold"> | ||
English | ||
</Text> | ||
</span> | ||
</Link> | ||
</MenuItem> | ||
</Menu> | ||
</Popover> | ||
</MenuTrigger> | ||
<LoginButton language={language} /> | ||
</div> | ||
</div> | ||
</div> | ||
</ReactAriaHeader> | ||
); | ||
}; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { type Language } from '@/features/language'; | ||
import { assertNever } from '@/utils/assertNever'; | ||
|
||
export const uploadText = (language: Language): string => { | ||
switch (language) { | ||
case 'ja': | ||
return 'アップロード'; | ||
case 'en': | ||
return 'Upload new Cats'; | ||
default: | ||
return assertNever(language); | ||
} | ||
}; | ||
|
||
export const howToUseText = (language: Language): string => { | ||
switch (language) { | ||
case 'ja': | ||
return '使い方'; | ||
case 'en': | ||
return 'How to Use'; | ||
default: | ||
return assertNever(language); | ||
} | ||
}; | ||
|
||
export const policyText = (language: Language): string => { | ||
switch (language) { | ||
case 'ja': | ||
return 'ポリシー'; | ||
case 'en': | ||
return 'Policy'; | ||
default: | ||
return assertNever(language); | ||
} | ||
}; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import { HeaderLogo } from './HeaderLogo'; | ||
|
||
const meta = { | ||
component: HeaderLogo, | ||
} satisfies Meta<typeof HeaderLogo>; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const HomeLinkIsJapanese: Story = { | ||
args: { | ||
language: 'ja', | ||
}, | ||
}; | ||
|
||
export const HomeLinkIsEnglish: Story = { | ||
args: { | ||
language: 'en', | ||
}, | ||
}; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { LgtmCatIcon } from '@/app/_components/LgtmCatIcon'; | ||
import type { Language } from '@/features/language'; | ||
import { createIncludeLanguageAppPath } from '@/features/url'; | ||
import Link from 'next/link'; | ||
import type { JSX } from 'react'; | ||
import { Text } from 'react-aria-components'; | ||
|
||
export type Props = { | ||
language: Language; | ||
}; | ||
|
||
export const HeaderLogo = ({ language }: Props): JSX.Element => { | ||
const homeToLink = createIncludeLanguageAppPath('home', language); | ||
|
||
return ( | ||
<Link | ||
href={homeToLink} | ||
className="flex h-10 w-[218px] items-center justify-center gap-0.5 bg-orange-500" | ||
prefetch={false} | ||
> | ||
<LgtmCatIcon className="shrink-0" aria-hidden={true} /> | ||
<h1 className="text-4xl font-bold text-orange-50 no-underline"> | ||
<Text>LGTMeow</Text> | ||
</h1> | ||
</Link> | ||
); | ||
}; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import { LgtmCatIcon } from './LgtmCatIcon'; | ||
|
||
const meta = { | ||
component: LgtmCatIcon, | ||
} satisfies Meta<typeof LgtmCatIcon>; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const Default: Story = {}; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import type { JSX } from 'react'; | ||
|
||
type Props = { | ||
className?: string; | ||
'aria-hidden'?: boolean; | ||
}; | ||
|
||
export const LgtmCatIcon = ({ | ||
className, | ||
'aria-hidden': ariaHidden, | ||
}: Props): JSX.Element => { | ||
return ( | ||
<svg | ||
xmlns="http://www.w3.org/2000/svg" | ||
width="36" | ||
height="27" | ||
viewBox="0 0 36 27" | ||
fill="none" | ||
className={className} | ||
aria-hidden={ariaHidden} | ||
> | ||
<path | ||
d="M6.54738 10.5211C6.63369 10.5436 6.71625 10.5548 6.80256 10.5548C7.21159 10.5548 7.59059 10.2847 7.70692 9.86822C8.46869 7.1555 9.42934 4.15011 10.0823 2.56675C11.9023 4.61536 13.6847 6.79155 13.8611 7.32059C13.9624 7.82711 14.4578 8.15729 14.9643 8.05599C15.4709 7.95468 15.8012 7.45941 15.6998 6.95289C15.4672 5.79351 12.3826 2.2891 10.5664 0.304268C10.3825 0.10541 10.1273 -0.00715129 9.84962 0.000352791C9.57569 0.00785687 9.32052 0.131674 9.1479 0.345541C8.10469 1.61748 6.25844 8.08225 5.89819 9.36545C5.75935 9.86447 6.0483 10.3823 6.54738 10.5211Z" | ||
fill="#FFF7ED" | ||
/> | ||
<path | ||
d="M35.3142 14.3219C34.4211 14.8621 33.3479 15.016 32.3422 15.3124C32.1734 14.0592 31.7869 12.7798 31.1714 11.5191C30.9463 11.0538 30.3834 10.8587 29.9181 11.0838C29.4528 11.309 29.2576 11.8718 29.4828 12.337C30.087 13.5752 30.4322 14.8284 30.5298 16.0403C29.6742 16.4343 28.8186 16.8357 27.8992 17.0608C27.3138 17.2072 27.5615 18.1114 28.1469 17.9651C28.9875 17.755 29.768 17.406 30.5485 17.0458C30.5035 18.2277 30.2108 19.3458 29.6704 20.3439C29.1976 20.2914 28.7248 20.2426 28.2482 20.2051C27.6478 20.16 27.6478 21.098 28.2482 21.1431C28.5334 21.1656 28.8148 21.1993 29.0963 21.2256C29.07 21.2594 29.0475 21.2969 29.0212 21.3307C28.1356 22.4525 26.8147 23.3793 25.0923 24.0922C23.7001 24.67 22.1653 24.9626 20.5067 24.9626L16.3902 25.1127C14.5927 25.1765 12.8703 24.9776 11.2604 24.5199C10.7201 24.3661 10.2547 24.201 9.91327 24.0434C8.84004 23.5444 7.81935 22.6101 7.04257 21.4057C7.00504 21.3457 6.97127 21.2856 6.93375 21.2256C7.21143 21.1993 7.48537 21.1656 7.76306 21.1431C8.35971 21.098 8.36722 20.16 7.76306 20.2051C7.32026 20.2388 6.88121 20.2876 6.44216 20.3364C5.86427 19.1582 5.62411 18.0814 5.59409 17.1096C6.32959 17.4473 7.06884 17.77 7.86062 17.9651C8.44602 18.1114 8.69744 17.2072 8.10829 17.0608C7.24521 16.847 6.43841 16.4793 5.63161 16.1078C5.76295 14.9147 6.15697 13.9016 6.47969 13.0799L6.61478 12.7347C6.79865 12.2507 6.55849 11.7104 6.07441 11.5228C5.59033 11.339 5.04997 11.5791 4.86234 12.0631L4.73475 12.3933C4.4383 13.1437 4.04804 14.1493 3.8454 15.3612C2.79094 15.031 1.64641 14.8884 0.697016 14.3181C0.179164 14.0067 -0.293656 14.8171 0.224195 15.1285C1.29367 15.7739 2.56954 15.9015 3.73658 16.3067C3.65402 17.5674 3.81913 19.0082 4.49084 20.5878C3.23374 20.7829 1.98414 21.0343 0.749551 21.3457C0.164154 21.492 0.411822 22.4 0.997219 22.2499C2.28809 21.9235 3.59398 21.6683 4.90737 21.4732C5.07248 21.7847 5.25261 22.0998 5.46275 22.4188C6.44216 23.9383 7.70677 25.0865 9.12148 25.7431C9.55677 25.9457 10.1009 26.1408 10.7426 26.3209C12.3224 26.7711 13.996 27 15.7297 27C15.9699 27 16.21 26.9962 16.454 26.985L20.5367 26.8387C22.4092 26.8387 24.1842 26.4972 25.8053 25.8294C27.8279 24.9927 29.404 23.8708 30.4922 22.4938C30.7474 22.1711 30.9726 21.8334 31.1752 21.4845C32.4623 21.6796 33.7419 21.931 35.0065 22.2499C35.5919 22.3962 35.8434 21.492 35.2542 21.3457C34.0571 21.0418 32.8451 20.7979 31.6255 20.6028C32.2221 19.267 32.4848 17.7887 32.4135 16.2542C33.5393 15.8865 34.7514 15.7439 35.7758 15.1285C36.2937 14.8171 35.8208 14.0067 35.303 14.3181L35.3142 14.3219Z" | ||
fill="#FFF7ED" | ||
/> | ||
<path | ||
d="M17.3364 7.91346L20.7324 8.02227C20.7324 8.02227 20.7512 8.02227 20.7625 8.02227C20.8 8.02227 20.8338 8.01476 20.8713 8.01101C20.9313 8.03728 20.9951 8.05979 21.0627 8.07104C21.573 8.17235 22.0608 7.85718 22.1622 7.35065C22.346 6.7991 24.1285 4.61541 25.9485 2.5668C26.6014 4.15391 27.5621 7.15555 28.3238 9.86827C28.4402 10.281 28.8154 10.5549 29.2282 10.5549C29.3108 10.5549 29.3971 10.5436 29.4834 10.5211C29.9825 10.3823 30.2714 9.86452 30.1326 9.3655C29.7723 8.0823 27.9261 1.62129 26.8829 0.349343C26.7102 0.139229 26.4551 0.0116594 26.1811 0.00415533C25.9147 -0.0071008 25.6483 0.109212 25.4644 0.308071C23.9671 1.94396 21.6105 4.60791 20.6987 6.14625L17.4002 6.04119C16.8936 6.01868 16.4508 6.4314 16.432 6.94918C16.4133 7.46697 16.8223 7.89845 17.3401 7.91721L17.3364 7.91346Z" | ||
fill="#FFF7ED" | ||
/> | ||
<path | ||
d="M15.4627 20.3214C16.1307 20.7116 16.8737 20.9367 17.5416 20.4077C17.7668 20.2313 17.9431 20.0025 18.1045 19.7698C18.2696 20.0025 18.446 20.2276 18.6674 20.4077C19.3316 20.933 20.0746 20.7079 20.7463 20.3214C21.2679 20.0175 20.7951 19.207 20.2735 19.511C19.9357 19.7061 19.5492 19.9462 19.2077 19.6423C19.0614 19.511 18.9488 19.3496 18.8362 19.1883C18.7162 19.0157 18.5848 18.8393 18.5886 18.6255C18.5961 18.3703 18.3672 18.1565 18.1195 18.1565H18.0895C17.8418 18.1565 17.6129 18.3703 17.6204 18.6255C17.6242 18.8318 17.5078 18.9932 17.3953 19.1583C17.2789 19.3309 17.1589 19.5034 17.005 19.6423C16.6635 19.9499 16.277 19.7098 15.9393 19.511C15.4177 19.207 14.9449 20.0175 15.4665 20.3214H15.4627Z" | ||
fill="#FFF7ED" | ||
/> | ||
<path | ||
d="M13.6813 14.5395C13.4974 14.442 13.2948 14.4195 13.0921 14.4007C12.9308 14.3857 12.7694 14.3745 12.6081 14.3857C12.2328 14.412 11.8575 14.532 11.6024 14.821C11.351 15.1061 11.2346 15.4475 11.2009 15.8227C11.1821 16.0516 11.2121 16.2805 11.2459 16.5056C11.2797 16.7082 11.3134 16.9221 11.4185 17.0984C11.5423 17.3011 11.7337 17.4136 11.9476 17.4962C12.0077 17.5187 12.0677 17.5412 12.1277 17.5599C12.1277 17.5599 12.1277 17.5599 12.1352 17.5637C12.1427 17.5674 12.1502 17.5749 12.1578 17.5787C12.1578 17.5787 12.1578 17.5787 12.1615 17.5825C12.214 17.6387 12.2853 17.6838 12.3679 17.7025C12.6118 17.755 12.8295 17.7213 13.0584 17.6312C13.3023 17.5337 13.5387 17.4136 13.7601 17.2635C14.0378 17.0759 14.2517 16.8621 14.3455 16.5244C14.4431 16.1867 14.4243 15.789 14.3305 15.4513C14.2329 15.0911 14.019 14.7084 13.6738 14.532L13.6813 14.5395Z" | ||
fill="#FFF7ED" | ||
/> | ||
<path | ||
d="M22.398 14.2768C22.0303 14.3144 21.6813 14.4644 21.4261 14.7383C21.1634 15.0197 21.0284 15.3837 21.0058 15.7626C20.9833 16.1791 21.1372 16.5731 21.3961 16.8958C21.6175 17.1697 21.9215 17.331 22.2554 17.406C22.3117 17.4323 22.3718 17.4436 22.4393 17.4436C22.4843 17.4473 22.5294 17.4436 22.5744 17.4286C22.7583 17.4098 22.9309 17.3723 23.1073 17.2897C23.3737 17.1659 23.5988 16.9633 23.7715 16.7269C23.9779 16.453 24.0416 16.1266 23.9929 15.7964C23.9516 15.5075 23.8803 15.2186 23.7302 14.9635C23.4638 14.5132 22.9234 14.2206 22.3943 14.2768H22.398Z" | ||
fill="#FFF7ED" | ||
/> | ||
</svg> | ||
); | ||
}; | ||
Oops, something went wrong.