mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat(card): structure improved
This commit is contained in:
parent
f5b3c788e4
commit
0eaf34994a
@ -1,7 +1,6 @@
|
||||
import {forwardRef, HTMLNextUIProps} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {clsx} from "@nextui-org/shared-utils";
|
||||
import {filterDOMProps} from "@react-aria/utils";
|
||||
|
||||
import {useCardContext} from "./card-context";
|
||||
|
||||
@ -16,11 +15,7 @@ const CardBody = forwardRef<HTMLNextUIProps, "div">((props, ref) => {
|
||||
const bodyStyles = clsx(styles?.body, className);
|
||||
|
||||
return (
|
||||
<Component
|
||||
ref={domRef}
|
||||
className={slots.body?.({class: bodyStyles})}
|
||||
{...filterDOMProps(otherProps, {labelable: true})}
|
||||
>
|
||||
<Component ref={domRef} className={slots.body?.({class: bodyStyles})} {...otherProps}>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import {forwardRef, HTMLNextUIProps} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {clsx} from "@nextui-org/shared-utils";
|
||||
import {filterDOMProps} from "@react-aria/utils";
|
||||
|
||||
import {useCardContext} from "./card-context";
|
||||
|
||||
@ -22,11 +21,7 @@ const CardFooter = forwardRef<CardFooterProps, "div">((props, ref) => {
|
||||
});
|
||||
|
||||
return (
|
||||
<Component
|
||||
ref={domRef}
|
||||
className={slots.footer?.({class: footerStyles})}
|
||||
{...filterDOMProps(otherProps, {labelable: true})}
|
||||
>
|
||||
<Component ref={domRef} className={slots.footer?.({class: footerStyles})} {...otherProps}>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import {forwardRef, HTMLNextUIProps} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {clsx} from "@nextui-org/shared-utils";
|
||||
import {filterDOMProps} from "@react-aria/utils";
|
||||
|
||||
import {useCardContext} from "./card-context";
|
||||
|
||||
@ -17,11 +16,7 @@ const CardHeader = forwardRef<HTMLNextUIProps, "div">((props, ref) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Component
|
||||
ref={domRef}
|
||||
className={slots.header?.({class: headerStyles})}
|
||||
{...filterDOMProps(otherProps, {labelable: true})}
|
||||
>
|
||||
<Component ref={domRef} className={slots.header?.({class: headerStyles})} {...otherProps}>
|
||||
{children}
|
||||
</Component>
|
||||
</>
|
||||
|
||||
@ -3,7 +3,7 @@ import type {SlotsToClasses, CardSlots, CardReturnType, CardVariantProps} from "
|
||||
|
||||
import {card} from "@nextui-org/theme";
|
||||
import {MouseEvent, useCallback, useMemo} from "react";
|
||||
import {filterDOMProps, mergeProps} from "@react-aria/utils";
|
||||
import {mergeProps} from "@react-aria/utils";
|
||||
import {useFocusRing} from "@react-aria/focus";
|
||||
import {useHover} from "@react-aria/interactions";
|
||||
import {useButton as useAriaButton} from "@react-aria/button";
|
||||
@ -51,8 +51,8 @@ export type UseCardProps = Props & PressEvents & FocusableProps & CardVariantPro
|
||||
export type ContextType = {
|
||||
slots: CardReturnType;
|
||||
styles?: SlotsToClasses<CardSlots>;
|
||||
variant?: CardVariantProps["variant"];
|
||||
isDisabled?: CardVariantProps["isDisabled"];
|
||||
isBordered?: CardVariantProps["isBordered"];
|
||||
isFooterBlurred?: CardVariantProps["isFooterBlurred"];
|
||||
disableAnimation?: CardVariantProps["disableAnimation"];
|
||||
fullWidth?: CardVariantProps["fullWidth"];
|
||||
@ -120,7 +120,7 @@ export function useCard(originalProps: UseCardProps) {
|
||||
|
||||
const context = useMemo<ContextType>(
|
||||
() => ({
|
||||
variant: originalProps.variant,
|
||||
isBordered: originalProps.isBordered,
|
||||
isDisabled: originalProps.isDisabled,
|
||||
isFooterBlurred: originalProps.isFooterBlurred,
|
||||
disableAnimation: originalProps.disableAnimation,
|
||||
@ -131,7 +131,7 @@ export function useCard(originalProps: UseCardProps) {
|
||||
[
|
||||
slots,
|
||||
styles,
|
||||
originalProps.variant,
|
||||
originalProps.isBordered,
|
||||
originalProps.isDisabled,
|
||||
originalProps.isFooterBlurred,
|
||||
originalProps.disableAnimation,
|
||||
@ -153,8 +153,8 @@ export function useCard(originalProps: UseCardProps) {
|
||||
...mergeProps(
|
||||
originalProps.isPressable ? {...buttonProps, ...focusProps} : {},
|
||||
originalProps.isHoverable ? hoverProps : {},
|
||||
filterDOMProps(otherProps, {labelable: true}),
|
||||
filterDOMProps(props, {labelable: true}),
|
||||
otherProps,
|
||||
props,
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
@ -1,33 +1,36 @@
|
||||
import React from "react";
|
||||
import {ComponentMeta, ComponentStory} from "@storybook/react";
|
||||
import {Link} from "@nextui-org/link";
|
||||
import {Code} from "@nextui-org/code";
|
||||
import {styled} from "@nextui-org/system";
|
||||
import {ComponentStory, ComponentMeta} from "@storybook/react";
|
||||
import {card} from "@nextui-org/theme";
|
||||
|
||||
import {Card, CardProps} from "../src";
|
||||
import {Card, CardBody, CardProps} from "../src";
|
||||
|
||||
export default {
|
||||
title: "General/Card",
|
||||
title: "Components/Card",
|
||||
component: Card,
|
||||
argTypes: {
|
||||
variant: {
|
||||
shadow: {
|
||||
control: {
|
||||
type: "radio",
|
||||
options: ["shadow", "bordered", "flat"],
|
||||
type: "select",
|
||||
options: ["none", "sm", "md", "lg", "xl", "2xl", "inner"],
|
||||
},
|
||||
},
|
||||
borderWeight: {
|
||||
radius: {
|
||||
control: {
|
||||
type: "radio",
|
||||
options: ["light", "normal", "bold", "extrabold", "black"],
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "2xl", "3xl", "full"],
|
||||
},
|
||||
},
|
||||
isPressable: {
|
||||
isBordered: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
disableAnimation: {
|
||||
fullWidth: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
isFooterBlurred: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
@ -37,520 +40,50 @@ export default {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
isPressable: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
isDisabled: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
disableRipple: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
disableAnimation: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div className="flex items-center justify-center w-screen h-screen">
|
||||
<div className="max-w-md w-full">
|
||||
<Story />
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
],
|
||||
} as ComponentMeta<typeof Card>;
|
||||
|
||||
const defaultProps = {
|
||||
...card.defaultVariants,
|
||||
disableRipple: false,
|
||||
};
|
||||
|
||||
const Template: ComponentStory<typeof Card> = (args: CardProps) => (
|
||||
<Card {...args} className="max-w-[50%]">
|
||||
<Card.Body>A basic card</Card.Body>
|
||||
<Card {...args}>
|
||||
<CardBody>A basic card</CardBody>
|
||||
</Card>
|
||||
);
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
variant: "shadow",
|
||||
...defaultProps,
|
||||
};
|
||||
|
||||
export const Hoverable = Template.bind({});
|
||||
Hoverable.args = {
|
||||
variant: "bordered",
|
||||
isHoverable: true,
|
||||
};
|
||||
|
||||
export const Variants = () => (
|
||||
<div className="container flex gap-2">
|
||||
<div className="w-4/12">
|
||||
<Card>
|
||||
<Card.Body>
|
||||
<p>Default card. (shadow)</p>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="w-4/12">
|
||||
<Card variant="flat">
|
||||
<Card.Body>
|
||||
<p>Flat card.</p>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="w-4/12">
|
||||
<Card variant="bordered">
|
||||
<Card.Body>
|
||||
<p>Bordered card.</p>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const WithFooter = () => (
|
||||
<Card className="p-3 max-w-[400px]">
|
||||
<Card.Header>
|
||||
<img
|
||||
alt="nextui logo"
|
||||
height="34px"
|
||||
src="https://avatars.githubusercontent.com/u/86160567?s=200&v=4"
|
||||
width="34px"
|
||||
/>
|
||||
<div className="flex flex-col pl-3">
|
||||
<h4 className="pb-2">Next UI</h4>
|
||||
<p>nextui.org</p>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Body className="py-2">
|
||||
<p>Make beautiful websites regardless of your design experience.</p>
|
||||
</Card.Body>
|
||||
<Card.Footer>
|
||||
<Link isExternal color="primary" href="https://github.com/nextui-org/nextui" target="_blank">
|
||||
Visit source code on GitHub.
|
||||
</Link>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
);
|
||||
|
||||
export const AbsImageWithHeader = () => {
|
||||
return (
|
||||
<div className="flex justify-center gap-2">
|
||||
<Card className="w-[330px]">
|
||||
<Card.Header className="absolute top-5 z-10">
|
||||
<div className="grid-cols-2">
|
||||
<p className="text-white/75 text-sm uppercase font-bold">What to watch</p>
|
||||
<h3 className="text-white text-xl">Stream the Apple event</h3>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Apple event background"
|
||||
autoResize={false}
|
||||
height={440}
|
||||
src={require("./assets/apple-event.jpeg")}
|
||||
style={{objectFit: "cover"}}
|
||||
width="100%"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const AbsImgWithHeaderFooter = () => {
|
||||
return (
|
||||
<div className="flex justify-center items-start gap-2">
|
||||
<Card className="w-[330px] bg-neutral-100">
|
||||
<Card.Header className="absolute top-5 z-10">
|
||||
<div className="flex flex-col">
|
||||
<p className="text-xs text-neutral-400 upper font-bold">New</p>
|
||||
<h2 className="text-lg text-black">HomePod mini</h2>
|
||||
<p className="text-xs text-foreground pr-1.5">
|
||||
Room-filling sound, Intelligent assistant. Smart home control. Works seamlessly with
|
||||
iPhone. Check it out
|
||||
</p>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Apple homedpods background"
|
||||
autoResize={false}
|
||||
height={440}
|
||||
src={require("./assets/homepod.jpeg")}
|
||||
style={{objectFit: "cover", paddingTop: "100px"}}
|
||||
width="100%"
|
||||
/>
|
||||
<Card.Footer className="justify-between">
|
||||
<div>
|
||||
<p className="text-xs">Available soon.</p>
|
||||
<p className="text-xs">Get notified.</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex flex-wrap justify-end">
|
||||
<p className="text-xs upper font-bold">Notify Me</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
<Card className="w-[630px]">
|
||||
<Card.Header className="absolute top-5 z-10">
|
||||
<div className="flex flex-col">
|
||||
<p className="text-neutral-300 upper font-bold">Your day your way</p>
|
||||
<h3 className="text-white text-xl">Your checklist for better sleep</h3>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Apple homedpods background"
|
||||
autoResize={false}
|
||||
height={440}
|
||||
src={require("./assets/relaxing.jpeg")}
|
||||
style={{objectFit: "cover"}}
|
||||
width="100%"
|
||||
/>
|
||||
<Card.Footer isBlurred className="absolute bottom-0 z-10 border-t border-border-dark">
|
||||
<div className="flex flex-grow items-start">
|
||||
<div className="w-[40px] mr-2">
|
||||
<Card.Image
|
||||
alt="Breathing app icon"
|
||||
autoResize={false}
|
||||
height={40}
|
||||
src={require("./assets/breathing-app-icon.jpeg")}
|
||||
style={{background: "black"}}
|
||||
width={40}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<p className="text-xs text-neutral-400">Breathing App</p>
|
||||
<p className="text-xs text-neutral-400">Get a good night's sleep.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-white upper font-bold">Get App</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const CoverImage = () => (
|
||||
<div className="gap-2 grid grid-cols-12">
|
||||
<div className="col-span-12 sm:col-span-4">
|
||||
<Card>
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">What to watch</p>
|
||||
<h4 className="text-white font-medium text-lg">Stream the Acme event</h4>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Card image background"
|
||||
height={340}
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-4.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-4">
|
||||
<Card>
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">Plant a tree</p>
|
||||
<h4 className="text-white font-medium text-lg">Contribute to the planet</h4>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Card image background"
|
||||
height={340}
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-3.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-4">
|
||||
<Card className="bg-black">
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">Supercharged</p>
|
||||
<h4 className="text-white font-medium text-lg">Creates beauty like a beast</h4>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Card image background"
|
||||
height={340}
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-2.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-5">
|
||||
<Card className="w-full h-[400px]">
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">New</p>
|
||||
<h3 className="text-black font-medium text-2xl">Acme camera</h3>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Card example background"
|
||||
height="100%"
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-6.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
<Card.Footer
|
||||
isBlurred
|
||||
className="absolute bg-white/50 bottom-0 border-t border-border-dark z-10"
|
||||
>
|
||||
<div>
|
||||
<p className="text-black text-xs">Available soon.</p>
|
||||
<p className="text-black text-xs">Get notified.</p>
|
||||
</div>
|
||||
<p className="text-xs upper font-bold text-inherit ml-auto">Notify Me</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-7">
|
||||
<Card className="w-full h-[400px]">
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">Your day your way</p>
|
||||
<h3 className="text-white font-medium text-2xl">Your checklist for better sleep</h3>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Relaxing app background"
|
||||
height="100%"
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-5.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
<Card.Footer
|
||||
isBlurred
|
||||
className="absolute bottom-0 z-10 bg-black/50 border-t border-border-dark"
|
||||
>
|
||||
<div className="flex flex-grow items-center">
|
||||
<div className="w-[40px] mr-2">
|
||||
<Card.Image
|
||||
alt="Breathing app icon"
|
||||
autoResize={false}
|
||||
height={40}
|
||||
src={require("./assets/breathing-app-icon.jpeg")}
|
||||
style={{background: "black"}}
|
||||
width={40}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<p className="text-xs text-neutral-400">Breathing App</p>
|
||||
<p className="text-xs text-neutral-400">Get a good night's sleep.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-white upper font-bold">Get App</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const PrimaryAction = () => {
|
||||
const list = [
|
||||
{
|
||||
title: "Orange",
|
||||
img: "/images/fruit-1.jpeg",
|
||||
price: "$5.50",
|
||||
},
|
||||
{
|
||||
title: "Tangerine",
|
||||
img: "/images/fruit-2.jpeg",
|
||||
price: "$3.00",
|
||||
},
|
||||
{
|
||||
title: "Raspberry",
|
||||
img: "/images/fruit-3.jpeg",
|
||||
price: "$10.00",
|
||||
},
|
||||
{
|
||||
title: "Lemon",
|
||||
img: "/images/fruit-4.jpeg",
|
||||
price: "$5.30",
|
||||
},
|
||||
{
|
||||
title: "Advocato",
|
||||
img: "/images/fruit-5.jpeg",
|
||||
price: "$15.70",
|
||||
},
|
||||
{
|
||||
title: "Lemon 2",
|
||||
img: "/images/fruit-6.jpeg",
|
||||
price: "$8.00",
|
||||
},
|
||||
{
|
||||
title: "Banana",
|
||||
img: "/images/fruit-7.jpeg",
|
||||
price: "$7.50",
|
||||
},
|
||||
{
|
||||
title: "Watermelon",
|
||||
img: "/images/fruit-8.jpeg",
|
||||
price: "$12.20",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="gap-2 grid grid-cols-2 sm:grid-cols-4">
|
||||
{list.map((item, index) => (
|
||||
// eslint-disable-next-line no-console
|
||||
<Card key={index} isPressable onPress={() => console.log("item pressed", item)}>
|
||||
<Card.Body className="!p-0">
|
||||
<Card.Image
|
||||
alt={item.title}
|
||||
height={140}
|
||||
src={"https://nextui.org" + item.img}
|
||||
style={{objectFit: "cover"}}
|
||||
width="100%"
|
||||
/>
|
||||
</Card.Body>
|
||||
<Card.Footer className="justify-between">
|
||||
<strong>{item.title}</strong>
|
||||
<p className="font-medium text-neutral-500">{item.price}</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const CenterImgWithHeader = () => {
|
||||
const list = [
|
||||
{
|
||||
title: "Mac",
|
||||
img: require("./assets/mac.png"),
|
||||
},
|
||||
{
|
||||
title: "iPhone",
|
||||
img: require("./assets/iphone.png"),
|
||||
},
|
||||
{
|
||||
title: "iPad",
|
||||
img: require("./assets/ipad.png"),
|
||||
},
|
||||
{
|
||||
title: "Apple Watch",
|
||||
img: require("./assets/apple-watch.png"),
|
||||
},
|
||||
{
|
||||
title: "AirPods",
|
||||
img: require("./assets/airpods.png"),
|
||||
},
|
||||
{
|
||||
title: "AirTag",
|
||||
img: require("./assets/airtag.png"),
|
||||
},
|
||||
{
|
||||
title: "Apple TV",
|
||||
img: require("./assets/appletv.png"),
|
||||
},
|
||||
{
|
||||
title: "HomePod mini",
|
||||
img: require("./assets/homepod-mini.png"),
|
||||
},
|
||||
{
|
||||
title: "Accessories",
|
||||
img: require("./assets/accessories.png"),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 justify-center flex-wrap">
|
||||
{list.map((item, index) => (
|
||||
<div key={index}>
|
||||
<Card isHoverable isPressable className="w-[200px] h-[200px]">
|
||||
<Card.Header className="!p-0">
|
||||
<h5 className="pl-6 pt-2.5">{item.title}</h5>
|
||||
</Card.Header>
|
||||
<Card.Body className="h-full justify-center">
|
||||
<Card.Image alt={item.title} autoResize={false} src={item.img} width={180} />
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const WithDivider = () => (
|
||||
<Card className="w-max-[400px]" variant="bordered">
|
||||
<Card.Header className="border-b border-border dark:border-border-dark">
|
||||
<strong>Description</strong>
|
||||
</Card.Header>
|
||||
<Card.Body>
|
||||
<p>The Object constructor creates an object wrapper for the given value.</p>
|
||||
</Card.Body>
|
||||
<Card.Footer className="border-t border-border dark:border-border-dark">
|
||||
<p>
|
||||
When called in a non-constructor context, Object behaves identically to{" "}
|
||||
<Code>new Object()</Code>.
|
||||
</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
);
|
||||
|
||||
export const Shadows = () => {
|
||||
const Box = styled("div", {
|
||||
size: "120px",
|
||||
dflex: "center",
|
||||
bg: "$backgroundContrast",
|
||||
br: "$md",
|
||||
});
|
||||
|
||||
const shadows = ["$xs", "$sm", "$md", "$lg", "$xl"];
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 sm:grid-cols-5 gap-2 justify-center">
|
||||
<div className="flex justify-center col-span-2 sm:col-span-5">
|
||||
<strong>Drop shadows</strong>
|
||||
</div>
|
||||
{shadows.map((shadow, index) => (
|
||||
<div key={`${shadow}_${index}`}>
|
||||
<Box css={{dropShadow: shadow}}>
|
||||
<p>Shadow: {shadow}</p>
|
||||
</Box>
|
||||
</div>
|
||||
))}
|
||||
<div className="flex justify-center col-span-2 sm:col-span-5">
|
||||
<strong>Box shadows</strong>
|
||||
</div>
|
||||
{shadows.map((shadow, index) => (
|
||||
<div key={`${shadow}_${index}`}>
|
||||
<Box css={{boxShadow: shadow}}>
|
||||
<p>Shadow: {shadow}</p>
|
||||
</Box>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
//TODO: Input & Button still missing
|
||||
// export const withForm = () => {
|
||||
// return (
|
||||
// <Card css={{mw: "400px"}}>
|
||||
// <Card.Header css={{justifyContent: "center"}}>
|
||||
// <Text size={18}>
|
||||
// Welcome to
|
||||
// <Text b size={18}>
|
||||
// NextUI
|
||||
// </Text>
|
||||
// </Text>
|
||||
// </Card.Header>
|
||||
// <Card.Body css={{px: "$10", pt: "$1", ov: "visible"}}>
|
||||
// <Input
|
||||
// bordered
|
||||
// clearable
|
||||
// fullWidth
|
||||
// color="primary"
|
||||
// contentLeft={<Mail fill="currentColor" />}
|
||||
// placeholder="Email"
|
||||
// size="lg"
|
||||
// />
|
||||
// <Spacer y={0.5} />
|
||||
// <Input
|
||||
// bordered
|
||||
// clearable
|
||||
// fullWidth
|
||||
// color="primary"
|
||||
// contentLeft={<Password />}
|
||||
// placeholder="Password"
|
||||
// size="lg"
|
||||
// />
|
||||
// <Spacer y={0.5} />
|
||||
// <Row align="center" justify="space-between">
|
||||
// <Checkbox>
|
||||
// <Text css={{color: "$accents8"}} size={14}>
|
||||
// Remember me
|
||||
// </Text>
|
||||
// </Checkbox>
|
||||
// <Link css={{color: "$link", fontSize: "$sm"}} href="#">
|
||||
// Forgot password?
|
||||
// </Link>
|
||||
// </Row>
|
||||
// </Card.Body>
|
||||
// <Card.Footer css={{pt: 0}}>
|
||||
// <Grid.Container gap={1} justify="flex-end">
|
||||
// <Grid>
|
||||
// <Button auto flat>
|
||||
// Sign Up
|
||||
// </Button>
|
||||
// </Grid>
|
||||
// <Grid>
|
||||
// <Button auto>Login</Button>
|
||||
// </Grid>
|
||||
// </Grid.Container>
|
||||
// </Card.Footer>
|
||||
// </Card>
|
||||
// );
|
||||
// };
|
||||
|
||||
556
packages/components/card/stories/card.stories.tsx.old
Normal file
556
packages/components/card/stories/card.stories.tsx.old
Normal file
@ -0,0 +1,556 @@
|
||||
import React from "react";
|
||||
import {ComponentMeta, ComponentStory} from "@storybook/react";
|
||||
import {Link} from "@nextui-org/link";
|
||||
import {Code} from "@nextui-org/code";
|
||||
import {styled} from "@nextui-org/system";
|
||||
|
||||
import {Card, CardProps} from "../src";
|
||||
|
||||
export default {
|
||||
title: "General/Card",
|
||||
component: Card,
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: {
|
||||
type: "radio",
|
||||
options: ["shadow", "bordered", "flat"],
|
||||
},
|
||||
},
|
||||
borderWeight: {
|
||||
control: {
|
||||
type: "radio",
|
||||
options: ["light", "normal", "bold", "extrabold", "black"],
|
||||
},
|
||||
},
|
||||
isPressable: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
disableAnimation: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
isHoverable: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof Card>;
|
||||
|
||||
const Template: ComponentStory<typeof Card> = (args: CardProps) => (
|
||||
<Card {...args} className="max-w-[50%]">
|
||||
<Card.Body>A basic card</Card.Body>
|
||||
</Card>
|
||||
);
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
variant: "shadow",
|
||||
};
|
||||
|
||||
export const Hoverable = Template.bind({});
|
||||
Hoverable.args = {
|
||||
variant: "bordered",
|
||||
isHoverable: true,
|
||||
};
|
||||
|
||||
export const Variants = () => (
|
||||
<div className="container flex gap-2">
|
||||
<div className="w-4/12">
|
||||
<Card>
|
||||
<Card.Body>
|
||||
<p>Default card. (shadow)</p>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="w-4/12">
|
||||
<Card variant="flat">
|
||||
<Card.Body>
|
||||
<p>Flat card.</p>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="w-4/12">
|
||||
<Card variant="bordered">
|
||||
<Card.Body>
|
||||
<p>Bordered card.</p>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const WithFooter = () => (
|
||||
<Card className="p-3 max-w-[400px]">
|
||||
<Card.Header>
|
||||
<img
|
||||
alt="nextui logo"
|
||||
height="34px"
|
||||
src="https://avatars.githubusercontent.com/u/86160567?s=200&v=4"
|
||||
width="34px"
|
||||
/>
|
||||
<div className="flex flex-col pl-3">
|
||||
<h4 className="pb-2">Next UI</h4>
|
||||
<p>nextui.org</p>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Body className="py-2">
|
||||
<p>Make beautiful websites regardless of your design experience.</p>
|
||||
</Card.Body>
|
||||
<Card.Footer>
|
||||
<Link isExternal color="primary" href="https://github.com/nextui-org/nextui" target="_blank">
|
||||
Visit source code on GitHub.
|
||||
</Link>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
);
|
||||
|
||||
export const AbsImageWithHeader = () => {
|
||||
return (
|
||||
<div className="flex justify-center gap-2">
|
||||
<Card className="w-[330px]">
|
||||
<Card.Header className="absolute top-5 z-10">
|
||||
<div className="grid-cols-2">
|
||||
<p className="text-white/75 text-sm uppercase font-bold">What to watch</p>
|
||||
<h3 className="text-white text-xl">Stream the Apple event</h3>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Apple event background"
|
||||
autoResize={false}
|
||||
height={440}
|
||||
src={require("./assets/apple-event.jpeg")}
|
||||
style={{objectFit: "cover"}}
|
||||
width="100%"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const AbsImgWithHeaderFooter = () => {
|
||||
return (
|
||||
<div className="flex justify-center items-start gap-2">
|
||||
<Card className="w-[330px] bg-neutral-100">
|
||||
<Card.Header className="absolute top-5 z-10">
|
||||
<div className="flex flex-col">
|
||||
<p className="text-xs text-neutral-400 upper font-bold">New</p>
|
||||
<h2 className="text-lg text-black">HomePod mini</h2>
|
||||
<p className="text-xs text-foreground pr-1.5">
|
||||
Room-filling sound, Intelligent assistant. Smart home control. Works seamlessly with
|
||||
iPhone. Check it out
|
||||
</p>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Apple homedpods background"
|
||||
autoResize={false}
|
||||
height={440}
|
||||
src={require("./assets/homepod.jpeg")}
|
||||
style={{objectFit: "cover", paddingTop: "100px"}}
|
||||
width="100%"
|
||||
/>
|
||||
<Card.Footer className="justify-between">
|
||||
<div>
|
||||
<p className="text-xs">Available soon.</p>
|
||||
<p className="text-xs">Get notified.</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex flex-wrap justify-end">
|
||||
<p className="text-xs upper font-bold">Notify Me</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
<Card className="w-[630px]">
|
||||
<Card.Header className="absolute top-5 z-10">
|
||||
<div className="flex flex-col">
|
||||
<p className="text-neutral-300 upper font-bold">Your day your way</p>
|
||||
<h3 className="text-white text-xl">Your checklist for better sleep</h3>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Apple homedpods background"
|
||||
autoResize={false}
|
||||
height={440}
|
||||
src={require("./assets/relaxing.jpeg")}
|
||||
style={{objectFit: "cover"}}
|
||||
width="100%"
|
||||
/>
|
||||
<Card.Footer isBlurred className="absolute bottom-0 z-10 border-t border-border-dark">
|
||||
<div className="flex flex-grow items-start">
|
||||
<div className="w-[40px] mr-2">
|
||||
<Card.Image
|
||||
alt="Breathing app icon"
|
||||
autoResize={false}
|
||||
height={40}
|
||||
src={require("./assets/breathing-app-icon.jpeg")}
|
||||
style={{background: "black"}}
|
||||
width={40}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<p className="text-xs text-neutral-400">Breathing App</p>
|
||||
<p className="text-xs text-neutral-400">Get a good night's sleep.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-white upper font-bold">Get App</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const CoverImage = () => (
|
||||
<div className="gap-2 grid grid-cols-12">
|
||||
<div className="col-span-12 sm:col-span-4">
|
||||
<Card>
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">What to watch</p>
|
||||
<h4 className="text-white font-medium text-lg">Stream the Acme event</h4>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Card image background"
|
||||
height={340}
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-4.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-4">
|
||||
<Card>
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">Plant a tree</p>
|
||||
<h4 className="text-white font-medium text-lg">Contribute to the planet</h4>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Card image background"
|
||||
height={340}
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-3.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-4">
|
||||
<Card className="bg-black">
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">Supercharged</p>
|
||||
<h4 className="text-white font-medium text-lg">Creates beauty like a beast</h4>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Card image background"
|
||||
height={340}
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-2.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-5">
|
||||
<Card className="w-full h-[400px]">
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">New</p>
|
||||
<h3 className="text-black font-medium text-2xl">Acme camera</h3>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Card example background"
|
||||
height="100%"
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-6.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
<Card.Footer
|
||||
isBlurred
|
||||
className="absolute bg-white/50 bottom-0 border-t border-border-dark z-10"
|
||||
>
|
||||
<div>
|
||||
<p className="text-black text-xs">Available soon.</p>
|
||||
<p className="text-black text-xs">Get notified.</p>
|
||||
</div>
|
||||
<p className="text-xs upper font-bold text-inherit ml-auto">Notify Me</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-7">
|
||||
<Card className="w-full h-[400px]">
|
||||
<Card.Header className="absolute z-10 top-1 flex-col !items-start">
|
||||
<p className="text-xs text-white/75 upper font-bold">Your day your way</p>
|
||||
<h3 className="text-white font-medium text-2xl">Your checklist for better sleep</h3>
|
||||
</Card.Header>
|
||||
<Card.Image
|
||||
alt="Relaxing app background"
|
||||
height="100%"
|
||||
objectFit="cover"
|
||||
src="https://nextui.org/images/card-example-5.jpeg"
|
||||
width="100%"
|
||||
/>
|
||||
<Card.Footer
|
||||
isBlurred
|
||||
className="absolute bottom-0 z-10 bg-black/50 border-t border-border-dark"
|
||||
>
|
||||
<div className="flex flex-grow items-center">
|
||||
<div className="w-[40px] mr-2">
|
||||
<Card.Image
|
||||
alt="Breathing app icon"
|
||||
autoResize={false}
|
||||
height={40}
|
||||
src={require("./assets/breathing-app-icon.jpeg")}
|
||||
style={{background: "black"}}
|
||||
width={40}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<p className="text-xs text-neutral-400">Breathing App</p>
|
||||
<p className="text-xs text-neutral-400">Get a good night's sleep.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-white upper font-bold">Get App</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const PrimaryAction = () => {
|
||||
const list = [
|
||||
{
|
||||
title: "Orange",
|
||||
img: "/images/fruit-1.jpeg",
|
||||
price: "$5.50",
|
||||
},
|
||||
{
|
||||
title: "Tangerine",
|
||||
img: "/images/fruit-2.jpeg",
|
||||
price: "$3.00",
|
||||
},
|
||||
{
|
||||
title: "Raspberry",
|
||||
img: "/images/fruit-3.jpeg",
|
||||
price: "$10.00",
|
||||
},
|
||||
{
|
||||
title: "Lemon",
|
||||
img: "/images/fruit-4.jpeg",
|
||||
price: "$5.30",
|
||||
},
|
||||
{
|
||||
title: "Advocato",
|
||||
img: "/images/fruit-5.jpeg",
|
||||
price: "$15.70",
|
||||
},
|
||||
{
|
||||
title: "Lemon 2",
|
||||
img: "/images/fruit-6.jpeg",
|
||||
price: "$8.00",
|
||||
},
|
||||
{
|
||||
title: "Banana",
|
||||
img: "/images/fruit-7.jpeg",
|
||||
price: "$7.50",
|
||||
},
|
||||
{
|
||||
title: "Watermelon",
|
||||
img: "/images/fruit-8.jpeg",
|
||||
price: "$12.20",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="gap-2 grid grid-cols-2 sm:grid-cols-4">
|
||||
{list.map((item, index) => (
|
||||
// eslint-disable-next-line no-console
|
||||
<Card key={index} isPressable onPress={() => console.log("item pressed", item)}>
|
||||
<Card.Body className="!p-0">
|
||||
<Card.Image
|
||||
alt={item.title}
|
||||
height={140}
|
||||
src={"https://nextui.org" + item.img}
|
||||
style={{objectFit: "cover"}}
|
||||
width="100%"
|
||||
/>
|
||||
</Card.Body>
|
||||
<Card.Footer className="justify-between">
|
||||
<strong>{item.title}</strong>
|
||||
<p className="font-medium text-neutral-500">{item.price}</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const CenterImgWithHeader = () => {
|
||||
const list = [
|
||||
{
|
||||
title: "Mac",
|
||||
img: require("./assets/mac.png"),
|
||||
},
|
||||
{
|
||||
title: "iPhone",
|
||||
img: require("./assets/iphone.png"),
|
||||
},
|
||||
{
|
||||
title: "iPad",
|
||||
img: require("./assets/ipad.png"),
|
||||
},
|
||||
{
|
||||
title: "Apple Watch",
|
||||
img: require("./assets/apple-watch.png"),
|
||||
},
|
||||
{
|
||||
title: "AirPods",
|
||||
img: require("./assets/airpods.png"),
|
||||
},
|
||||
{
|
||||
title: "AirTag",
|
||||
img: require("./assets/airtag.png"),
|
||||
},
|
||||
{
|
||||
title: "Apple TV",
|
||||
img: require("./assets/appletv.png"),
|
||||
},
|
||||
{
|
||||
title: "HomePod mini",
|
||||
img: require("./assets/homepod-mini.png"),
|
||||
},
|
||||
{
|
||||
title: "Accessories",
|
||||
img: require("./assets/accessories.png"),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 justify-center flex-wrap">
|
||||
{list.map((item, index) => (
|
||||
<div key={index}>
|
||||
<Card isHoverable isPressable className="w-[200px] h-[200px]">
|
||||
<Card.Header className="!p-0">
|
||||
<h5 className="pl-6 pt-2.5">{item.title}</h5>
|
||||
</Card.Header>
|
||||
<Card.Body className="h-full justify-center">
|
||||
<Card.Image alt={item.title} autoResize={false} src={item.img} width={180} />
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const WithDivider = () => (
|
||||
<Card className="w-max-[400px]" variant="bordered">
|
||||
<Card.Header className="border-b border-border dark:border-border-dark">
|
||||
<strong>Description</strong>
|
||||
</Card.Header>
|
||||
<Card.Body>
|
||||
<p>The Object constructor creates an object wrapper for the given value.</p>
|
||||
</Card.Body>
|
||||
<Card.Footer className="border-t border-border dark:border-border-dark">
|
||||
<p>
|
||||
When called in a non-constructor context, Object behaves identically to{" "}
|
||||
<Code>new Object()</Code>.
|
||||
</p>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
);
|
||||
|
||||
export const Shadows = () => {
|
||||
const Box = styled("div", {
|
||||
size: "120px",
|
||||
dflex: "center",
|
||||
bg: "$backgroundContrast",
|
||||
br: "$md",
|
||||
});
|
||||
|
||||
const shadows = ["$xs", "$sm", "$md", "$lg", "$xl"];
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 sm:grid-cols-5 gap-2 justify-center">
|
||||
<div className="flex justify-center col-span-2 sm:col-span-5">
|
||||
<strong>Drop shadows</strong>
|
||||
</div>
|
||||
{shadows.map((shadow, index) => (
|
||||
<div key={`${shadow}_${index}`}>
|
||||
<Box css={{dropShadow: shadow}}>
|
||||
<p>Shadow: {shadow}</p>
|
||||
</Box>
|
||||
</div>
|
||||
))}
|
||||
<div className="flex justify-center col-span-2 sm:col-span-5">
|
||||
<strong>Box shadows</strong>
|
||||
</div>
|
||||
{shadows.map((shadow, index) => (
|
||||
<div key={`${shadow}_${index}`}>
|
||||
<Box css={{boxShadow: shadow}}>
|
||||
<p>Shadow: {shadow}</p>
|
||||
</Box>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
//TODO: Input & Button still missing
|
||||
// export const withForm = () => {
|
||||
// return (
|
||||
// <Card css={{mw: "400px"}}>
|
||||
// <Card.Header css={{justifyContent: "center"}}>
|
||||
// <Text size={18}>
|
||||
// Welcome to
|
||||
// <Text b size={18}>
|
||||
// NextUI
|
||||
// </Text>
|
||||
// </Text>
|
||||
// </Card.Header>
|
||||
// <Card.Body css={{px: "$10", pt: "$1", ov: "visible"}}>
|
||||
// <Input
|
||||
// bordered
|
||||
// clearable
|
||||
// fullWidth
|
||||
// color="primary"
|
||||
// contentLeft={<Mail fill="currentColor" />}
|
||||
// placeholder="Email"
|
||||
// size="lg"
|
||||
// />
|
||||
// <Spacer y={0.5} />
|
||||
// <Input
|
||||
// bordered
|
||||
// clearable
|
||||
// fullWidth
|
||||
// color="primary"
|
||||
// contentLeft={<Password />}
|
||||
// placeholder="Password"
|
||||
// size="lg"
|
||||
// />
|
||||
// <Spacer y={0.5} />
|
||||
// <Row align="center" justify="space-between">
|
||||
// <Checkbox>
|
||||
// <Text css={{color: "$accents8"}} size={14}>
|
||||
// Remember me
|
||||
// </Text>
|
||||
// </Checkbox>
|
||||
// <Link css={{color: "$link", fontSize: "$sm"}} href="#">
|
||||
// Forgot password?
|
||||
// </Link>
|
||||
// </Row>
|
||||
// </Card.Body>
|
||||
// <Card.Footer css={{pt: 0}}>
|
||||
// <Grid.Container gap={1} justify="flex-end">
|
||||
// <Grid>
|
||||
// <Button auto flat>
|
||||
// Sign Up
|
||||
// </Button>
|
||||
// </Grid>
|
||||
// <Grid>
|
||||
// <Button auto>Login</Button>
|
||||
// </Grid>
|
||||
// </Grid.Container>
|
||||
// </Card.Footer>
|
||||
// </Card>
|
||||
// );
|
||||
// };
|
||||
@ -14,7 +14,7 @@ const accordion = tv({
|
||||
base: "px-2",
|
||||
variants: {
|
||||
variant: {
|
||||
shadow: "px-4 shadow-lg rounded-lg dark:bg-content1 border border-neutral-100",
|
||||
shadow: "px-4 shadow-lg rounded-xl dark:bg-content1 border border-neutral-100",
|
||||
bordered: "px-4 border border-neutral rounded-lg",
|
||||
splitted: "group is-splitted flex flex-col gap-2", // the styles are applied in the accordion-item component
|
||||
},
|
||||
|
||||
@ -21,18 +21,14 @@ const card = tv({
|
||||
base: [
|
||||
"flex",
|
||||
"flex-col",
|
||||
"m-0",
|
||||
"p-0",
|
||||
"relative",
|
||||
"overflow-hidden",
|
||||
"w-full",
|
||||
"height-auto",
|
||||
"bg-white",
|
||||
"text-foreground",
|
||||
"rounded-xl",
|
||||
"box-border",
|
||||
"dark:bg-neutral-900",
|
||||
"dark:text-foreground-dark",
|
||||
"dark:bg-content1",
|
||||
"border border-neutral-100",
|
||||
],
|
||||
header: [
|
||||
"flex",
|
||||
@ -44,6 +40,7 @@ const card = tv({
|
||||
"color-inherit",
|
||||
"p-3",
|
||||
"z-10",
|
||||
"subpixel-antialiased",
|
||||
],
|
||||
body: [
|
||||
"relative",
|
||||
@ -58,6 +55,7 @@ const card = tv({
|
||||
"px-3",
|
||||
"text-left",
|
||||
"overflow-y-auto",
|
||||
"subpixel-antialiased",
|
||||
],
|
||||
footer: [
|
||||
"w-full",
|
||||
@ -68,18 +66,60 @@ const card = tv({
|
||||
"overflow-hidden",
|
||||
"color-inherit",
|
||||
"rounded-b-xl",
|
||||
"subpixel-antialiased",
|
||||
],
|
||||
},
|
||||
variants: {
|
||||
variant: {
|
||||
shadow: {
|
||||
base: "drop-shadow-lg",
|
||||
shadow: {
|
||||
none: {
|
||||
base: "shadow-none",
|
||||
},
|
||||
bordered: {
|
||||
base: "border-border dark:border-border-dark",
|
||||
sm: {
|
||||
base: "shadow-sm",
|
||||
},
|
||||
flat: {
|
||||
base: "bg-neutral-100",
|
||||
md: {
|
||||
base: "shadow-md",
|
||||
},
|
||||
lg: {
|
||||
base: "shadow-lg",
|
||||
},
|
||||
xl: {
|
||||
base: "shadow-xl",
|
||||
},
|
||||
"2xl": {
|
||||
base: "shadow-2xl",
|
||||
},
|
||||
inner: {
|
||||
base: "shadow-inner",
|
||||
},
|
||||
},
|
||||
radius: {
|
||||
none: {
|
||||
base: "rounded-none",
|
||||
},
|
||||
base: {
|
||||
base: "rounded",
|
||||
},
|
||||
sm: {
|
||||
base: "rounded-sm",
|
||||
},
|
||||
md: {
|
||||
base: "rounded-md",
|
||||
},
|
||||
lg: {
|
||||
base: "rounded-lg",
|
||||
},
|
||||
xl: {
|
||||
base: "rounded-xl",
|
||||
},
|
||||
"2xl": {
|
||||
base: "rounded-2xl",
|
||||
},
|
||||
"3xl": {
|
||||
base: "rounded-3xl",
|
||||
},
|
||||
full: {
|
||||
base: "rounded-full",
|
||||
},
|
||||
},
|
||||
fullWidth: {
|
||||
@ -87,6 +127,11 @@ const card = tv({
|
||||
base: "w-full",
|
||||
},
|
||||
},
|
||||
isBordered: {
|
||||
true: {
|
||||
base: "border-2 border-neutral",
|
||||
},
|
||||
},
|
||||
isHoverable: {
|
||||
true: {
|
||||
base: "hover:drop-shadow-lg",
|
||||
@ -112,50 +157,32 @@ const card = tv({
|
||||
},
|
||||
disableAnimation: {
|
||||
true: "",
|
||||
false: {base: "!transition motion-reduce:transition-none"},
|
||||
false: {base: "transition-transform motion-reduce:transition-none"},
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
{
|
||||
isHoverable: true,
|
||||
disableAnimation: false,
|
||||
class: "hover:-translate-y-0.5",
|
||||
class: "hover:-translate-y-2",
|
||||
},
|
||||
{
|
||||
isPressable: true,
|
||||
disableAnimation: false,
|
||||
class: "active:scale-95",
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
borderWeight: "light",
|
||||
class: "border",
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
borderWeight: "normal",
|
||||
class: "border-2",
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
borderWeight: "bold",
|
||||
class: "border-3",
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
borderWeight: "extrabold",
|
||||
class: "border-4",
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
borderWeight: "black",
|
||||
class: "border-5",
|
||||
},
|
||||
],
|
||||
defaultVariants: {
|
||||
variant: "shadow",
|
||||
radius: "xl",
|
||||
shadow: "lg",
|
||||
fullWidth: false,
|
||||
isHoverable: false,
|
||||
isPressable: false,
|
||||
isFocusVisible: false,
|
||||
isBordered: false,
|
||||
isDisabled: false,
|
||||
disableAnimation: false,
|
||||
isFooterBlurred: false,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ module.exports = {
|
||||
"../../components/pagination/stories/*.stories.@(js|jsx|ts|tsx)",
|
||||
"../../components/switch/stories/*.stories.@(js|jsx|ts|tsx)",
|
||||
"../../components/accordion/stories/*.stories.@(js|jsx|ts|tsx)",
|
||||
"../../components/card/stories/*.stories.@(js|jsx|ts|tsx)",
|
||||
],
|
||||
staticDirs: ["../public"],
|
||||
addons: [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user