Skip to content
This repository has been archived by the owner on Jul 17, 2024. It is now read-only.

Commit

Permalink
refactor/button: add variant for dropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
9ssi7 committed Mar 24, 2024
1 parent 5206d84 commit 3a4397a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@turistikrota/ui",
"version": "1.4.0",
"version": "1.4.1",
"description": "the turistikrota ui library for React",
"main": "./index.js",
"module": "./index.js",
Expand Down
46 changes: 38 additions & 8 deletions packages/ui/src/dropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,60 @@ type PropsWithActive<P = any> = P & {
active?: boolean
}

type DropdownVariant = 'primary' | 'secondary'

type DropdownContext = {
active: boolean
variant: DropdownVariant
setActive: React.Dispatch<React.SetStateAction<boolean>>
}

type DropdownType = React.FC<React.PropsWithChildren> & {
type DropdownType = React.FC<
React.PropsWithChildren<{
variant?: DropdownVariant
}>
> & {
Button: React.FC<React.PropsWithChildren<PropsWithActive>>
Overlay: React.FC<React.PropsWithChildren>
OverlayItem: React.FC<React.PropsWithChildren<PropsWithActive<OverlayItemProps>>>
}

type DropdownVariantMap = {
button: string
overlay: string
inactiveItem: string
}

const variantMap: Record<DropdownVariant, DropdownVariantMap> = {
primary: {
button: 'bg-default',
inactiveItem: 'hover:bg-second',
overlay: 'bg-default',
},
secondary: {
button: 'bg-second',
inactiveItem: 'hover:bg-default',
overlay: 'bg-second',
},
}

const Context = React.createContext<DropdownContext>({
active: false,
variant: 'primary',
setActive: () => {},
})

const Button: React.FC<React.PropsWithChildren<PropsWithActive>> = ({ active, children }) => {
const { active: activeContext, setActive } = useContext(Context)
const { active: activeContext, setActive, variant } = useContext(Context)
const debouncedBlur = debounce((activeContext) => {
if (activeContext) setActive(false)
}, 200)
return (
<button
type='button'
className={`bg-default group peer inline-flex w-full items-center justify-center rounded-md border p-2 text-sm font-medium transition-colors focus:outline-none focus:ring-0 focus:ring-transparent focus-visible:outline-none
className={`group peer inline-flex w-full items-center justify-center rounded-md border p-2 text-sm font-medium transition-colors focus:outline-none focus:ring-0 focus:ring-transparent focus-visible:outline-none
${active ? 'text-primary' : 'text-gray-700 dark:text-gray-300'}
${variantMap[variant].button}
`}
onClick={() => setActive(!activeContext)}
onBlur={() => debouncedBlur(activeContext)}
Expand All @@ -52,12 +80,13 @@ const Button: React.FC<React.PropsWithChildren<PropsWithActive>> = ({ active, ch
}

const Overlay: React.FC<React.PropsWithChildren> = ({ children }) => {
const { active } = useContext(Context)
const { active, variant } = useContext(Context)
return (
<div
className={`
bg-default absolute right-0 z-10 mt-2 w-40 origin-top-right rounded-md border p-2 ring-0 transition-opacity
absolute right-0 z-10 mt-2 w-40 origin-top-right rounded-md border p-2 ring-0 transition-opacity
${active ? 'visible opacity-100' : 'invisible opacity-0'}
${variantMap[variant].overlay}
`}
>
<div className='space-y-1' role='menu' aria-orientation='vertical' aria-labelledby='options-menu'>
Expand All @@ -72,13 +101,14 @@ const OverlayItem: React.FC<React.PropsWithChildren<PropsWithActive<OverlayItemP
children,
onClick,
}) => {
const { variant } = useContext(Context)
return (
<a
href='#'
className={`flex items-center justify-between rounded-md p-2 text-sm transition-colors ${
active
? 'text-primary bg-primary-200 dark:bg-primary-700 cursor-auto bg-opacity-10 dark:bg-opacity-10'
: 'hover:bg-second text-gray-700 dark:text-gray-300'
: `${variantMap[variant].inactiveItem} text-gray-700 dark:text-gray-300`
}`}
role='menuitem'
onClick={onClick}
Expand All @@ -89,10 +119,10 @@ const OverlayItem: React.FC<React.PropsWithChildren<PropsWithActive<OverlayItemP
)
}

const Dropdown: DropdownType = ({ children }) => {
const Dropdown: DropdownType = ({ children, variant = 'primary' }) => {
const [active, setActive] = useState(false)
return (
<Context.Provider value={{ active, setActive }}>
<Context.Provider value={{ active, setActive, variant }}>
<div className='relative hidden lg:block'>{children}</div>
</Context.Provider>
)
Expand Down

0 comments on commit 3a4397a

Please sign in to comment.