import {
  Meta,
  Canvas,
  ArgsTable,
  Story,
  SourceState,
} from "@storybook/blocks";
import { ComponentHeading } from "../../storybook-components";
import { JUSTIFY } from "../../types";
import { tokens } from "../../style-dictionary/dist/tokens";
import { Button, BUTTON_VARIANT } from "../Button";
import { VendorLogo } from "../VendorLogo";
import { Heading } from "../Heading";
import { Flex } from "../Flex";
import { Card } from "./Card";

<Meta title="Components/Data/Card" component={Card} />

<ComponentHeading
  componentName="Card"
  description=""
  sourcePath="src/components/Card/Card.tsx"
/>

## Installation

```jsx
import { Card } from "@conveyorhq/arrow-ds";
```

## Basic usage

<Canvas withSource={SourceState.OPEN}>
  <Story name="Card">
    <Card cardSize={250} bodySlot="Card" />
  </Story>
</Canvas>

## API

### Card

These are the custom props that extend [`BoxProps`](/?path=/docs/components-box--box#all-props).

<ArgsTable of={Card} />

### Card.Group

The `Card.Group` component uses CSS grid to display 1 or more `Card` components

These are the custom props that extend [`BoxProps`](/?path=/docs/components-box--box#all-props).

<ArgsTable of={Card.Group} />

## Demos

### Card

export const onCardClick = () => {
  console.log("card clicked!");
};

export const onButtonClick = () => {
  console.log("button clicked!");
};

#### Accent Color

Using the prop `accentColorPlacement`, the accent color can be placed on the top or left of the card.

<Canvas>
  <Story name="CardColorGreen">
    <Card
      clickable
      accentColor={tokens.color.brandGreen["400"]}
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorGray">
    <Card
      clickable
      accentColor={tokens.color.gray["400"]}
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorYellow">
    <Card
      clickable
      accentColor={tokens.color.gold["400"]}
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorBlue">
    <Card
      clickable
      accentColor={tokens.color.blue["400"]}
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorPurple">
    <Card
      clickable
      accentColor={tokens.color.purple["400"]}
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorRed">
    <Card
      clickable
      accentColor={tokens.color.red["400"]}
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
</Canvas>

<Canvas>
  <Story name="CardColorGreenLeft">
    <Card
      clickable
      accentColor={tokens.color.brandGreen["400"]}
      accentColorPlacement="left"
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorGrayLeft">
    <Card
      clickable
      accentColor={tokens.color.gray["400"]}
      accentColorPlacement="left"
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorYellowLeft">
    <Card
      clickable
      accentColor={tokens.color.gold["400"]}
      accentColorPlacement="left"
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorBlueLeft">
    <Card
      clickable
      accentColor={tokens.color.blue["400"]}
      accentColorPlacement="left"
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorPurpleLeft">
    <Card
      clickable
      accentColor={tokens.color.purple["400"]}
      accentColorPlacement="left"
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
  <Story name="CardColorRedLeft">
    <Card
      clickable
      accentColor={tokens.color.red["400"]}
      accentColorPlacement="left"
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="Body"
    />
  </Story>
</Canvas>

#### Content

`Card` provides two slots for custom React content: `bodySlot` and `footerSlot`.
If content is provided to the `footerSlot` prop, a separate footer section will be included at the bottom of the card. Clicking in this area does not trigger the card's click action.

<Canvas>
  <Story name="Content1">
    <Card
      clickable
      accentColor={tokens.color.brandGreen["400"]}
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/conveyorhq.com"
            vendorName="Conveyor"
            size={20}
            alt=""
          />
          <Heading.H3>Conveyor</Heading.H3>
        </Flex>
      }
      footerSlot={
        <Flex className="justify-center">
          <Button variant={BUTTON_VARIANT.SECONDARY} onClick={onButtonClick}>
            Action
          </Button>
        </Flex>
      }
    />
  </Story>
  <Story name="Content2">
    <Card
      clickable
      accentColor={tokens.color.brandGreen["400"]}
      accentColorPlacement="left"
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot={
        <Flex className="h-full flex-col justify-center">
          <Heading.H2>Conveyor</Heading.H2>
        </Flex>
      }
      footerSlot={
        <Button.Group>
          <Button variant={BUTTON_VARIANT.MINIMAL} onClick={onButtonClick}>
            Action 1
          </Button>
          <Button variant={BUTTON_VARIANT.MINIMAL} onClick={onButtonClick}>
            Action 2
          </Button>
        </Button.Group>
      }
    />
  </Story>
</Canvas>

#### Sizes

Sizing a group of cards should be done using the `Card.Group` component. Size for an individual card can be set using the `cardSize` prop. The provided pixel size will adjust the overall size of the card. If a footer is used, the body height will be automatically adjusted.

<Canvas isColumn>
  <Story name="SizeDefault">
    <Card
      clickable
      cardSize={250}
      accentColor={tokens.color.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="250"
    />
  </Story>
  <Story name="SizeDefaultWithFooter">
    <Card
      clickable
      cardSize={250}
      accentColor={tokens.color.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="250"
      footerSlot="Footer"
    />
  </Story>
  <Story name="Size200">
    <Card
      clickable
      cardSize={200}
      accentColor={tokens.color.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="200"
    />
  </Story>
  <Story name="Size200WithFooter">
    <Card
      clickable
      cardSize={200}
      accentColor={tokens.color.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="200"
      footerSlot="Footer"
    />
  </Story>
  <Story name="Size150">
    <Card
      clickable
      cardSize={150}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="150"
    />
  </Story>
  <Story name="Size150WithFooter">
    <Card
      clickable
      cardSize={150}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="150"
      footerSlot="Footer"
    />
  </Story>
</Canvas>

#### As Link

export const Link = ({ to, children, ...rest }) => (
  <a href={to} {...rest}>
    {children}
  </a>
);

<Canvas>
  <Story name="AsLink">
    <Card
      clickable
      cardSize={250}
      accentColor={tokens.color.brandGreen["400"]}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/conveyorhq.com"
            vendorName="Conveyor"
            size={20}
            alt=""
          />
          <Heading.H3>Conveyor</Heading.H3>
        </Flex>
      }
      bodyProps={{
        as: "a",
        href: "http://google.com",
      }}
      footerSlot={
        <Button.Group justify={JUSTIFY.CENTER}>
          <Button variant={BUTTON_VARIANT.SECONDARY} onClick={onButtonClick}>
            Action
          </Button>
        </Button.Group>
      }
    />
  </Story>
  <Story name="AsRouter">
    <Card
      clickable
      cardSize={250}
      accentColor={tokens.color.brandGreen["400"]}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/conveyorhq.com"
            vendorName="Conveyor"
            size={20}
            alt=""
          />
          <Heading.H3>Conveyor</Heading.H3>
        </Flex>
      }
      bodyProps={{
        as: Link,
        to: "http://google.com",
      }}
      footerSlot={
        <Button.Group justify={JUSTIFY.CENTER}>
          <Button variant={BUTTON_VARIANT.SECONDARY} onClick={onButtonClick}>
            Action
          </Button>
        </Button.Group>
      }
    />
  </Story>
</Canvas>

#### Disabled

<Canvas>
  <Story name="DisabledCard">
    <Card
      clickable
      cardDisabled
      cardSize={250}
      accentColor={tokens.color.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/conveyorhq.com"
            vendorName="Conveyor"
            size={20}
            alt=""
          />
          <Heading.H3>Conveyor</Heading.H3>
        </Flex>
      }
      footerSlot={
        <Button.Group justify={JUSTIFY.CENTER}>
          <Button variant={BUTTON_VARIANT.SECONDARY} onClick={onButtonClick}>
            Action
          </Button>
        </Button.Group>
      }
    />
  </Story>
  <Story name="DisabledBody">
    <Card
      clickable
      bodyDisabled
      cardSize={250}
      accentColor={tokens.color.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/conveyorhq.com"
            vendorName="Conveyor"
            size={20}
            alt=""
          />
          <Heading.H3>Conveyor</Heading.H3>
        </Flex>
      }
      footerSlot={
        <Button.Group justify={JUSTIFY.CENTER}>
          <Button variant={BUTTON_VARIANT.SECONDARY} onClick={onButtonClick}>
            Action
          </Button>
        </Button.Group>
      }
    />
  </Story>
</Canvas>

#### Not Clickable

<Canvas>
  <Story name="NotClickableGreen">
    <Card
      accentColor={tokens.color.brandGreen["400"]}
      cardSize={250}
      bodySlot="Body"
    />
  </Story>
  <Story name="NotClickableGray">
    <Card
      accentColor={tokens.color.gray["400"]}
      cardSize={250}
      bodySlot="Body"
    />
  </Story>
  <Story name="NotClickableYellow">
    <Card
      accentColor={tokens.color.gold["400"]}
      cardSize={250}
      bodySlot="Body"
    />
  </Story>
</Canvas>

### As Placeholder

<Canvas>
  <Story name="Placeholder">
    <Card
      isPlaceholder
      bodyDisabled
      cardSize={250}
      accentColor={tokens.color.gold["400"]}
      bodySlot={
        <Flex className="h-full flex-col justify-center">
          <Heading.H2>Conveyor</Heading.H2>
        </Flex>
      }
    />
  </Story>
</Canvas>

### Card.Group

#### Sizing

In most cases, all cards in a group should all be the same size and be square in shape. The `Card.Group` component uses this size to set the `grid-template-columns` and `grid-auto-rows` CSS properties. To create a `Card.Group` where cards are different sizes or non-square, set your own grid sizing.

##### 150px

<Canvas>
  <Story name="CardGroupSize150">
    <Card.Group cardSize={150}>
      <Card bodySlot="150" />
      <Card bodySlot="150" />
      <Card bodySlot="150" />
      <Card bodySlot="150" />
      <Card bodySlot="150" />
      <Card bodySlot="150" />
    </Card.Group>
  </Story>
</Canvas>

##### 300px

<Canvas>
  <Story name="CardGroupSize300">
    <Card.Group cardSize={300}>
      <Card bodySlot="300" />
      <Card bodySlot="300" />
      <Card bodySlot="300" />
      <Card bodySlot="300" />
      <Card bodySlot="300" />
      <Card bodySlot="300" />
    </Card.Group>
  </Story>
</Canvas>

##### Custom

<Canvas>
  <Story name="CardGroupSizeDynamic">
    <Card.Group
      style={{
        gridTemplateColumns: `repeat(2, 1fr)`,
        gridTemplateRows: "max-content",
      }}
    >
      <Card
        bodySlot={
          <Flex>
            I have a lot of content. A lot of content. A lot of content. A lot
            of content. A lot of content. A lot of content. A lot of content. A
            lot of content. A lot of content. A lot of content. A lot of
            content.
          </Flex>
        }
      />
      <Card bodySlot="I expand in height to match" />
      <Card bodySlot="This row has less content" />
      <Card bodySlot="And is shorter" />
    </Card.Group>
  </Story>
</Canvas>

#### Gap

The default card gap is `20px`. This should be suitable for the majority of use cases, use caution when overriding this value.

##### Default

<Canvas>
  <Story name="GapDefault">
    <Card.Group cardSize={150}>
      <Card bodySlot="default gap" />
      <Card bodySlot="default gap" />
      <Card bodySlot="default gap" />
      <Card bodySlot="default gap" />
      <Card bodySlot="default gap" />
      <Card bodySlot="default gap" />
    </Card.Group>
  </Story>
</Canvas>

##### 40px

<Canvas>
  <Story name="Gap40">
    <Card.Group cardSize={150} gridGap="40px">
      <Card bodySlot="40px gap" />
      <Card bodySlot="40px gap" />
      <Card bodySlot="40px gap" />
      <Card bodySlot="40px gap" />
      <Card bodySlot="40px gap" />
      <Card bodySlot="40px gap" />
    </Card.Group>
  </Story>
</Canvas>

#### Without Accents

<Canvas>
  <Story name="Without accents">
    <Card.Group cardSize={250}>
      <Card bodySlot="Body" footerSlot="Footer" />
      <Card bodySlot="Body" footerSlot="Footer" />
      <Card bodySlot="Body" footerSlot="Footer" />
      <Card bodySlot="Body" footerSlot="Footer" />
      <Card bodySlot="Body" footerSlot="Footer" />
      <Card bodySlot="Body" footerSlot="Footer" />
    </Card.Group>
  </Story>
</Canvas>

#### Mixed Accents

<Canvas>
  <Story name="Mixed accents">
    <Card.Group hasAccents cardSize={250}>
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.brandGreen["400"]}
      />
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.brandGreen["400"]}
      />
      <Card bodySlot="Body" footerSlot="Footer" />
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.gold["400"]}
      />
      <Card bodySlot="Body" footerSlot="Footer" />
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.brandGreen["400"]}
      />
    </Card.Group>
  </Story>
</Canvas>

#### With Accents

<Canvas>
  <Story name="With accents">
    <Card.Group hasAccents cardSize={250}>
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.brandGreen["400"]}
      />
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.brandGreen["400"]}
      />
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.gray["400"]}
      />
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.gold["400"]}
      />
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.gray["400"]}
      />
      <Card
        bodySlot="Body"
        footerSlot="Footer"
        accentColor={tokens.color.brandGreen["400"]}
      />
    </Card.Group>
  </Story>
</Canvas>
