From 836d5b76e1d36d9eb2f5e0108fb8f8e090d11297 Mon Sep 17 00:00:00 2001 From: enes Date: Wed, 4 Dec 2024 13:26:22 +0100 Subject: [PATCH] feat(category): dynamic dropdown item height --- src/components/ModForm.tsx | 126 +++++++++++++++++++++++++------------ src/styles/styles.css | 4 +- 2 files changed, 89 insertions(+), 41 deletions(-) diff --git a/src/components/ModForm.tsx b/src/components/ModForm.tsx index 8546125..67e1f3f 100644 --- a/src/components/ModForm.tsx +++ b/src/components/ModForm.tsx @@ -1,6 +1,7 @@ import _ from 'lodash' import { Event, kinds, nip19, UnsignedEvent } from 'nostr-tools' import React, { + CSSProperties, Fragment, useCallback, useEffect, @@ -10,7 +11,7 @@ import React, { } from 'react' import { Link, useLocation, useNavigate } from 'react-router-dom' import { toast } from 'react-toastify' -import { FixedSizeList as List } from 'react-window' +import { VariableSizeList, FixedSizeList } from 'react-window' import { v4 as uuidv4 } from 'uuid' import { T_TAG_VALUE } from '../constants' import { useAppSelector, useGames, useNDKContext } from '../hooks' @@ -865,7 +866,7 @@ const GameDropdown = ({
- )} - +
@@ -992,6 +993,70 @@ export const CategoryAutocomplete = ({ })) }, [selectedCategories, setFormState]) + const listRef = useRef(null) + const rowHeights = useRef<{ [index: number]: number }>({}) + const setRowHeight = (index: number, size: number) => { + rowHeights.current = { ...rowHeights.current, [index]: size } + if (listRef.current) { + listRef.current.resetAfterIndex(index) + } + } + const getRowHeight = (index: number) => { + return (rowHeights.current[index] || 35) + 8 + } + + const Row = ({ index, style }: { index: number; style: CSSProperties }) => { + const rowRef = useRef(null) + + useEffect(() => { + const rowElement = rowRef.current + if (!rowElement) return + const updateHeight = () => { + const height = Math.max(rowElement.scrollHeight, 35) + setRowHeight(index, height) + } + const observer = new ResizeObserver(() => { + updateHeight() + }) + observer.observe(rowElement) + updateHeight() + return () => { + observer.disconnect() + } + }, [index]) + + if (!filteredOptions) return null + + return ( +
handleSelect(filteredOptions[index])} + > + {capitalizeEachWord(filteredOptions[index].hierarchy)} + {selectedCategories.some( + (cat) => cat.hierarchy === filteredOptions[index].hierarchy + ) && ( + + )} +
+ ) + } + return (
@@ -1025,43 +1090,22 @@ export const CategoryAutocomplete = ({
{filteredOptions && filteredOptions.length > 0 ? ( - + {Row} + + ) : ( + - {({ index, style }) => ( -
handleSelect(filteredOptions[index])} - > - {capitalizeEachWord(filteredOptions[index].hierarchy)} - {selectedCategories.some( - (cat) => - cat.hierarchy === filteredOptions[index].hierarchy - ) && ( - - )} -
- )} -
- ) : ( - {({ index, style }) => (
)} - + )}
@@ -1103,8 +1147,9 @@ export const CategoryAutocomplete = ({ {LTags.map((hierarchy) => { const heirarchicalCategories = hierarchy.split(`:`) const categories = heirarchicalCategories - .map((c: string) => ( + .map((c, i) => ( {capitalizeEachWord(c)}

)) - .reduce((prev, curr) => [ + .reduce((prev, curr, i) => [ prev, -
+

>

, curr diff --git a/src/styles/styles.css b/src/styles/styles.css index 8458aae..6aad09b 100644 --- a/src/styles/styles.css +++ b/src/styles/styles.css @@ -298,7 +298,7 @@ h6 { } .dropdownMainMenuItem { - transition: ease 0.4s; + transition: background ease 0.4s, color ease 0.4s; background: linear-gradient( rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.03) @@ -319,7 +319,7 @@ h6 { } .dropdownMainMenuItem:hover { - transition: ease 0.4s; + transition: background ease 0.4s, color ease 0.4s; background: linear-gradient( rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05)