-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
148 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@theguild/components': minor | ||
--- | ||
|
||
Add ProductCard |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...s-and-libraries-cards/hive-decoration.svg → ...mponents/product-card/hive-decoration.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion
2
...braries-cards/hive-gateway-decoration.svg → .../product-card/hive-gateway-decoration.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { cn } from '../../cn'; | ||
import { FOUR_MAIN_PRODUCTS, ProductInfo, PRODUCTS } from '../../products'; | ||
import { HighlightDecoration } from '../decorations'; | ||
import { ArrowIcon } from '../icons'; | ||
import { ReactComponent as HiveDecoration } from './hive-decoration.svg'; | ||
import { ReactComponent as HiveGatewayDecoration } from './hive-gateway-decoration.svg'; | ||
import { ReactComponent as MeshDecoration } from './mesh-decoration.svg'; | ||
import { ReactComponent as YogaDecoration } from './yoga-decoration.svg'; | ||
|
||
const cardDecorations = { | ||
[PRODUCTS.HIVE.name]: HiveDecoration, | ||
[PRODUCTS.YOGA.name]: YogaDecoration, | ||
[PRODUCTS.MESH.name]: MeshDecoration, | ||
[PRODUCTS.HIVE_GATEWAY.name]: HiveGatewayDecoration, | ||
}; | ||
|
||
export function MainProductCard({ as: Root, product, className, ...rest }: ProductCardProps) { | ||
const Decoration = cardDecorations[product.name]; | ||
const Icon = product.logo; | ||
|
||
const isHive = product.name === PRODUCTS.HIVE.name; | ||
|
||
return ( | ||
<Root | ||
className={cn( | ||
'hive-focus-within group relative flex-1 shrink-0 basis-[283.5px] overflow-hidden rounded-2xl bg-blue-400 text-green-1000 max-md:w-[283.5px]', | ||
isHive && 'bg-green-1000 text-white', | ||
className, | ||
)} | ||
{...rest} | ||
> | ||
<a | ||
className="relative z-10 flex h-full flex-1 flex-col justify-between p-8 outline-none focus-visible:outline-none" | ||
href={product.href} | ||
> | ||
<p className="font-medium">{product.name}</p> | ||
<Icon className="mt-8" /> | ||
<ArrowIcon className="absolute bottom-8 right-8" /> | ||
</a> | ||
<Decoration | ||
strokeWidth="0.5px" | ||
className={cn( | ||
'pointer-events-none absolute bottom-0 right-0 h-full fill-blue-200 opacity-0 transition-opacity duration-500 group-focus-within:opacity-100 group-hover:opacity-100', | ||
isHive && 'fill-blue-700', | ||
)} | ||
preserveAspectRatio="xMidYMid meet" | ||
/> | ||
<HighlightDecoration className="pointer-events-none absolute left-0 top-[-15%] h-[150%] w-full opacity-0 transition-opacity duration-1000 group-focus-within:opacity-100 group-hover:opacity-100" /> | ||
</Root> | ||
); | ||
} | ||
|
||
export function AncillaryProductCard({ product, as: Root, className, ...rest }: ProductCardProps) { | ||
const Logo = product.logo; | ||
return ( | ||
<Root | ||
className={cn( | ||
'hive-focus-within shrink-0 basis-[283.5px] rounded-2xl bg-beige-200 text-green-1000 transition-colors duration-500 hover:bg-beige-400 max-sm:min-w-[283.5px]', | ||
className, | ||
)} | ||
{...rest} | ||
> | ||
<a | ||
href={product.href} | ||
className="relative flex h-full flex-col justify-between rounded-[inherit] p-8 focus:outline-none focus-visible:outline-none" | ||
> | ||
<div> | ||
<p className="font-medium">{product.name}</p> | ||
<p className="mt-2 text-sm text-green-800">{product.title}</p> | ||
</div> | ||
<div | ||
role="presentation" | ||
className="mt-8 flex size-8 items-center justify-center rounded bg-green-1000 p-[5px] text-sm/5 font-medium text-white" | ||
> | ||
<Logo /> | ||
</div> | ||
<ArrowIcon className="absolute bottom-8 right-8" /> | ||
</a> | ||
</Root> | ||
); | ||
} | ||
|
||
export interface ProductCardProps extends React.HTMLAttributes<HTMLElement> { | ||
as: 'div' | 'li'; | ||
product: ProductInfo; | ||
} | ||
|
||
export function ProductCard(props: ProductCardProps) { | ||
const isMainProduct = FOUR_MAIN_PRODUCTS.some(p => p.name === props.product.name); | ||
|
||
return isMainProduct ? <MainProductCard {...props} /> : <AncillaryProductCard {...props} />; | ||
} |
2 changes: 1 addition & 1 deletion
2
...s-and-libraries-cards/mesh-decoration.svg → ...mponents/product-card/mesh-decoration.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions
31
packages/components/src/components/product-card/product-card.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Meta, StoryObj } from '@storybook/react'; | ||
import { hiveThemeDecorator } from '../../../../../.storybook/hive-theme-decorator'; | ||
import { PRODUCTS } from '../../products'; | ||
import { ProductCard } from './index'; | ||
|
||
export default { | ||
title: 'Hive/ProductCard', | ||
component: ProductCard, | ||
decorators: [hiveThemeDecorator], | ||
parameters: { | ||
forcedLightMode: true, | ||
}, | ||
} satisfies Meta; | ||
|
||
// interweaved to make sure main product cards look good alongside ancillary product cards | ||
const productsLexicographically = Object.values(PRODUCTS).sort((a, b) => | ||
a.name.localeCompare(b.name), | ||
); | ||
|
||
export const Default: StoryObj<typeof ProductCard> = { | ||
name: 'ProductCard', | ||
render() { | ||
return ( | ||
<ul className="mt-5 grid grid-cols-4 gap-5 overflow-x-auto p-4 last-of-type:mb-24"> | ||
{productsLexicographically.map(product => ( | ||
<ProductCard as="li" key={product.name} product={product} /> | ||
))} | ||
</ul> | ||
); | ||
}, | ||
}; |
2 changes: 1 addition & 1 deletion
2
...s-and-libraries-cards/yoga-decoration.svg → ...mponents/product-card/yoga-decoration.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters