Skip to content

Commit 7f88b45

Browse files
authoredFeb 18, 2025··
Expose scheme and href props from InfoCard (#2045)
1 parent 2c777e7 commit 7f88b45

File tree

5 files changed

+76
-16
lines changed

5 files changed

+76
-16
lines changed
 

‎.changeset/eight-meals-change.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@theguild/components': minor
3+
---
4+
5+
Expose `href` and `scheme` props from InfoCard

‎packages/components/src/components/info-card.stories.tsx

+19-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,17 @@ export default {
77
title: 'Components/InfoCard',
88
component: InfoCard,
99
decorators: [hiveThemeDecorator],
10+
argTypes: {
11+
scheme: {
12+
control: {
13+
type: 'select',
14+
},
15+
options: ['neutral', 'green'],
16+
},
17+
},
1018
} satisfies Meta<InfoCardProps>;
1119

12-
export const Default: StoryObj<InfoCardProps> = {
20+
export const Default: StoryObj<InfoCardProps.InfoCardInertProps> = {
1321
args: {
1422
icon: <AccountBox />,
1523
as: 'div',
@@ -18,3 +26,13 @@ export const Default: StoryObj<InfoCardProps> = {
1826
'Control user access with detailed, role-based permissions for enhanced security and flexibility.',
1927
},
2028
};
29+
30+
export const Link: StoryObj<InfoCardProps.InfoCardLinkProps> = {
31+
args: {
32+
icon: <AccountBox />,
33+
href: '#',
34+
heading: 'Customizable User Roles and Permissions',
35+
children:
36+
'Control user access with detailed, role-based permissions for enhanced security and flexibility.',
37+
},
38+
};
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,62 @@
11
import { ReactNode } from 'react';
22
import { cn } from '../cn';
3+
import { UnionToIntersection } from '../types/utility';
4+
import { Anchor, AnchorProps } from './anchor';
35
import { Stud } from './stud';
46

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+
}
922
}
1023

24+
export type InfoCardProps = InfoCardProps.InfoCardLinkProps | InfoCardProps.InfoCardInertProps;
25+
1126
export function InfoCard({
12-
as: Root = 'div',
1327
icon,
1428
heading,
1529
className,
1630
children,
31+
scheme = 'neutral',
1732
...rest
1833
}: 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+
1943
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+
>
2157
<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>
2460
</Root>
2561
);
2662
}

‎packages/components/src/next-types.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { UnionToIntersection } from './types/utility';
2+
13
/**
24
* Next.js page props type.
35
* @see https://nextjs.org/docs/app/api-reference/file-conventions/page#props
@@ -18,10 +20,3 @@ export interface NextPageProps<
1820
>;
1921
searchParams: Promise<{ [K in TSearchParams]?: string | string[] }>;
2022
}
21-
22-
type Prettify<T> = { [K in keyof T]: T[K] } & {};
23-
24-
type UnionToIntersection<T> = Prettify<
25-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
26-
(T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never
27-
>;
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export type Prettify<T> = { [K in keyof T]: T[K] } & {};
2+
3+
export type UnionToIntersection<T> = Prettify<
4+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5+
(T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never
6+
>;

0 commit comments

Comments
 (0)
Please sign in to comment.