Skip to content

Commit

Permalink
fix + style: 修 bug + 配合調整結構
Browse files Browse the repository at this point in the history
1. Prop XXX did not match. Server: "null 或 AAA" Client: "OOO" → vercel/next.js#7322 (comment)
2. Transient Props 問題 → react 不認得的 prop 前面加 $ (component 本身也要加)
3. Tag Button Active 時的動畫做好 + 顏色改固定不隨機了
4. _document 因應 SSR 整個改寫 (參考 nextjs/example/with-styled-components)
5. 調整 theme 物件 color 的結構 (分為 toneColor(固定不變)、coreColor(亮暗模式會變))
6. 取消在變換 Tag 時的 shallow routing (breadcrumb 配合調整如果沒有那頁面就顯示普通文字)
  • Loading branch information
kyo144 committed Jan 2, 2022
1 parent 18a3f21 commit 546f6b5
Show file tree
Hide file tree
Showing 20 changed files with 224 additions and 160 deletions.
2 changes: 1 addition & 1 deletion .babelrc
@@ -1,4 +1,4 @@
{
"presets": ["next/babel"],
"plugins": ["styled-components"]
"plugins": [["styled-components", { "ssr": true, "displayName": true, "preprocess": false }]]
}
2 changes: 1 addition & 1 deletion components/Boxes/WrapBox.js
Expand Up @@ -5,7 +5,7 @@ import { motion } from 'framer-motion'
const WrapBox = styled(motion.div)`
width: ${({ width }) => width};
height: ${({ height }) => height};
position: ${({ position }) => position};
position: ${({ position }) => position ? position : 'relative'};
border: ${({ border }) => border ? border : 'none'};
border-radius: 2px;
${({ position }) => position && positionMixins};
Expand Down
4 changes: 2 additions & 2 deletions components/Buttons/CircleButton.js
Expand Up @@ -9,8 +9,8 @@ const CircleButton = styled(motion.button)`
border-radius: 50%;
border: ${({ border }) => border ? border : 'none'};
padding: 0px;
color: ${({ theme, color }) => color ? color : theme.color.core.secondary};
background-color: ${({ theme, bgColor }) => bgColor ? bgColor : theme.color.core.primary};
color: ${({ theme, color }) => color ? color : theme.coreColor.secondary};
background-color: ${({ theme, bgColor }) => bgColor ? bgColor : theme.coreColor.primary};
position: ${({ position }) => position};
${({ position }) => position && positionMixins};
${transformMixins};
Expand Down
10 changes: 6 additions & 4 deletions components/Buttons/TagButton.js
@@ -1,11 +1,13 @@
import styled from 'styled-components'
import { motion } from 'framer-motion'

const TagButton = styled.button`
const TagButton = styled(motion.button)`
height: 32px;
border-radius: 2px;
border: none;
background-color: ${({ theme, bgColor }) => bgColor ? bgColor : theme.color.core.tertiary};
color: ${({ theme }) => theme.color.core.secondary};
border: ${({ border }) => border};
background-color: ${({ bgColor }) => bgColor};
color: ${({ color }) => color};
font-weight: ${({ theme }) => theme.fontWeights.medium};
`

export default TagButton
4 changes: 2 additions & 2 deletions components/Buttons/TriangleButton.js
Expand Up @@ -11,8 +11,8 @@ const TriangleButton = styled(motion.span)`
width: 0;
height: 0;
border-style: solid;
border-width: ${({ widthNum, heightNum }) => `${heightNum}px ${widthNum / 2}px 0 ${widthNum / 2}px`};
border-color: ${({ theme, color }) => `${color ? color : theme.color.core.tertiary} transparent transparent transparent`};
border-width: ${({ $widthNum, $heightNum }) => `${$heightNum}px ${$widthNum / 2}px 0 ${$widthNum / 2}px`};
border-color: ${({ theme, color }) => `${color ? color : theme.coreColor.tertiary} transparent transparent transparent`};
${transformMixins}
`

Expand Down
40 changes: 26 additions & 14 deletions components/Layout.js
@@ -1,20 +1,24 @@
import React, { useState, useEffect, useRef } from 'react'
import PropTypes from 'prop-types'
import dynamic from 'next/dynamic'
import { useAtom } from 'jotai'
import { darkModeAtom } from '../store/atoms'
import { useRouter } from 'next/router'
import styled from 'styled-components'
import { Col } from 'react-bootstrap'
import { useTheme } from 'styled-components'
import { FlexBox, FlexItem, flexParentMixin } from './Boxes/FlexBox'
import NoSsr from './NoSsr'
import Spacer from './Spacer'
import { flexParentMixin } from './Boxes/FlexBox'
import FixedBox from './Boxes/FixedBox'
import { ContainerBox } from './Boxes/ContainerBox'
import GlobalNav from './Navs/GlobalNav'
import Breadcrumbs from './Navs/Breadcrumb'
import GlobalFooter from './Footers/GlobalFooter'
import CircleButton from './Buttons/CircleButton'
import CtrlBarLine from './Lines/CtrlBarLine'
import CtrlBarText from './Typography/CtrlBarText'
import CircleButton from './Buttons/CircleButton'
import FixedBox from './Boxes/FixedBox'
import Breadcrumbs from './Navs/Breadcrumb'
import { Col } from 'react-bootstrap'

const FlexItemWithNoSSR = dynamic(() => import('./Boxes/FlexBox').then((mod => mod.FlexItem)), { ssr: false })

export const IndexSection = styled(Col)`
z-index: ${({ $isMainSection }) => $isMainSection ? '9' : undefined};
Expand Down Expand Up @@ -42,14 +46,11 @@ const LayoutContainer = styled(ContainerBox)`
display: flex;
${flexParentMixin};
`
const Main = styled(FlexItem)`
margin-top: ${({ marginTop }) => marginTop};
background-color: ${({ theme }) => theme.color.core.quarternary};
padding-top: 60px;
const Main = styled(FlexItemWithNoSSR)`
background-color: ${({ theme }) => theme.coreColor.quarternary};
`

const Layout = ({ children, navLinks }) => {
const router = useRouter()
const globalNavRef = useRef()
const theme = useTheme()
const [mainMarginTop, setMainMarginTop] = useState()
Expand All @@ -62,17 +63,28 @@ const Layout = ({ children, navLinks }) => {
<GlobalNav ref={globalNavRef} navLinks={navLinks} />
{/* Breadcrumb */}
<Breadcrumbs />
<Main marginTop={`${mainMarginTop}px`} flex='1'>
<Spacer size={mainMarginTop} />
<Main flex='1'>
{/* Main Content */}
<Spacer axis='vertical' size={60} />
<ContainerBox>
{ children }
</ContainerBox>
</Main>
{/* Theme Ctrl */}
<FixedBox flexFlow='column' justifyContent='center' alignItems='center' gap='12px' top={`${112}px`} right={`${60}px`}>
<CtrlBarText axis='vertical' fontSize={theme.fontSizes.excerpt}>{`Theme`}</CtrlBarText>
<CtrlBarLine axis='vertical' />
<CircleButton width='38px' height='38px' border={`1px solid ${theme.color.core.secondary}`} onClick={() => setDarkMode(!darkMode)}>{darkMode ? '🔥' : '🌘'}</CircleButton>
<NoSsr>
<CtrlBarLine axis='vertical' />
<CircleButton
width='38px'
height='38px'
border={`1px solid ${theme.coreColor.secondary}`}
onClick={() => setDarkMode(!darkMode)}
>
{darkMode ? '🔥' : '🌘'}
</CircleButton>
</NoSsr>
</FixedBox>
<GlobalFooter />
</LayoutContainer>
Expand Down
2 changes: 1 addition & 1 deletion components/Lines/CtrlBarLine.js
Expand Up @@ -10,7 +10,7 @@ const CtrlBarLine = styled.div`
height: 2px;
width: ${({ axis, width }) => axis === 'vertical' ? '2px' : width};
height: ${({ axis }) => axis === 'vertical' ? '100px' : '2px'};
background-color: ${({ theme }) => theme.color.core.secondary};
background-color: ${({ theme }) => theme.coreColor.secondary};
${({ axis }) => axis === 'vertical' && CtrlBarLineMixin};
`

Expand Down
2 changes: 1 addition & 1 deletion components/Lines/NavActiveLine.js
Expand Up @@ -7,7 +7,7 @@ const NavActiveLine = styled(motion.div)`
height: 2px;
width: ${({ width }) => width};
left: ${({ left }) => left};
background-color: #4F4F4F;
background-color: ${({ theme }) => theme.coreColor.secondary};
`

export default NavActiveLine
54 changes: 30 additions & 24 deletions components/Navs/Breadcrumb.js
@@ -1,14 +1,15 @@
import React, { useEffect, useState } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useAtom } from 'jotai'
import { curTagAtom } from '../../store/atoms'
import Link from 'next/link'
import { useTheme } from 'styled-components'
import NoSsr from '../NoSsr'
import FixedBox from '../Boxes/FixedBox'
import CtrlBarLine from '../Lines/CtrlBarLine'
import CtrlBarText from '../Typography/CtrlBarText'
import CircleButton from '../Buttons/CircleButton'
import TriangleButton from '../Buttons/TriangleButton'
import CtrlBarLine from '../Lines/CtrlBarLine'
import CtrlBarText from '../Typography/CtrlBarText'

const convertBreadcrumb = string => {
const replacedString = string
Expand Down Expand Up @@ -47,31 +48,36 @@ const Breadcrumbs = () => {
<FixedBox flexFlow='column' justifyContent='center' alignItems='center' gap='12px' top={`${196}px`} left={`${60}px`}>
<Link href='/' passHref>
<a>
<CircleButton
width='38px'
height='38px'
border={`1px solid ${theme.color.core.secondary}`}
onClick={() => curTag !== '' && setCurTag('')}
>
{'🏠'}
</CircleButton>
<NoSsr>
<CircleButton
width='38px'
height='38px'
border={`1px solid ${theme.coreColor.secondary}`}
onClick={() => curTag !== '' && setCurTag('')}
>
{'🏠'}
</CircleButton>
</NoSsr>
</a>
</Link>
<CtrlBarLine axis='vertical' />
<CtrlBarText axis='vertical' fontSize={theme.fontSizes.body1}>
{breadcrumbs.map((breadcrumb, index) =>
<>
<Link
passHref
key={breadcrumb.href}
href={breadcrumb.href === `/${curTag}` ? '/' : breadcrumb.href}
as={breadcrumb.href === `/${curTag}` ? `/${curTag}` : breadcrumb.href}
shallow={breadcrumb.href === `/${curTag}`}
>
<a>{convertBreadcrumb(breadcrumb.breadcrumb)}</a>
</Link>
{(index + 1 < breadcrumbs.length) && <TriangleButton widthNum={20} heightNum={17} margin='12px auto' />}
</>
{breadcrumbs.map(({ breadcrumb, href}, index) =>
<span key={href}>
{ breadcrumb === 'Blog' || (`${curTag}` && index === 0)
? (
<span>{convertBreadcrumb(breadcrumb)}</span>
) : (
<Link
passHref
href={href}
as={href}
>
<a>{convertBreadcrumb(breadcrumb)}</a>
</Link>
)}
{(index + 1 < breadcrumbs.length) && <NoSsr><TriangleButton $widthNum={20} $heightNum={17} margin='12px auto' /></NoSsr>}
</span>
)}
</CtrlBarText>
</FixedBox>
Expand Down
20 changes: 12 additions & 8 deletions components/Navs/GlobalNav.js
Expand Up @@ -6,11 +6,13 @@ import { useAtom } from 'jotai'
import { useAtomValue } from 'jotai/utils'
import { navLinksAtom, curTagAtom } from '../../store/atoms'
import styled from 'styled-components'
import NoSsr from '../NoSsr'
import Spacer from '../Spacer'
import { FlexBox, FlexItem, flexParentMixin } from '../Boxes/FlexBox'
import { ContainerBox } from '../Boxes/ContainerBox'
import NavActiveLine from '../Lines/NavActiveLine'

const NavBar = styled(FlexBox)`
margin-top: 42px;
position: relative;
`
const NavItemWrap = styled.a`
Expand All @@ -25,7 +27,6 @@ const Logo = styled(FlexItem)`
width: 51px;
margin-right: 16px;
`
const NavActiveLineWithNoSSR = dynamic(() => import('../Lines/NavActiveLine'), { ssr: false })

const GlobalNav = forwardRef((props, ref) => {
const [NavActiveLineOffset, setNavActiveLineOffset] = useState()
Expand All @@ -51,6 +52,7 @@ const GlobalNav = forwardRef((props, ref) => {

return (
<ContainerBox>
<Spacer size={42} />
{/* Header */}
<NavBar gap='32px' ref={ref}>
{navLinks?.map(navLink =>
Expand Down Expand Up @@ -81,12 +83,14 @@ const GlobalNav = forwardRef((props, ref) => {
</NavItemWrap>
</Link>
)}
<NavActiveLineWithNoSSR
width={firstNavItemRef.current.offsetWidth + 'px'}
left={firstNavItemRef.current.offsetLeft + 'px'}
initial={{ width: 0, left: 0 }}
animate={{ width: NavActiveLineOffset?.width, left: NavActiveLineOffset?.left }}
/>
<NoSsr>
<NavActiveLine
width={firstNavItemRef.current.offsetWidth + 'px'}
left={firstNavItemRef.current.offsetLeft + 'px'}
initial={{ width: 0, left: 0 }}
animate={{ width: NavActiveLineOffset?.width, left: NavActiveLineOffset?.left }}
/>
</NoSsr>
</NavBar>
</ContainerBox>
)
Expand Down
10 changes: 10 additions & 0 deletions components/NoSsr.js
@@ -0,0 +1,10 @@
import React from 'react'
import dynamic from 'next/dynamic'

const NoSsr = ({ children }) => <>{children}</>

export default dynamic(() => Promise.resolve(NoSsr), { ssr: false })

// * 2022-1-2 目前兩種 component 需要 dynamic with No SSR
// * 1. 用到 Framer Motion 的 (使用到動畫的)
// * 2. Dark Mode / Light Mode 樣式會變的
2 changes: 1 addition & 1 deletion components/globalMixins.js
Expand Up @@ -9,5 +9,5 @@ export const positionMixins = css`

export const transformMixins = css`
transform: ${({ transform }) => transform};
transform-origin: ${({ transformOrigin }) => transformOrigin};
transform-origin: ${({ $transformOrigin }) => $transformOrigin};
`
3 changes: 0 additions & 3 deletions lib/posts.js
@@ -1,7 +1,6 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { randomHueValue, randomPastelColor } from './tag'
import { getPostImg } from './imgs'

// * 取得 posts 資料夾路徑
Expand Down Expand Up @@ -63,9 +62,7 @@ export const getAllPost = async () => {
export const getAllUniqueTag = allPostData => {
const allTag = allPostData.map(postData => postData.tag)
let allUniqueTag = [...new Set(allTag)]
const hues = randomHueValue(allUniqueTag.length)
return allUniqueTag
.map((tag, index) => ({ tagName:tag, tagHue: randomPastelColor(hues[index]) }))
}

// * Get Slugs
Expand Down
11 changes: 3 additions & 8 deletions lib/tag.js
@@ -1,13 +1,8 @@
// * 產生 0 ~ 360 隨機數字 (色相環) 組成的 Array,Array 長度依照 Tag 數量
export const randomHueValue = length => {
return Array.from({ length }, () => Math.floor(Math.random() * 360)+1)
}

// * 隨機和菓子色產生器 (用 HSL)
export const randomPastelColor = value => {
// * 和菓子色產生器 (用 HSL)
export const pastelColor = value => {
const minHue = 360
const maxHue = 0
const curPercent = (value - minHue) / (maxHue-minHue)
const colorString = 'hsl(' + ((curPercent * (maxHue-minHue) ) + minHue) + ',85%,90%)'
const colorString = 'hsl(' + ((curPercent * (maxHue-minHue) ) + minHue) + ',85%,75%)'
return colorString
}
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -28,7 +28,7 @@
},
"devDependencies": {
"@next/eslint-plugin-next": "^11.1.2",
"babel-plugin-styled-components": "^1.13.3",
"babel-plugin-styled-components": "^2.0.2",
"eslint": "^7.23.0",
"eslint-config-next": "^12.0.7"
}
Expand Down

0 comments on commit 546f6b5

Please sign in to comment.