Skip to content

Commit

Permalink
fix: emoji panel float popover
Browse files Browse the repository at this point in the history
  • Loading branch information
Innei committed Sep 8, 2023
1 parent 4116060 commit 5919712
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 137 deletions.
16 changes: 8 additions & 8 deletions src/app/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { PeekLink } from '~/components/widgets/peek/PeekLink'
import { PostMetaBar } from '~/components/widgets/post'
import {
microReboundPreset,
softBouncePrest,
softBouncePreset,
softSpringPreset,
} from '~/constants/spring'
import { shuffle } from '~/lib/_'
Expand Down Expand Up @@ -131,7 +131,7 @@ const Welcome = () => {
className="group relative leading-[4] [&_*]:inline-block"
initial={{ opacity: 0.0001, y: 50 }}
animate={{ opacity: 1, y: 0 }}
transition={softBouncePrest}
transition={softBouncePreset}
>
{title.template.map((t, i) => {
const { type } = t
Expand All @@ -157,7 +157,7 @@ const Welcome = () => {

<BottomToUpTransitionView
delay={titleAnimateD + 500}
transition={softBouncePrest}
transition={softBouncePreset}
className="my-3"
>
<span className="opacity-80">{description}</span>
Expand Down Expand Up @@ -195,7 +195,7 @@ const Welcome = () => {
<m.div
initial={{ opacity: 0.0001, y: 50 }}
animate={{ opacity: 1, y: 0 }}
transition={softBouncePrest}
transition={softBouncePreset}
className={clsx(
'absolute bottom-0 left-0 right-0 flex flex-col center',

Expand Down Expand Up @@ -298,7 +298,7 @@ const PostScreen = () => {
initial={{ opacity: 0.0001, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{
...softBouncePrest,
...softBouncePreset,
delay: 0.3 + 0.2 * posts.length,
}}
className="relative mt-12 w-full text-center"
Expand Down Expand Up @@ -336,7 +336,7 @@ const NoteScreen = () => {
className="mb-6 text-center text-2xl"
initial={{ opacity: 0.0001, y: 50 }}
animate={{ opacity: 1, y: 0 }}
transition={softBouncePrest}
transition={softBouncePreset}
>
看看我的近况,这是我最近的所思所想
</m.h3>
Expand Down Expand Up @@ -388,7 +388,7 @@ const NoteScreen = () => {
initial={{ opacity: 0.0001, y: 50 }}
animate={{ opacity: 0.8, y: 0 }}
transition={{
...softBouncePrest,
...softBouncePreset,
delay: 0.5,
}}
className="text-lg"
Expand Down Expand Up @@ -506,7 +506,7 @@ const FriendScreen = () => {
animate={{ scale: 1, opacity: 1 }}
transition={{
delay: i * 0.1 + 0.3,
...softBouncePrest,
...softBouncePreset,
}}
className="w-full min-w-0"
>
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/header/internal/Activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '~/atoms/activity'
import { ImpressionView } from '~/components/common/ImpressionTracker'
import { FloatPopover } from '~/components/ui/float-popover'
import { softBouncePrest } from '~/constants/spring'
import { softBouncePreset } from '~/constants/spring'
import { TrackerAction } from '~/constants/tracker'
import useDebounceValue from '~/hooks/common/use-debounce-value'
import { usePageIsActive } from '~/hooks/common/use-is-active'
Expand Down Expand Up @@ -203,7 +203,7 @@ export const Activity = memo(() => {
opacity: 0,
x: -10,
}}
transition={softBouncePrest}
transition={softBouncePreset}
>
<FloatPopover
TriggerComponent={TriggerComponent}
Expand Down
142 changes: 37 additions & 105 deletions src/components/ui/float-popover/FloatPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

import { flip, offset, shift, useFloating } from '@floating-ui/react-dom'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { AnimatePresence, m } from 'framer-motion'
import type { UseFloatingOptions } from '@floating-ui/react-dom'
import type { FC, PropsWithChildren } from 'react'

import { microReboundPreset } from '~/constants/spring'
import useClickAway from '~/hooks/common/use-click-away'
import { useEventCallback } from '~/hooks/common/use-event-callback'
import { clsxm } from '~/lib/helper'

import { RootPortal } from '../portal'
import styles from './index.module.css'

type FloatPopoverProps<T> = PropsWithChildren<{
TriggerComponent: FC<T>
Expand Down Expand Up @@ -58,11 +60,8 @@ export const FloatPopover = function FloatPopover<T extends {}>(
...floatingProps
} = props

const [mounted, setMounted] = useState(false)

const [currentStatus, setCurrentStatus] = useState(false)
const [open, setOpen] = useState(false)
const { x, y, refs, strategy, update, isPositioned } = useFloating({
const { x, y, refs, strategy, isPositioned } = useFloating({
middleware: floatingProps.middleware ?? [
flip({ padding: padding ?? 20 }),
offset(offsetValue ?? 10),
Expand All @@ -72,96 +71,34 @@ export const FloatPopover = function FloatPopover<T extends {}>(
placement: floatingProps.placement ?? 'bottom-start',
whileElementsMounted: floatingProps.whileElementsMounted,
})
const updateOnce = useRef(false)
const doPopoverShow = useCallback(() => {
setCurrentStatus(true)
setMounted(true)

if (!updateOnce.current) {
requestAnimationFrame(() => {
update()
updateOnce.current = true
})
}
}, [])

const [containerAnchorRef, setContainerAnchorRef] =
useState<HTMLDivElement | null>()
const containerRef = useRef<HTMLDivElement>(null)

const handleTransition = useCallback(
(status: 'in' | 'out') => {
const nextElementSibling =
containerAnchorRef?.nextElementSibling as HTMLDivElement

if (!nextElementSibling) {
return
}

if (status === 'in') {
nextElementSibling.ontransitionend = null
nextElementSibling.classList.add(styles.show)
} else {
nextElementSibling.classList.remove(styles.show)
nextElementSibling.ontransitionend = () => {
setOpen(false)
setMounted(false)
}
}
},
[containerAnchorRef?.nextElementSibling],
)

useEffect(() => {
if (!containerAnchorRef) {
return
}

if (currentStatus) {
setOpen(true)
requestAnimationFrame(() => {
handleTransition('in')
})
} else {
requestAnimationFrame(() => {
handleTransition('out')
})
}
}, [currentStatus, containerAnchorRef, handleTransition])

useClickAway(containerRef, () => {
if (trigger == 'click' || trigger == 'both') {
doPopoverDisappear()
clickTriggerFlag.current = false
}
})

const doPopoverDisappear = useCallback(() => {
if (debug) {
return
}
if (!animate) {
setOpen(false)
}
setCurrentStatus(false)
setOpen(false)
}, [debug, animate])

const clickTriggerFlag = useRef(false)
const doPopoverShow = useEventCallback(() => {
setOpen(true)
})

const handleMouseOut = useCallback(() => {
if (clickTriggerFlag.current === true) {
return
}
doPopoverDisappear()
}, [])
const handleClickTrigger = useCallback(() => {
clickTriggerFlag.current = true
doPopoverShow()
}, [])

const listener = useMemo(() => {
const baseListener = {
onFocus: doPopoverShow,
onBlur: doPopoverDisappear,
// onFocus: doPopoverShow,
// onBlur: doPopoverDisappear,
}
switch (trigger) {
case 'click':
Expand All @@ -178,18 +115,12 @@ export const FloatPopover = function FloatPopover<T extends {}>(
case 'both':
return {
...baseListener,
onClick: handleClickTrigger,
onClick: doPopoverShow,
onMouseOver: doPopoverShow,
onMouseOut: handleMouseOut,
}
}
}, [
doPopoverDisappear,
doPopoverShow,
handleClickTrigger,
handleMouseOut,
trigger,
])
}, [doPopoverDisappear, doPopoverShow, handleMouseOut, trigger])

const TriggerWrapper = (
<As
Expand Down Expand Up @@ -220,20 +151,19 @@ export const FloatPopover = function FloatPopover<T extends {}>(
<>
{TriggerWrapper}

{mounted && (
<RootPortal>
<div
className={clsxm(
'float-popover',
'relative z-[99]',
popoverWrapperClassNames,
)}
{...(trigger === 'hover' || trigger === 'both' ? listener : {})}
ref={containerRef}
>
<div ref={setContainerAnchorRef} />
{open && (
<div
<AnimatePresence>
{open && (
<RootPortal>
<m.div
className={clsxm(
'float-popover',
'relative z-[99]',
popoverWrapperClassNames,
)}
{...(trigger === 'hover' || trigger === 'both' ? listener : {})}
ref={containerRef}
>
<m.div
tabIndex={-1}
role={type === 'tooltip' ? 'tooltip' : 'dialog'}
className={clsxm(
Expand All @@ -245,14 +175,16 @@ export const FloatPopover = function FloatPopover<T extends {}>(

'relative z-[2]',

headless && styles['headless'],
animate && styles['animate'],
type === 'tooltip'
? `max-w-[25rem] break-all rounded-xl px-4 py-2 ${styles['headless']}`
: styles['popover-root'],
? `max-w-[25rem] break-all rounded-xl px-4 py-2`
: '',
popoverClassNames,
)}
ref={refs.setFloating}
initial={{ translateY: '10px', opacity: 0 }}
animate={{ translateY: '0px', opacity: 1 }}
exit={{ translateY: '10px', opacity: 0 }}
transition={microReboundPreset}
style={{
position: strategy,
top: y ?? '',
Expand All @@ -261,11 +193,11 @@ export const FloatPopover = function FloatPopover<T extends {}>(
}}
>
{props.children}
</div>
)}
</div>
</RootPortal>
)}
</m.div>
</m.div>
</RootPortal>
)}
</AnimatePresence>
</>
)
}
18 changes: 0 additions & 18 deletions src/components/ui/float-popover/index.module.css

This file was deleted.

4 changes: 2 additions & 2 deletions src/components/ui/transition/BottomToUpTransitionView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { softBouncePrest } from '~/constants/spring'
import { softBouncePreset } from '~/constants/spring'

import { createTransitionView } from './factor'

Expand All @@ -13,5 +13,5 @@ export const BottomToUpTransitionView = createTransitionView({
y: 0,
opacity: 1,
},
preset: softBouncePrest,
preset: softBouncePreset,
})
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const UniversalTextArea = () => {
$ta.selectionStart = $ta.selectionEnd = $ta.value.length
$ta.focus()
}, [])

return (
<TextArea
ref={taRef}
Expand Down
6 changes: 5 additions & 1 deletion src/components/widgets/shared/EmojiPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import EmojiPicker$, { EmojiStyle } from 'emoji-picker-react'
import EmojiPicker$, { EmojiStyle, Theme } from 'emoji-picker-react'
import { memo } from 'react'
import type { FC } from 'react'

import { useIsDark } from '~/hooks/common/use-is-dark'

export const EmojiPicker: FC<{
onEmojiSelect: (emoji: string) => void
}> = memo(({ onEmojiSelect }) => {
const isDark = useIsDark()
return (
<EmojiPicker$
theme={isDark ? Theme.DARK : Theme.LIGHT}
onEmojiClick={(e) => {
onEmojiSelect(e.emoji)
}}
Expand Down
2 changes: 1 addition & 1 deletion src/constants/spring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const softSpringPreset: Spring = {
damping: 20,
}

export const softBouncePrest: Spring = {
export const softBouncePreset: Spring = {
type: 'spring',
damping: 10,
stiffness: 100,
Expand Down

1 comment on commit 5919712

@vercel
Copy link

@vercel vercel bot commented on 5919712 Sep 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

shiro – ./

shiro-innei.vercel.app
springtide.vercel.app
shiro-git-main-innei.vercel.app
innei.in

Please sign in to comment.