fix: Link, Pages, Topic, Hook and Others (#178)

* chore: remove useKeyDownListener

* chore: remove react-use, update jazz version and add query string

* chore: update jazz version

* chore: use simple mac or win utils code

* feat(util): add isTextInput

* feat(hooks): all needed hooks

* fix: link bunch stuff

* fix: page bunch stuff

* chore: bunch update for custom component

* chore: use throttle from internal hook

* chore: topic bunch stuff

* chore: update layout

* fix: truncate content header of topic detail
This commit is contained in:
Aslam
2024-09-23 23:16:02 +07:00
committed by GitHub
parent 21084cd3f3
commit 867478d55c
43 changed files with 616 additions and 466 deletions

View File

@@ -19,6 +19,7 @@ import { FormField, FormItem, FormLabel } from "@/components/ui/form"
import { LearningStateSelector } from "@/components/custom/learning-state-selector"
import { TopicSelector, topicSelectorAtom } from "@/components/custom/topic-selector"
import { JAZZ_GLOBAL_GROUP_ID } from "@/lib/constants"
import { useOnClickOutside } from "@/hooks/use-on-click-outside"
export const globalLinkFormExceptionRefsAtom = atom<React.RefObject<HTMLElement>[]>([])
@@ -78,26 +79,16 @@ export const LinkForm: React.FC<LinkFormProps> = ({
[exceptionsRefs, globalExceptionRefs]
)
React.useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
const isClickInsideForm = formRef.current && formRef.current.contains(event.target as Node)
const isClickInsideExceptions = allExceptionRefs.some((ref, index) => {
const isInside = ref.current && ref.current.contains(event.target as Node)
return isInside
})
if (!isClickInsideForm && !istopicSelectorOpen && !islearningStateSelectorOpen && !isClickInsideExceptions) {
onClose?.()
}
useOnClickOutside(formRef, event => {
if (
!istopicSelectorOpen &&
!islearningStateSelectorOpen &&
!allExceptionRefs.some(ref => ref.current?.contains(event.target as Node))
) {
console.log("clicking outside")
onClose?.()
}
document.addEventListener("mousedown", handleClickOutside)
return () => {
document.removeEventListener("mousedown", handleClickOutside)
}
}, [islearningStateSelectorOpen, istopicSelectorOpen, allExceptionRefs, onClose])
})
React.useEffect(() => {
if (selectedLink) {
@@ -193,7 +184,15 @@ export const LinkForm: React.FC<LinkFormProps> = ({
const canSubmit = form.formState.isValid && !form.formState.isSubmitting
return (
<div className="p-3 transition-all">
<div
tabIndex={-1}
className="p-3 transition-all"
onKeyDown={e => {
if (e.key === "Escape") {
handleCancel()
}
}}
>
<div className={cn("bg-muted/30 relative rounded-md border", isFetching && "opacity-50")}>
<Form {...form}>
<form ref={formRef} onSubmit={form.handleSubmit(onSubmit)} className="relative min-w-0 flex-1">
@@ -213,7 +212,6 @@ export const LinkForm: React.FC<LinkFormProps> = ({
<LearningStateSelector
value={field.value}
onChange={value => {
// toggle, if already selected set undefined
form.setValue("learningState", field.value === value ? undefined : value)
}}
showSearch={false}

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useMemo } from "react"
import * as React from "react"
import Image from "next/image"
import Link from "next/link"
import { useAtom } from "jotai"
@@ -19,22 +19,18 @@ interface LinkItemProps extends React.HTMLAttributes<HTMLDivElement> {
personalLink: PersonalLink
disabled?: boolean
editId: string | null
setEditId: (id: string | null) => void
isActive: boolean
setActiveItemIndex: (index: number | null) => void
index: number
onItemSelected?: (personalLink: PersonalLink) => void
onFormClose?: () => void
}
export const LinkItem = React.forwardRef<HTMLDivElement, LinkItemProps>(
(
{ personalLink, disabled, editId, setEditId, isActive, setActiveItemIndex, index, onItemSelected, ...props },
ref
) => {
({ personalLink, disabled, editId, isActive, index, onItemSelected, onFormClose, ...props }, ref) => {
const [openPopoverForId, setOpenPopoverForId] = useAtom(linkOpenPopoverForIdAtom)
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: personalLink.id, disabled })
const style = useMemo(
const style = React.useMemo(
() => ({
transform: CSS.Transform.toString(transform),
transition
@@ -42,15 +38,12 @@ export const LinkItem = React.forwardRef<HTMLDivElement, LinkItemProps>(
[transform, transition]
)
const handleSuccess = useCallback(() => setEditId(null), [setEditId])
const handleOnClose = useCallback(() => setEditId(null), [setEditId])
const selectedLearningState = useMemo(
const selectedLearningState = React.useMemo(
() => LEARNING_STATES.find(ls => ls.value === personalLink.learningState),
[personalLink.learningState]
)
const handleLearningStateSelect = useCallback(
const handleLearningStateSelect = React.useCallback(
(value: string) => {
const learningState = value as LearningStateValue
personalLink.learningState = personalLink.learningState === learningState ? undefined : learningState
@@ -59,10 +52,19 @@ export const LinkItem = React.forwardRef<HTMLDivElement, LinkItemProps>(
[personalLink, setOpenPopoverForId]
)
const handleKeyDown = React.useCallback(
(ev: React.KeyboardEvent<HTMLDivElement>) => {
if (ev.key === "Enter") {
ev.preventDefault()
ev.stopPropagation()
onItemSelected?.(personalLink)
}
},
[personalLink, onItemSelected]
)
if (editId === personalLink.id) {
return (
<LinkForm onClose={handleOnClose} personalLink={personalLink} onSuccess={handleSuccess} onFail={() => {}} />
)
return <LinkForm onClose={onFormClose} personalLink={personalLink} onSuccess={onFormClose} onFail={() => {}} />
}
return (
@@ -86,12 +88,7 @@ export const LinkItem = React.forwardRef<HTMLDivElement, LinkItemProps>(
data-disabled={disabled}
data-active={isActive}
className="w-full overflow-visible border-b-[0.5px] border-transparent outline-none data-[active='true']:bg-[var(--link-background-muted)] data-[keyboard-active='true']:focus-visible:shadow-[var(--link-shadow)_0px_0px_0px_1px_inset]"
onKeyDown={e => {
if (e.key === "Enter") {
e.preventDefault()
onItemSelected?.(personalLink)
}
}}
onKeyDown={handleKeyDown}
>
<div
className={cn(