From ee35e64f6997f2b33e97917460a9f2a933295f0b Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 23:06:54 +0700 Subject: [PATCH 01/12] =?UTF-8?q?=F0=9F=94=A7=20chore:=20add=20icons?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/CustomIcon/BuildingIcon.tsx | 22 +++++++++++++++++++ .../shared/CustomIcon/ChevronUpDown.tsx | 21 ++++++++++++++++++ .../src/components/shared/CustomIcon/index.ts | 2 ++ 3 files changed, 45 insertions(+) create mode 100644 packages/frontend/src/components/shared/CustomIcon/BuildingIcon.tsx create mode 100644 packages/frontend/src/components/shared/CustomIcon/ChevronUpDown.tsx diff --git a/packages/frontend/src/components/shared/CustomIcon/BuildingIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/BuildingIcon.tsx new file mode 100644 index 00000000..cae3610e --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/BuildingIcon.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const BuildingIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/ChevronUpDown.tsx b/packages/frontend/src/components/shared/CustomIcon/ChevronUpDown.tsx new file mode 100644 index 00000000..ac6f1723 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/ChevronUpDown.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const ChevronUpDown = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/index.ts b/packages/frontend/src/components/shared/CustomIcon/index.ts index 72205c83..59a6d8f2 100644 --- a/packages/frontend/src/components/shared/CustomIcon/index.ts +++ b/packages/frontend/src/components/shared/CustomIcon/index.ts @@ -4,6 +4,7 @@ export * from './CheckIcon'; export * from './ChevronGrabberHorizontal'; export * from './ChevronLeft'; export * from './ChevronRight'; +export * from './ChevronUpDown'; export * from './InfoSquareIcon'; export * from './WarningIcon'; export * from './SearchIcon'; @@ -26,6 +27,7 @@ export * from './GithubIcon'; export * from './GitTeaIcon'; export * from './LockIcon'; export * from './PencilIcon'; +export * from './BuildingIcon'; export * from './CheckRadioIcon'; export * from './ChevronDownIcon'; export * from './BranchIcon'; From 2f466d4fbb3a8eb6e13511772b4ca491b205b259 Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 23:07:31 +0700 Subject: [PATCH 02/12] =?UTF-8?q?=F0=9F=94=A7=20chore:=20remove=20dot=20wh?= =?UTF-8?q?en=20description=20dont=20exist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/shared/Select/SelectItem/SelectItem.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/components/shared/Select/SelectItem/SelectItem.tsx b/packages/frontend/src/components/shared/Select/SelectItem/SelectItem.tsx index a6bbc487..060be52a 100644 --- a/packages/frontend/src/components/shared/Select/SelectItem/SelectItem.tsx +++ b/packages/frontend/src/components/shared/Select/SelectItem/SelectItem.tsx @@ -62,11 +62,13 @@ const SelectItem = forwardRef(

{label}

- {orientation === 'horizontal' && } {description && ( -

- {description} -

+ <> + {orientation === 'horizontal' && } +

+ {description} +

+ )} {renderRightIcon} From 0381fdbbedbe1ff80cc26a4d69e6ac76188d3e6c Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 23:07:54 +0700 Subject: [PATCH 03/12] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20impelment=20?= =?UTF-8?q?user=20select?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/UserSelect/UserSelect.theme.ts | 58 ++++++ .../shared/UserSelect/UserSelect.tsx | 186 ++++++++++++++++++ .../UserSelectItem/UserSelectItem.theme.ts | 28 +++ .../UserSelectItem/UserSelectItem.tsx | 75 +++++++ .../shared/UserSelect/UserSelectItem/index.ts | 2 + .../src/components/shared/UserSelect/index.ts | 2 + 6 files changed, 351 insertions(+) create mode 100644 packages/frontend/src/components/shared/UserSelect/UserSelect.theme.ts create mode 100644 packages/frontend/src/components/shared/UserSelect/UserSelect.tsx create mode 100644 packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.theme.ts create mode 100644 packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx create mode 100644 packages/frontend/src/components/shared/UserSelect/UserSelectItem/index.ts create mode 100644 packages/frontend/src/components/shared/UserSelect/index.ts diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelect.theme.ts b/packages/frontend/src/components/shared/UserSelect/UserSelect.theme.ts new file mode 100644 index 00000000..7e17355e --- /dev/null +++ b/packages/frontend/src/components/shared/UserSelect/UserSelect.theme.ts @@ -0,0 +1,58 @@ +import { tv, VariantProps } from 'tailwind-variants'; + +export const userSelectTheme = tv({ + slots: { + container: ['flex', 'flex-col', 'relative', 'gap-2'], + inputWrapper: [ + 'relative', + 'flex', + 'flex-wrap', + 'gap-1', + 'min-w-[200px]', + 'w-full', + 'rounded-lg', + 'bg-transparent', + 'text-elements-mid-em', + 'shadow-sm', + 'border', + 'border-border-interactive', + 'focus-ring', + 'disabled:shadow-none', + 'disabled:border-none', + ], + input: ['outline-none'], + popover: [ + 'mt-12', + 'z-20', + 'absolute', + 'px-1', + 'py-1', + 'flex-col', + 'gap-0.5', + 'min-w-full', + 'bg-surface-floating', + 'shadow-dropdown', + 'w-auto', + 'max-h-60', + 'overflow-auto', + 'border', + 'border-gray-200', + 'rounded-xl', + ], + }, + variants: { + isOpen: { + true: { + popover: ['flex'], + }, + false: { + popover: ['hidden'], + }, + }, + hasValue: { + true: '', + }, + }, +}); + +export type UserSelectTheme = VariantProps; diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx new file mode 100644 index 00000000..7bfca072 --- /dev/null +++ b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx @@ -0,0 +1,186 @@ +import React, { + useState, + ComponentPropsWithoutRef, + useCallback, + useRef, + useEffect, +} from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useCombobox } from 'downshift'; +import { UserSelectTheme, userSelectTheme } from './UserSelect.theme'; +import { + BuildingIcon, + ChevronUpDown, + SettingsSlidersIcon, +} from 'components/shared/CustomIcon'; +import { cn } from 'utils/classnames'; +import { EmptyUserSelectItem, UserSelectItem } from './UserSelectItem'; + +export type UserSelectOption = { + value: string; + label: string; + imgSrc?: string; +}; + +interface UserSelectProps + extends Omit, 'value' | 'onChange'>, + UserSelectTheme { + options: UserSelectOption[]; + value?: UserSelectOption; +} + +export const UserSelect = ({ options, value }: UserSelectProps) => { + const theme = userSelectTheme(); + const navigate = useNavigate(); + + const [selectedItem, setSelectedItem] = useState( + null, + ); + const [dropdownOpen, setDropdownOpen] = useState(false); + const [dropdownPosition, setDropdownPosition] = useState<'top' | 'bottom'>( + 'bottom', + ); + const popoverRef = useRef(null); // Ref for the popover + const inputWrapperRef = useRef(null); // Ref for the input wrapper + + // Calculate and update popover position + useEffect(() => { + if (dropdownOpen && popoverRef.current && inputWrapperRef.current) { + const popover = popoverRef.current; + // @ts-expect-error – we know it's not null lol + const input = inputWrapperRef.current.getBoundingClientRect(); + const spaceBelow = window.innerHeight - input.bottom; + const spaceAbove = input.top; + // @ts-expect-error – we know it's not null lol + const popoverHeight = popover.offsetHeight; + + // Determine if there's enough space below + if (spaceBelow >= popoverHeight) { + setDropdownPosition('bottom'); + } else if (spaceAbove >= popoverHeight) { + setDropdownPosition('top'); + } else { + // Default to bottom if neither has enough space, but you could also set logic to choose the side with more space + setDropdownPosition('bottom'); + } + } + }, [dropdownOpen]); // Re-calculate whenever the dropdown is opened + + useEffect(() => { + setSelectedItem(value as UserSelectOption); + }, [value]); + + const handleSelectedItemChange = (selectedItem: UserSelectOption | null) => { + setSelectedItem(selectedItem); + navigate(`/${selectedItem?.value}`); + }; + + const isSelected = useCallback( + (item: UserSelectOption) => selectedItem?.value === item.value, + [selectedItem], + ); + + const { isOpen, getMenuProps, highlightedIndex, getItemProps, openMenu } = + useCombobox({ + items: options, + // @ts-expect-error – there are two params but we don't need the second one + isItemDisabled: (item) => item.disabled, + onSelectedItemChange: ({ selectedItem }) => { + if (selectedItem) { + console.log(selectedItem); + handleSelectedItemChange(selectedItem); + } + }, + onIsOpenChange: ({ isOpen }) => { + setDropdownOpen(isOpen ?? false); + }, + selectedItem: selectedItem, + itemToString: (item) => (item ? item.label : ''), + }); + + const handleManage = () => { + //TODO: implement manage handler + }; + + return ( +
+ {/* Input */} +
!dropdownOpen && openMenu()} + className="cursor-pointer relative py-2 pl-2 pr-4 flex min-w-[200px] w-full items-center justify-between rounded-xl bg-surface-card shadow-sm" + > +
+ Snowball Logo +
+ {selectedItem?.label ? ( +

+ {selectedItem?.label} +

+ ) : ( +
+ )} +

Organization

+
+
+ +
+ +
+
+ + {/* Popover */} +
    + {/* Settings header */} +
    +
    + +

    Other teams

    +
    +
    +

    Manage

    + +
    +
    + + {/* Organization */} + {isOpen && options.length !== 0 ? ( + options.map((item, index) => ( + + )) + ) : ( + + )} + + {/* //TODO:Squiggly line */} + {/* //TODO:Personal */} +
+
+ ); +}; diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.theme.ts b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.theme.ts new file mode 100644 index 00000000..e5b8685e --- /dev/null +++ b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.theme.ts @@ -0,0 +1,28 @@ +import { tv, VariantProps } from 'tailwind-variants'; + +export const userSelectItemTheme = tv({ + slots: { + wrapper: [ + 'p-2', + 'gap-3', + 'flex', + 'items-center', + 'justify-between', + 'rounded-lg', + 'cursor-pointer', + ], + content: ['flex', 'gap-3', 'items-center'], + img: ['h-5', 'w-5'], + selectedIcon: ['h-5', 'w-5', 'text-controls-primary'], + label: ['text-sm', 'text-elements-high-em', 'tracking-[-0.006em]'], + }, + variants: { + active: { + true: { + wrapper: ['bg-base-bg-emphasized'], + }, + }, + }, +}); + +export type UserSelectItemTheme = VariantProps; diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx new file mode 100644 index 00000000..9684bc9a --- /dev/null +++ b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx @@ -0,0 +1,75 @@ +import React, { forwardRef, ComponentPropsWithoutRef, useMemo } from 'react'; +import { Overwrite, UseComboboxGetItemPropsReturnValue } from 'downshift'; +import { + userSelectItemTheme, + UserSelectItemTheme, +} from './UserSelectItem.theme'; +import { CheckRadioIcon } from 'components/shared/CustomIcon'; +import { UserSelectOption } from 'components/shared/UserSelect'; +import { OmitCommon } from 'types/common'; + +/** + * Represents a type that merges ComponentPropsWithoutRef<'li'> with certain exclusions. + * @type {MergedComponentPropsWithoutRef} + */ +type MergedComponentPropsWithoutRef = OmitCommon< + ComponentPropsWithoutRef<'li'>, + Omit< + Overwrite, + 'index' | 'item' + > +>; + +export interface UserSelectItemProps + extends MergedComponentPropsWithoutRef, + UserSelectItemTheme { + selected: boolean; + option: UserSelectOption; + hovered?: boolean; +} + +const UserSelectItem = forwardRef( + ({ className, selected, hovered, option, ...props }, ref) => { + const theme = userSelectItemTheme(); + + const { value, label, imgSrc } = option; + + const renderLeftImage = useMemo( + () => ( +
+ {`${value}-logo`} +
+ ), + [imgSrc, value], + ); + + return ( +
  • +
    + {renderLeftImage} +

    {label}

    +
    + {selected && } +
  • + ); + }, +); + +export const EmptyUserSelectItem = () => { + const theme = userSelectItemTheme(); + return ( +
  • +
    +

    No results found

    +
    +
  • + ); +}; + +UserSelectItem.displayName = 'UserSelectItem'; + +export { UserSelectItem }; diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelectItem/index.ts b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/index.ts new file mode 100644 index 00000000..57e76fc6 --- /dev/null +++ b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/index.ts @@ -0,0 +1,2 @@ +export * from './UserSelectItem'; +export * from './UserSelectItem.theme'; diff --git a/packages/frontend/src/components/shared/UserSelect/index.ts b/packages/frontend/src/components/shared/UserSelect/index.ts new file mode 100644 index 00000000..8225a33c --- /dev/null +++ b/packages/frontend/src/components/shared/UserSelect/index.ts @@ -0,0 +1,2 @@ +export * from './UserSelect'; +export * from './UserSelect.theme'; From 30c50a3eec21e1572fc1635a1a2b483c7684bf9a Mon Sep 17 00:00:00 2001 From: Andre H Date: Wed, 28 Feb 2024 23:08:21 +0700 Subject: [PATCH 04/12] =?UTF-8?q?=F0=9F=94=A7=20chore:=20use=20UserSelect?= =?UTF-8?q?=20in=20sidebar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/shared/Sidebar/Sidebar.tsx | 69 ++++++------------- 1 file changed, 22 insertions(+), 47 deletions(-) diff --git a/packages/frontend/src/components/shared/Sidebar/Sidebar.tsx b/packages/frontend/src/components/shared/Sidebar/Sidebar.tsx index 0d746749..1dbb3b6d 100644 --- a/packages/frontend/src/components/shared/Sidebar/Sidebar.tsx +++ b/packages/frontend/src/components/shared/Sidebar/Sidebar.tsx @@ -1,14 +1,11 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Link, NavLink, useNavigate, useParams } from 'react-router-dom'; import { Organization } from 'gql-client'; -import { Option } from '@material-tailwind/react'; import { useDisconnect } from 'wagmi'; import { useGQLClient } from 'context/GQLClientContext'; -import AsyncSelect from 'components/shared/AsyncSelect'; import { - ChevronGrabberHorizontal, FolderIcon, GlobeIcon, LifeBuoyIcon, @@ -17,6 +14,7 @@ import { } from 'components/shared/CustomIcon'; import { Tabs } from 'components/shared/Tabs'; import { Heading } from 'components/shared/Heading'; +import { UserSelect } from 'components/shared/UserSelect'; export const Sidebar = () => { const { orgSlug } = useParams(); @@ -37,6 +35,22 @@ export const Sidebar = () => { setSelectedOrgSlug(orgSlug); }, [orgSlug]); + const formattedSelected = useMemo(() => { + const selected = organizations.find((org) => org.slug === selectedOrgSlug); + return { + value: selected?.slug ?? '', + label: selected?.name ?? '', + imgSrc: '/logo.svg', + }; + }, [organizations, selectedOrgSlug, orgSlug]); + const formattedSelectOptions = useMemo(() => { + return organizations.map((org) => ({ + value: org.slug, + label: org.name, + imgSrc: '/logo.svg', + })); + }, [organizations, selectedOrgSlug, orgSlug]); + const handleLogOut = useCallback(() => { disconnect(); navigate('/login'); @@ -57,49 +71,10 @@ export const Sidebar = () => { {/* Switch organization */}
    - { - setSelectedOrgSlug(value!); - navigate(`/${value}`); - }} - selected={(_, index) => ( -
    - Application Logo -
    -
    - {organizations[index!]?.name} -
    -
    Organization
    -
    -
    - )} - arrow={} - > - {/* // TODO: Show label organization and manage in option */} - {organizations.map((org) => ( - - ))} -
    + {[ From f77f7c120a00e65dbed5290f1e474108a1cfb950 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 29 Feb 2024 08:52:26 +0700 Subject: [PATCH 05/12] =?UTF-8?q?=F0=9F=94=A7=20chore:=20follow=20select?= =?UTF-8?q?=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/shared/UserSelect/UserSelect.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx index 7bfca072..eaae61d1 100644 --- a/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx +++ b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx @@ -1,7 +1,6 @@ import React, { useState, ComponentPropsWithoutRef, - useCallback, useRef, useEffect, } from 'react'; @@ -34,7 +33,7 @@ export const UserSelect = ({ options, value }: UserSelectProps) => { const navigate = useNavigate(); const [selectedItem, setSelectedItem] = useState( - null, + (value as UserSelectOption) || null, ); const [dropdownOpen, setDropdownOpen] = useState(false); const [dropdownPosition, setDropdownPosition] = useState<'top' | 'bottom'>( @@ -75,10 +74,8 @@ export const UserSelect = ({ options, value }: UserSelectProps) => { navigate(`/${selectedItem?.value}`); }; - const isSelected = useCallback( - (item: UserSelectOption) => selectedItem?.value === item.value, - [selectedItem], - ); + const isSelected = (item: UserSelectOption) => + selectedItem?.value === item.value; const { isOpen, getMenuProps, highlightedIndex, getItemProps, openMenu } = useCombobox({ @@ -94,7 +91,7 @@ export const UserSelect = ({ options, value }: UserSelectProps) => { onIsOpenChange: ({ isOpen }) => { setDropdownOpen(isOpen ?? false); }, - selectedItem: selectedItem, + selectedItem: value || null, itemToString: (item) => (item ? item.label : ''), }); From a5b4103515c222cade865748837c3cee9b0e211a Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 29 Feb 2024 09:15:18 +0700 Subject: [PATCH 06/12] =?UTF-8?q?=F0=9F=94=A7=20chore:=20bigger=20img=20on?= =?UTF-8?q?=20userselectitem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UserSelect/UserSelectItem/UserSelectItem.theme.ts | 2 +- .../shared/UserSelect/UserSelectItem/UserSelectItem.tsx | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.theme.ts b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.theme.ts index e5b8685e..17f28bdd 100644 --- a/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.theme.ts +++ b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.theme.ts @@ -12,7 +12,7 @@ export const userSelectItemTheme = tv({ 'cursor-pointer', ], content: ['flex', 'gap-3', 'items-center'], - img: ['h-5', 'w-5'], + img: ['h-10', 'w-10', 'rounded-lg'], selectedIcon: ['h-5', 'w-5', 'text-controls-primary'], label: ['text-sm', 'text-elements-high-em', 'tracking-[-0.006em]'], }, diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx index 9684bc9a..861ca13f 100644 --- a/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx +++ b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx @@ -32,14 +32,10 @@ const UserSelectItem = forwardRef( ({ className, selected, hovered, option, ...props }, ref) => { const theme = userSelectItemTheme(); - const { value, label, imgSrc } = option; + const { value, label, imgSrc = './logo.svg' } = option; const renderLeftImage = useMemo( - () => ( -
    - {`${value}-logo`} -
    - ), + () => {`${value}-logo`}, [imgSrc, value], ); From fe427a9fb80a80d08cc0624ebb535ffccb782e5a Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 29 Feb 2024 09:16:01 +0700 Subject: [PATCH 07/12] =?UTF-8?q?=F0=9F=90=9B=20fix:=20onChange=20not=20tr?= =?UTF-8?q?iggered.=20thanks=20@ayungavis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/UserSelect/UserSelect.tsx | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx index eaae61d1..07866570 100644 --- a/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx +++ b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx @@ -5,14 +5,14 @@ import React, { useEffect, } from 'react'; import { useNavigate } from 'react-router-dom'; -import { useCombobox } from 'downshift'; -import { UserSelectTheme, userSelectTheme } from './UserSelect.theme'; +import { useSelect } from 'downshift'; import { BuildingIcon, ChevronUpDown, SettingsSlidersIcon, } from 'components/shared/CustomIcon'; import { cn } from 'utils/classnames'; +import { UserSelectTheme, userSelectTheme } from './UserSelect.theme'; import { EmptyUserSelectItem, UserSelectItem } from './UserSelectItem'; export type UserSelectOption = { @@ -77,23 +77,27 @@ export const UserSelect = ({ options, value }: UserSelectProps) => { const isSelected = (item: UserSelectOption) => selectedItem?.value === item.value; - const { isOpen, getMenuProps, highlightedIndex, getItemProps, openMenu } = - useCombobox({ - items: options, - // @ts-expect-error – there are two params but we don't need the second one - isItemDisabled: (item) => item.disabled, - onSelectedItemChange: ({ selectedItem }) => { - if (selectedItem) { - console.log(selectedItem); - handleSelectedItemChange(selectedItem); - } - }, - onIsOpenChange: ({ isOpen }) => { - setDropdownOpen(isOpen ?? false); - }, - selectedItem: value || null, - itemToString: (item) => (item ? item.label : ''), - }); + const { + isOpen, + getMenuProps, + getToggleButtonProps, + highlightedIndex, + getItemProps, + openMenu, + } = useSelect({ + items: options, + // @ts-expect-error – there are two params but we don't need the second one + isItemDisabled: (item) => item.disabled, + onSelectedItemChange: ({ selectedItem }) => { + if (selectedItem) { + handleSelectedItemChange(selectedItem); + } + }, + onIsOpenChange: ({ isOpen }) => { + setDropdownOpen(isOpen ?? false); + }, + itemToString: (item) => (item ? item.label : ''), + }); const handleManage = () => { //TODO: implement manage handler @@ -103,13 +107,17 @@ export const UserSelect = ({ options, value }: UserSelectProps) => {
    {/* Input */}
    !dropdownOpen && openMenu()} className="cursor-pointer relative py-2 pl-2 pr-4 flex min-w-[200px] w-full items-center justify-between rounded-xl bg-surface-card shadow-sm" >
    Snowball Logo From ee397d0e6ec47ea95bb926c34c5be493115a073a Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 29 Feb 2024 09:30:29 +0700 Subject: [PATCH 08/12] =?UTF-8?q?=F0=9F=94=A7=20chore:=20add=20squigglylin?= =?UTF-8?q?e=20icon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/CustomIcon/SquigglyLine.tsx | 20 +++++++++++++++++++ .../src/components/shared/CustomIcon/index.ts | 1 + 2 files changed, 21 insertions(+) create mode 100644 packages/frontend/src/components/shared/CustomIcon/SquigglyLine.tsx diff --git a/packages/frontend/src/components/shared/CustomIcon/SquigglyLine.tsx b/packages/frontend/src/components/shared/CustomIcon/SquigglyLine.tsx new file mode 100644 index 00000000..cc309d7e --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/SquigglyLine.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const SquigglyLine: React.FC = (props) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/index.ts b/packages/frontend/src/components/shared/CustomIcon/index.ts index 59a6d8f2..7a0c856e 100644 --- a/packages/frontend/src/components/shared/CustomIcon/index.ts +++ b/packages/frontend/src/components/shared/CustomIcon/index.ts @@ -36,3 +36,4 @@ export * from './ClockIcon'; export * from './HorizontalDotIcon'; export * from './WarningDiamondIcon'; export * from './ArrowRightCircleFilledIcon'; +export * from './SquigglyLine'; From 91a80cac8a9850621be95a31bfee53a363745787 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 29 Feb 2024 09:30:53 +0700 Subject: [PATCH 09/12] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20add=20squigg?= =?UTF-8?q?ly=20line=20and=20personal=20TODO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/UserSelect/UserSelect.theme.ts | 3 +- .../shared/UserSelect/UserSelect.tsx | 93 +++++++++++-------- 2 files changed, 57 insertions(+), 39 deletions(-) diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelect.theme.ts b/packages/frontend/src/components/shared/UserSelect/UserSelect.theme.ts index 7e17355e..bca34a1c 100644 --- a/packages/frontend/src/components/shared/UserSelect/UserSelect.theme.ts +++ b/packages/frontend/src/components/shared/UserSelect/UserSelect.theme.ts @@ -25,8 +25,6 @@ export const userSelectTheme = tv({ 'mt-12', 'z-20', 'absolute', - 'px-1', - 'py-1', 'flex-col', 'gap-0.5', 'min-w-full', @@ -39,6 +37,7 @@ export const userSelectTheme = tv({ 'border-gray-200', 'rounded-xl', ], + popoverItemWrapper: ['flex', 'flex-col', 'px-2', 'py-2', 'gap-1'], }, variants: { isOpen: { diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx index 07866570..f68214cd 100644 --- a/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx +++ b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx @@ -10,6 +10,7 @@ import { BuildingIcon, ChevronUpDown, SettingsSlidersIcon, + SquigglyLine, } from 'components/shared/CustomIcon'; import { cn } from 'utils/classnames'; import { UserSelectTheme, userSelectTheme } from './UserSelect.theme'; @@ -143,48 +144,66 @@ export const UserSelect = ({ options, value }: UserSelectProps) => { {...getMenuProps({ ref: popoverRef }, { suppressRefError: true })} id="popover" ref={popoverRef} - className={cn( - theme.popover({ isOpen }), - { - // Position the popover based on the dropdown position - 'top-[27.5%]': dropdownPosition === 'bottom', - 'bottom-[92.5%]': dropdownPosition === 'top', - }, - 'px-2 py-2', - )} + className={cn(theme.popover({ isOpen }), { + // Position the popover based on the dropdown position + 'top-[27.5%]': dropdownPosition === 'bottom', + 'bottom-[92.5%]': dropdownPosition === 'top', + })} > - {/* Settings header */} -
    -
    - -

    Other teams

    -
    -
    -

    Manage

    - +
    + {/* Settings header */} +
    +
    + +

    Other teams

    +
    +
    +

    Manage

    + +
    + + {/* Organization */} + {isOpen && options.length !== 0 ? ( + options.map((item, index) => ( + + )) + ) : ( + + )}
    - {/* Organization */} - {isOpen && options.length !== 0 ? ( - options.map((item, index) => ( - - )) - ) : ( - - )} + {/* Squiggly line */} + {/* //TODO:remove if personal dont exist */} +
    + +
    - {/* //TODO:Squiggly line */} - {/* //TODO:Personal */} +
    + {/* //TODO:Personal (replace options with Personal Options) */} + {isOpen && options.length !== 0 ? ( + options.map((item, index) => ( + + )) + ) : ( + + )} +
    ); From 638e31f7fe194359bad2803f14442158cfcccaf6 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 29 Feb 2024 13:58:22 +0700 Subject: [PATCH 10/12] =?UTF-8?q?=F0=9F=94=A7=20chore:=20use=20wavyBorder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/shared/UserSelect/UserSelect.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx index f68214cd..81ef7923 100644 --- a/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx +++ b/packages/frontend/src/components/shared/UserSelect/UserSelect.tsx @@ -6,15 +6,15 @@ import React, { } from 'react'; import { useNavigate } from 'react-router-dom'; import { useSelect } from 'downshift'; +import { UserSelectTheme, userSelectTheme } from './UserSelect.theme'; +import { EmptyUserSelectItem, UserSelectItem } from './UserSelectItem'; import { BuildingIcon, ChevronUpDown, SettingsSlidersIcon, - SquigglyLine, } from 'components/shared/CustomIcon'; +import { WavyBorder } from 'components/shared/WavyBorder'; import { cn } from 'utils/classnames'; -import { UserSelectTheme, userSelectTheme } from './UserSelect.theme'; -import { EmptyUserSelectItem, UserSelectItem } from './UserSelectItem'; export type UserSelectOption = { value: string; @@ -182,11 +182,9 @@ export const UserSelect = ({ options, value }: UserSelectProps) => { )}
    - {/* Squiggly line */} + {/* WavyBorder */} {/* //TODO:remove if personal dont exist */} -
    - -
    +
    {/* //TODO:Personal (replace options with Personal Options) */} From dfa38a4cba488d3a30f7bbb882a8ef3fe7a9b721 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 29 Feb 2024 13:58:45 +0700 Subject: [PATCH 11/12] =?UTF-8?q?=F0=9F=94=A7=20chore:=20remove=20useMemo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/UserSelect/UserSelectItem/UserSelectItem.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx index 861ca13f..4885d6c2 100644 --- a/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx +++ b/packages/frontend/src/components/shared/UserSelect/UserSelectItem/UserSelectItem.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, ComponentPropsWithoutRef, useMemo } from 'react'; +import React, { forwardRef, ComponentPropsWithoutRef } from 'react'; import { Overwrite, UseComboboxGetItemPropsReturnValue } from 'downshift'; import { userSelectItemTheme, @@ -34,11 +34,6 @@ const UserSelectItem = forwardRef( const { value, label, imgSrc = './logo.svg' } = option; - const renderLeftImage = useMemo( - () => {`${value}-logo`}, - [imgSrc, value], - ); - return (
  • ( className={theme.wrapper({ className, active: selected || hovered })} >
    - {renderLeftImage} + {`${value}-logo`}

    {label}

    {selected && } From 11aeda9453dc8b13489338c13023e145561b9fd7 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 29 Feb 2024 13:59:53 +0700 Subject: [PATCH 12/12] =?UTF-8?q?=F0=9F=94=A7=20chore:=20remove=20squiggly?= =?UTF-8?q?=20line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/CustomIcon/SquigglyLine.tsx | 20 ------------------- .../src/components/shared/CustomIcon/index.ts | 1 - 2 files changed, 21 deletions(-) delete mode 100644 packages/frontend/src/components/shared/CustomIcon/SquigglyLine.tsx diff --git a/packages/frontend/src/components/shared/CustomIcon/SquigglyLine.tsx b/packages/frontend/src/components/shared/CustomIcon/SquigglyLine.tsx deleted file mode 100644 index cc309d7e..00000000 --- a/packages/frontend/src/components/shared/CustomIcon/SquigglyLine.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import { CustomIcon, CustomIconProps } from './CustomIcon'; - -export const SquigglyLine: React.FC = (props) => { - return ( - - - - ); -}; diff --git a/packages/frontend/src/components/shared/CustomIcon/index.ts b/packages/frontend/src/components/shared/CustomIcon/index.ts index d62654dc..26a38f55 100644 --- a/packages/frontend/src/components/shared/CustomIcon/index.ts +++ b/packages/frontend/src/components/shared/CustomIcon/index.ts @@ -38,7 +38,6 @@ export * from './WarningDiamondIcon'; export * from './ArrowRightCircleIcon'; export * from './ClockOutlineIcon'; export * from './ArrowRightCircleFilledIcon'; -export * from './SquigglyLine'; // Templates export * from './templates';