Skip to content

Commit 41d4d7f

Browse files
authored
Merge pull request #75 from object-t/release/0.0.2
Release/0.0.2
2 parents b4bd814 + 33e853b commit 41d4d7f

29 files changed

+555
-100
lines changed

app/components/ActivityCard/activity-card.css

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,27 @@
6666
display: flex;
6767
justify-content: flex-end;
6868
}
69+
70+
@media (max-width: 1200px) {
71+
.activity-container {
72+
flex-direction: column;
73+
width: 700px;
74+
height: 700px
75+
}
76+
77+
.activity-image {
78+
height: 350px;
79+
}
80+
81+
.activity-image img {
82+
width: 700px;
83+
}
84+
85+
.activity-sub-container {
86+
background-color: var(--accent-color);
87+
width: 700px;
88+
height: 100px;
89+
}
90+
91+
92+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import type { Meta, StoryObj } from '@storybook/react';
2+
3+
import { Drawer } from './Drawer';
4+
5+
6+
const meta = {
7+
title: 'Common/Drawer',
8+
component: Drawer,
9+
tags: ['autodocs'],
10+
} satisfies Meta<typeof Drawer>;
11+
12+
export default meta;
13+
type Story = StoryObj<typeof meta>;
14+
15+
export const Default: Story = {
16+
args: {
17+
links: [
18+
{
19+
'label': "HOME",
20+
'to': "#home"
21+
},
22+
{
23+
'label': "MEMBER",
24+
'to': "#member"
25+
},
26+
{
27+
'label': "PRODUCT",
28+
'to': "#product"
29+
},
30+
{
31+
'label': "BLOG",
32+
'to': "#blog"
33+
}
34+
],
35+
onClick: () => {},
36+
children: (
37+
<button>クリック</button>
38+
)
39+
}
40+
};

app/components/Drawer/Drawer.tsx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { faXmark } from '@fortawesome/free-solid-svg-icons';
2+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3+
import { useEffect, useState } from 'react';
4+
import { LanguageButton } from '../LanguageButton/LanguageButton';
5+
import styles from './drawer.module.css';
6+
7+
export interface DrawerProps {
8+
links: Record<'label' | 'to', string>[];
9+
onClick: (link: string) => void;
10+
children: React.ReactNode;
11+
}
12+
13+
const sitemap: Record<string, string> = {
14+
"ホームページ": "/",
15+
"技術ブログ": "/blog",
16+
"": "",
17+
"お問い合わせ": "/",
18+
}
19+
20+
export const Drawer = ({
21+
links,
22+
onClick,
23+
children,
24+
...props
25+
}: DrawerProps) => {
26+
const [open, setOpen] = useState(false);
27+
28+
useEffect(() => {
29+
document.documentElement.style.overflow = open ? 'hidden' : '';
30+
}, [open]);
31+
32+
return (
33+
<div>
34+
<div {...props} onClick={() => setOpen(true)} className={[open ? styles.hidden : '', styles.trigger].join(" ")}>
35+
{children}
36+
</div>
37+
<div className={[styles.drawer, open ? styles['drawer-opened']: ''].join(" ")}>
38+
<div className={styles['button-container']}>
39+
<FontAwesomeIcon icon={faXmark} className={`${styles.close}`} onClick={() => setOpen(false)}/>
40+
<LanguageButton className={styles.lang}/>
41+
</div>
42+
<div className={styles['link-container']}>
43+
<h2>リンク</h2>
44+
<ul>
45+
{
46+
links.map(link => (
47+
<a
48+
key={link.label}
49+
href={link.to}
50+
onClick={(e) => {
51+
e.preventDefault();
52+
setOpen(false);
53+
54+
const id = link.to.replace('#', '');
55+
const element = document.getElementById(id);
56+
if (element) {
57+
element.scrollIntoView({ behavior: 'smooth' });
58+
}
59+
onClick?.(link.to);
60+
}}
61+
>
62+
<li>
63+
{link.label}
64+
</li>
65+
</a>
66+
))
67+
}
68+
</ul>
69+
<h2>サイトマップ</h2>
70+
<ul>
71+
{
72+
Object.entries(sitemap).map(([label, url]) => label ? (
73+
<a href={url} key={label}>
74+
<li>
75+
<p>
76+
{label}
77+
</p>
78+
</li>
79+
</a>
80+
): <br key={''}/>
81+
)
82+
}
83+
</ul>
84+
</div>
85+
</div>
86+
</div>
87+
);
88+
};
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.drawer {
2+
z-index: 99999999999;
3+
width: 100vw;
4+
height: 100vh;
5+
position: fixed;
6+
top: 0;
7+
left: 100%;
8+
background-color: #000000eb;
9+
opacity: 0;
10+
transition: transform 0.3s ease, opacity 0.3s ease-in;
11+
overflow-y: auto;
12+
}
13+
14+
.trigger {
15+
opacity: 1;
16+
padding-right: 12px;
17+
transition: opacity 0.3s ease;
18+
}
19+
20+
.hidden {
21+
opacity: 0;
22+
}
23+
24+
.button-container {
25+
width: auto;
26+
height: max-content;
27+
display: flex;
28+
flex-direction: column;
29+
align-items: end;
30+
padding-top: 24px;
31+
padding-right: 24px;
32+
}
33+
34+
.link-container {
35+
padding-left: 24px;
36+
}
37+
38+
.close {
39+
color: var(--accent-color);
40+
font-size: 52px;
41+
cursor: pointer;
42+
}
43+
44+
.lang {
45+
color: var(--accent-color);
46+
font-size: 52px;
47+
cursor: pointer;
48+
}
49+
50+
.drawer-opened {
51+
opacity: 1;
52+
transform: translateX(-100vw);
53+
}
54+
55+
a , p{
56+
color: var(--accent-color);
57+
font-size: 24px;
58+
text-decoration: none;
59+
}
60+
61+
ul {
62+
padding-left: 42px;
63+
}
64+
65+
li {
66+
margin: 4% 0;
67+
}
68+
69+
h2 {
70+
color: var(--accent-color);
71+
font-size: 42px;
72+
font-weight: 200;
73+
}

app/components/Footer/Footer.module.css

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,17 @@ footer {
5050
color: var(--accent-color);
5151
}
5252

53+
.container:last-of-type {
54+
padding-bottom: 40px;
55+
}
56+
5357
.copy {
5458
display: block;
55-
padding-top: 40px;
5659
text-align: center;
57-
padding-bottom: 12px;
60+
padding: 8px 0;
5861
letter-spacing: 1px;
62+
}
63+
64+
.copy.mobile {
65+
font-size: 12px;
5966
}

app/components/Footer/Footer.tsx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useIsMobile } from '~/hooks/useIsMobile';
12
import styles from './Footer.module.css';
23

34
const sitemap: Record<string, string> = {
@@ -37,27 +38,32 @@ const getList = (list: Record<string, string>) => {
3738
}
3839

3940
export const Footer = ({...props}) => {
41+
const isMobile = useIsMobile()
42+
4043
return (
4144
<footer {...props}>
42-
<div className={`${styles.container} ${styles.title}`}>
43-
<p>学生団体:Object&lt;T&gt;</p>
44-
<p>所属: 福岡デザイン&テクノロジー専門学校</p>
45-
</div>
46-
<div className={styles.container}>
47-
<div className={styles.block}>
48-
<p>サイトマップ</p>
49-
{getList(sitemap)}
50-
</div>
51-
<div className={styles.block}>
52-
<p>本サイトについて</p>
53-
{getList(aboutSite)}
54-
</div>
55-
<div className={styles.block}>
56-
<p>学校関連</p>
57-
{getList(school)}
45+
{
46+
!isMobile && <>
47+
<div className={`${styles.container} ${styles.title}`}>
48+
<p>学生団体:Object&lt;T&gt;</p>
49+
<p>所属: 福岡デザイン&テクノロジー専門学校</p>
50+
</div><div className={styles.container}>
51+
<div className={styles.block}>
52+
<p>サイトマップ</p>
53+
{getList(sitemap)}
54+
</div>
55+
<div className={styles.block}>
56+
<p>本サイトについて</p>
57+
{getList(aboutSite)}
58+
</div>
59+
<div className={styles.block}>
60+
<p>学校関連</p>
61+
{getList(school)}
62+
</div>
5863
</div>
59-
</div>
60-
<p className={styles.copy}>&copy; 学生団体 Object&lt;T&gt;. All rights reserved.</p>
64+
</>
65+
}
66+
<p className={[styles.copy, isMobile && styles.mobile].join(" ")}>&copy; 学生団体 Object&lt;T&gt;. All rights reserved.</p>
6167
</footer>
6268
);
6369
};

app/components/Header/Header.tsx

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11

2+
import { faBars } from '@fortawesome/free-solid-svg-icons';
3+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
24
import { useCallback, useEffect, useRef, useState } from 'react';
35
import { useNavigate } from 'react-router';
6+
import { useIsMobile } from '~/hooks/useIsMobile';
7+
import { Drawer } from '../Drawer/Drawer';
48
import { HeaderLink } from '../HeaderLink/HeaderLink';
59
import { LanguageButton } from '../LanguageButton/LanguageButton';
6-
import './header.css';
10+
import styles from './header.module.css';
711

812
const headers: Headers = [
913
{
@@ -33,6 +37,7 @@ type Headers = Record<'label' | 'to', string>[];
3337
export const Header = () => {
3438
const [activeSection, setActiveSection] = useState<string>('');
3539
const [isHidden, setIsHidden] = useState<boolean>(false);
40+
const isMobile = useIsMobile();
3641
const lastScrollY = useRef<number>(0);
3742
const ignoreScroll = useRef<boolean>(false);
3843
const ignoreTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
@@ -104,17 +109,30 @@ export const Header = () => {
104109

105110

106111
return (
107-
<header className={isHidden ? 'hidden' : ''}>
112+
<div>
108113
{
109-
headers.map(header => (
110-
<HeaderLink
111-
key={header.to}
112-
isActive={activeSection === header.to}
113-
label={header.label}
114-
onClick={() => handleClick(header.to)} to={header.to}/>
115-
))
114+
isMobile ?(
115+
<header className={styles.mobile}>
116+
<Drawer links={headers} onClick={(link) => handleClick(link)}>
117+
<FontAwesomeIcon icon={faBars} className={[`${styles.bars}`, isHidden && `${styles.hidden}`].join(" ")}/>
118+
</Drawer>
119+
</header>
120+
) : (
121+
<header className={isHidden ? styles.hidden : ''}>
122+
{
123+
headers.map(header => (
124+
<HeaderLink
125+
key={header.to}
126+
isActive={activeSection === header.to}
127+
label={header.label}
128+
onClick={() => handleClick(header.to)}
129+
to={header.to}/>
130+
))
131+
}
132+
<LanguageButton className={styles['language-button']}/>
133+
</header>
134+
)
116135
}
117-
<LanguageButton label={'JP'} className={'language-button'}/>
118-
</header>
136+
</div>
119137
);
120138
}

app/components/Header/header.css renamed to app/components/Header/header.module.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,21 @@ header {
2020
opacity: 0;
2121
transform: translateY(-100%);
2222
pointer-events: none;
23+
}
24+
25+
.mobile {
26+
right: 0;
27+
top: 0;
28+
padding-top: 24px;
29+
padding-right: 24px;
30+
}
31+
32+
.bars.hidden {
33+
transform: translateY(0);
34+
}
35+
36+
.bars {
37+
font-size: 42px;
38+
transition: opacity 0.5s ease, transform 0.5s ease;
39+
color: var(--accent-color);
2340
}

0 commit comments

Comments
 (0)