|
1 | 1 | import { ReactNode } from 'react';
|
2 | 2 | import { cn } from '../cn';
|
| 3 | +import { UnionToIntersection } from '../types/utility'; |
| 4 | +import { Anchor, AnchorProps } from './anchor'; |
3 | 5 | import { Stud } from './stud';
|
4 | 6 |
|
5 |
| -export interface InfoCardProps extends React.HTMLAttributes<HTMLElement> { |
6 |
| - icon: ReactNode; |
7 |
| - heading: ReactNode; |
8 |
| - as?: 'div' | 'li'; |
| 7 | +// eslint-disable-next-line @typescript-eslint/no-namespace |
| 8 | +export declare namespace InfoCardProps { |
| 9 | + interface InfoCardBaseProps { |
| 10 | + icon: ReactNode; |
| 11 | + heading: ReactNode; |
| 12 | + scheme?: 'neutral' | 'green'; |
| 13 | + } |
| 14 | + |
| 15 | + interface InfoCardLinkProps extends InfoCardBaseProps, Omit<AnchorProps, 'as'> { |
| 16 | + href: AnchorProps['href']; |
| 17 | + } |
| 18 | + |
| 19 | + interface InfoCardInertProps extends InfoCardBaseProps, React.HTMLAttributes<HTMLElement> { |
| 20 | + as: 'div' | 'li'; |
| 21 | + } |
9 | 22 | }
|
10 | 23 |
|
| 24 | +export type InfoCardProps = InfoCardProps.InfoCardLinkProps | InfoCardProps.InfoCardInertProps; |
| 25 | + |
11 | 26 | export function InfoCard({
|
12 |
| - as: Root = 'div', |
13 | 27 | icon,
|
14 | 28 | heading,
|
15 | 29 | className,
|
16 | 30 | children,
|
| 31 | + scheme = 'neutral', |
17 | 32 | ...rest
|
18 | 33 | }: InfoCardProps) {
|
| 34 | + let Root: InfoCardProps.InfoCardInertProps['as'] | typeof Anchor; |
| 35 | + |
| 36 | + if ('href' in rest) { |
| 37 | + Root = Anchor; |
| 38 | + } else { |
| 39 | + Root = rest.as || 'div'; |
| 40 | + delete (rest as { as?: unknown }).as; |
| 41 | + } |
| 42 | + |
19 | 43 | return (
|
20 |
| - <Root className={cn('bg-beige-100 p-6 md:p-12', className)} {...rest}> |
| 44 | + <Root |
| 45 | + className={cn( |
| 46 | + 'p-6 md:p-12', |
| 47 | + scheme === 'neutral' && |
| 48 | + 'bg-beige-100 [--color-h:theme(colors.green.1000)] [--color-text:theme(colors.green.800)] [--hover-bg:theme(colors.beige.200)] dark:bg-neutral-900 dark:[--color-h:theme(colors.white)] dark:[--color-text:theme(colors.white)] dark:[--hover-bg:theme(colors.neutral.800)]', |
| 49 | + scheme === 'green' && |
| 50 | + 'bg-green-900 [--color-h:theme(colors.white)] [--color-text:theme(colors.white)] [--hover-bg:theme(colors.green.800)]', |
| 51 | + Root === Anchor && |
| 52 | + 'hive-focus block cursor-pointer duration-300 hover:bg-[--hover-bg] focus-visible:bg-[--hover-bg]', |
| 53 | + className, |
| 54 | + )} |
| 55 | + {...(rest as UnionToIntersection<InfoCardProps>)} |
| 56 | + > |
21 | 57 | <Stud>{icon}</Stud>
|
22 |
| - <h3 className="mt-4 text-xl font-medium leading-[1.4] text-green-1000 md:mt-6">{heading}</h3> |
23 |
| - <div className="mt-2 space-y-2 text-green-800 md:mt-4">{children}</div> |
| 58 | + <h3 className="mt-4 text-xl font-medium leading-[1.4] text-[--color-h] md:mt-6">{heading}</h3> |
| 59 | + <div className="mt-2 space-y-2 text-[--color-text] md:mt-4">{children}</div> |
24 | 60 | </Root>
|
25 | 61 | );
|
26 | 62 | }
|
0 commit comments