Skip to content

Commit

Permalink
feat: header drawer
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Jun 18, 2023
1 parent 279f1cc commit 96fe3fa
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 40 deletions.
10 changes: 5 additions & 5 deletions src/app/notes/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ const NoteMetaBar = () => {

const children = [] as ReactNode[]
if (note.weather || !note.mood) {
children.push(<DividerVertical className="!mx-2 scale-y-50" />)
children.push(<DividerVertical className="!mx-2 scale-y-50" key="d0" />)
}

if (note.weather) {
children.push(
<span className="inline-flex items-center space-x-1">
<span className="inline-flex items-center space-x-1" key="weather">
{weather2icon(note.weather)}
<span className="font-medium">{note.weather}</span>
<DividerVertical className="!mx-2 scale-y-50" />
Expand All @@ -127,7 +127,7 @@ const NoteMetaBar = () => {

if (note.mood) {
children.push(
<span className="inline-flex items-center space-x-1">
<span className="inline-flex items-center space-x-1" key="mood">
{mood2icon(note.mood)}
<span className="font-medium">{note.mood}</span>
</span>,
Expand All @@ -136,8 +136,8 @@ const NoteMetaBar = () => {

if (note.count.read > 0) {
children.push(
<DividerVertical className="!mx-2 scale-y-50" />,
<span className="inline-flex items-center space-x-1">
<DividerVertical className="!mx-2 scale-y-50" key="d1" />,
<span className="inline-flex items-center space-x-1" key="readcount">
<i className="icon-[mingcute--book-6-line]" />
<span className="font-medium">{note.count.read}</span>
</span>,
Expand Down
18 changes: 9 additions & 9 deletions src/components/icons/emoji.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function EmojiSmile() {
)
}

export function FaSolidSadCry() {
export function EmojiSadCry() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -32,7 +32,7 @@ export function FaSolidSadCry() {
)
}

export function FaSolidSadTear() {
export function EmojiSadTear() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -48,7 +48,7 @@ export function FaSolidSadTear() {
)
}

export function FaSolidAngry() {
export function EmojiAngry() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -64,7 +64,7 @@ export function FaSolidAngry() {
)
}

export function FaSolidTired() {
export function EmojiTired() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -80,7 +80,7 @@ export function FaSolidTired() {
)
}

export function FaSolidMeh() {
export function EmojiMeh() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -102,7 +102,7 @@ export function FaSolidMeh() {
)
}

export function FaSolidGrinSquintTears() {
export function EmojiGrinSquintTears() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -118,7 +118,7 @@ export function FaSolidGrinSquintTears() {
)
}

export function FaSolidFrownOpen() {
export function EmojiFrownOpen() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -134,7 +134,7 @@ export function FaSolidFrownOpen() {
)
}

export function FaSolidGrimace() {
export function EmojiGrimace() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -150,7 +150,7 @@ export function FaSolidGrimace() {
)
}

export function FaSolidFlushed() {
export function EmojiFlushed() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand Down
7 changes: 5 additions & 2 deletions src/components/layout/header/internal/HeaderActionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
export const HeaderActionButton: Component = ({ children }) => {
export const HeaderActionButton: Component<JSX.IntrinsicElements['button']> = ({
children,
...rest
}) => {
return (
<button
type="button"
className="group h-10 rounded-full bg-gradient-to-b from-zinc-50/50 to-white/90 px-3 text-sm shadow-lg shadow-zinc-800/5 ring-1 ring-zinc-900/5 backdrop-blur transition dark:from-zinc-900/50 dark:to-zinc-800/90 dark:ring-white/10 dark:hover:ring-white/20"
{...rest}
>
{children}
</button>
Expand Down
124 changes: 121 additions & 3 deletions src/components/layout/header/internal/HeaderDrawerButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
'use client'

import * as Dialog from '@radix-ui/react-dialog'
import { memo } from 'react'
import { AnimatePresence, motion } from 'framer-motion'
import { atom, useAtom } from 'jotai'
import Link from 'next/link'
import type { SVGProps } from 'react'

import { CloseIcon } from '~/components/icons/close'
import { MotionButtonBase } from '~/components/ui/button/MotionButton'
import { reboundPreset } from '~/constants/spring'
import { jotaiStore } from '~/lib/store'

import { HeaderActionButton } from './HeaderActionButton'
import { useHeaderConfig } from './HeaderDataConfigureProvider'

function IcBaselineMenuOpen(props: SVGProps<SVGSVGElement>) {
return (
Expand All @@ -13,10 +26,115 @@ function IcBaselineMenuOpen(props: SVGProps<SVGSVGElement>) {
)
}

const drawerOpenAtom = atom(false)
export const HeaderDrawerButton = () => {
const [open, setOpen] = useAtom(drawerOpenAtom)

return (
<Dialog.Root open={open} onOpenChange={(open) => setOpen(open)}>
<Dialog.Trigger asChild>
<HeaderActionButton>
<IcBaselineMenuOpen />
</HeaderActionButton>
</Dialog.Trigger>
<Dialog.Portal forceMount>
<AnimatePresence>
{open && (
<>
<Dialog.Overlay asChild>
<motion.div
className="fixed inset-0 z-[11] bg-slate-50/80 backdrop-blur-sm dark:bg-slate-900/80"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
/>
</Dialog.Overlay>

<Dialog.Content>
<motion.dialog
className="fixed inset-0 z-[12] flex max-h-[100vh] min-h-0 items-center justify-center overflow-hidden rounded-xl bg-base-100/90"
initial={{ opacity: 0.8 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Dialog.DialogClose asChild>
<MotionButtonBase
className="absolute right-4 top-4 p-4"
onClick={() => {
setOpen(false)
}}
>
<CloseIcon />
</MotionButtonBase>
</Dialog.DialogClose>

<HeaderDrawerContent />
</motion.dialog>
</Dialog.Content>
</>
)}
</AnimatePresence>
</Dialog.Portal>
</Dialog.Root>
)
}

// @ts-ignore
const LinkInternal: typeof Link = memo(({ children, ...rest }) => {
return (
<HeaderActionButton>
<IcBaselineMenuOpen />
</HeaderActionButton>
<Link
{...rest}
onClick={() => {
jotaiStore.set(drawerOpenAtom, false)
}}
>
{children}
</Link>
)
})

const HeaderDrawerContent = () => {
const { config } = useHeaderConfig()

return (
<div className="h-[100vh] w-[90vw] space-y-4 overflow-auto py-8 scrollbar-none">
{config.map((section, index) => {
return (
<motion.section
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{
...reboundPreset,
delay: index * 0.08,
}}
key={section.path}
>
<LinkInternal className="block" href={section.path}>
<span className="flex items-center space-x-2 py-2 text-[16px]">
<i>{section.icon}</i>
<h2>{section.title}</h2>
</span>
</LinkInternal>

{section.subMenu && (
<ul className="my-2 grid grid-cols-2 gap-2">
{section.subMenu.map((sub) => {
return (
<li key={sub.path}>
<LinkInternal
className="inline-block p-2"
href={sub.path}
>
{sub.title}
</LinkInternal>
</li>
)
})}
</ul>
)}
</motion.section>
)
})}
</div>
)
}
22 changes: 22 additions & 0 deletions src/components/ui/button/MotionButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { memo } from 'react'
import { motion } from 'framer-motion'
import type { HTMLMotionProps } from 'framer-motion'

import { microReboundPreset } from '~/constants/spring'

export const MotionButtonBase: Component<HTMLMotionProps<'button'>> = memo(
({ children, ...rest }) => {
return (
<motion.button
initial={true}
whileFocus={{ scale: 1.05 }}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
transition={{ ...microReboundPreset }}
{...rest}
>
{children}
</motion.button>
)
},
)
42 changes: 21 additions & 21 deletions src/lib/meta-icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import type { FC } from 'react'

import { PhSunBold } from '~/components/icons/appearance'
import {
EmojiAngry,
EmojiFlushed,
EmojiFrownOpen,
EmojiGrimace,
EmojiGrinSquintTears,
EmojiMeh,
EmojiSadCry,
EmojiSadTear,
EmojiSmile,
FaSolidAngry,
FaSolidFlushed,
FaSolidFrownOpen,
FaSolidGrimace,
FaSolidGrinSquintTears,
FaSolidMeh,
FaSolidSadCry,
FaSolidSadTear,
FaSolidTired,
EmojiTired,
} from '~/components/icons/emoji'
import {
BiCloudLightningRainFill,
Expand All @@ -37,18 +37,18 @@ export const weather2icon = (weather: string) => {
export const mood2icon = (mood: string) => {
const map: Record<string, FC> = {
开心: EmojiSmile,
伤心: FaSolidSadTear,
大哭: FaSolidSadCry,
生气: FaSolidAngry,
痛苦: FaSolidTired,
悲哀: FaSolidMeh,
不快: FaSolidMeh,
激动: FaSolidGrinSquintTears,
担心: FaSolidFrownOpen,
可怕: FaSolidGrimace,
可恶: FaSolidAngry,
绝望: FaSolidFrownOpen,
焦虑: FaSolidFlushed,
伤心: EmojiSadTear,
大哭: EmojiSadCry,
生气: EmojiAngry,
痛苦: EmojiTired,
悲哀: EmojiMeh,
不快: EmojiMeh,
激动: EmojiGrinSquintTears,
担心: EmojiFrownOpen,
可怕: EmojiGrimace,
可恶: EmojiAngry,
绝望: EmojiFrownOpen,
焦虑: EmojiFlushed,
}
return React.createElement(map[mood] || EmojiSmile)
}

0 comments on commit 96fe3fa

Please sign in to comment.