NavigationIconButton.tsx52 lines · main
| 1 | import { ComponentProps, forwardRef, ReactNode } from 'react' |
| 2 | import { Button, cn } from 'ui' |
| 3 | |
| 4 | export const NavigationIconButton = forwardRef< |
| 5 | HTMLButtonElement, |
| 6 | Omit< |
| 7 | ComponentProps<typeof Button>, |
| 8 | // omit other icon props to avoid confusion |
| 9 | // using `icon` instead as there is only 1 use case for this component |
| 10 | 'iconRight' | 'iconLeft' |
| 11 | > & { |
| 12 | rightText?: ReactNode |
| 13 | } |
| 14 | >(({ icon, rightText, ...props }, ref) => { |
| 15 | return ( |
| 16 | <Button |
| 17 | ref={ref} |
| 18 | type="text" |
| 19 | size="tiny" |
| 20 | {...props} |
| 21 | className={cn( |
| 22 | 'h-10 [&>span]:relative [&>span]:items-center [&>span]:gap-3 [&>span]:flex [&>span]:w-full [&>span]:h-full p-0', |
| 23 | props.className |
| 24 | )} |
| 25 | > |
| 26 | <div className="absolute left-2 text-foreground-lighter">{icon}</div> |
| 27 | <span |
| 28 | className={cn( |
| 29 | 'absolute left-10 md:left-7 md:group-data-[state=expanded]:left-10', |
| 30 | 'opacity-100 md:opacity-0 md:group-data-[state=expanded]:opacity-100', |
| 31 | 'w-40 text-sm flex flex-col items-center', |
| 32 | 'transition-all' |
| 33 | )} |
| 34 | > |
| 35 | <span className="w-full text-left text-foreground-light truncate">{props.children}</span> |
| 36 | </span> |
| 37 | {rightText && ( |
| 38 | <div |
| 39 | className={cn( |
| 40 | 'absolute right-2 flex items-center', |
| 41 | 'opacity-100 md:opacity-0 transition-all', |
| 42 | 'md:group-data-[state=expanded]:opacity-100 ' |
| 43 | )} |
| 44 | > |
| 45 | {rightText} |
| 46 | </div> |
| 47 | )} |
| 48 | </Button> |
| 49 | ) |
| 50 | }) |
| 51 | |
| 52 | NavigationIconButton.displayName = 'NavigationIconButton' |