import {
  Meta,
  Preview,
  Props,
  Story,
  SourceState,
} from "@storybook/addon-docs/blocks";
import { Card } from "./Card";
import { Button, BUTTON_VARIANT } from "../Button";
import { VendorLogo } from "../VendorLogo";
import { Heading } from "../Heading";
import { Flex } from "../Flex";
import { JUSTIFY } from "../../types";
import { colors } from "../../tokens";

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

# Card

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

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

## `Card` Custom Props

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

<Props of={Card} />

# Card.Group

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

## `Card.Group` Custom Props

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

<Props of={Card.Group} />

## `Card` Demos

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.

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

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

### 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.

<Preview>
  <Story name="Content1">
    <Card
      clickable
      accentColor={colors.brandGreen["400"]}
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/aptible.com"
            vendorName="Aptible"
            size={20}
            alt=""
          />
          <Heading.H3>Aptible</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={colors.brandGreen["400"]}
      accentColorPlacement="left"
      cardSize={250}
      bodyProps={{ onClick: onCardClick }}
      bodySlot={
        <Flex className="h-full flex-col justify-center">
          <Heading.H2>Aptible</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>
</Preview>

### 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.

<Preview isColumn>
  <Story name="SizeDefault">
    <Card
      clickable
      cardSize={250}
      accentColor={colors.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="250"
    />
  </Story>
  <Story name="SizeDefaultWithFooter">
    <Card
      clickable
      cardSize={250}
      accentColor={colors.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="250"
      footerSlot="Footer"
    />
  </Story>
  <Story name="Size200">
    <Card
      clickable
      cardSize={200}
      accentColor={colors.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot="200"
    />
  </Story>
  <Story name="Size200WithFooter">
    <Card
      clickable
      cardSize={200}
      accentColor={colors.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>
</Preview>

### As Link

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

<Preview>
  <Story name="AsLink">
    <Card
      clickable
      cardSize={250}
      accentColor={colors.brandGreen["400"]}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/aptible.com"
            vendorName="Aptible"
            size={20}
            alt=""
          />
          <Heading.H3>Aptible</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={colors.brandGreen["400"]}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/aptible.com"
            vendorName="Aptible"
            size={20}
            alt=""
          />
          <Heading.H3>Aptible</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>
</Preview>

### Disabled

<Preview>
  <Story name="DisabledCard">
    <Card
      clickable
      cardDisabled
      cardSize={250}
      accentColor={colors.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/aptible.com"
            vendorName="Aptible"
            size={20}
            alt=""
          />
          <Heading.H3>Aptible</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={colors.brandGreen["400"]}
      bodyProps={{ onClick: onCardClick }}
      bodySlot={
        <Flex className="h-full flex-col items-center justify-center ">
          <VendorLogo
            src="https://logo.clearbit.com/aptible.com"
            vendorName="Aptible"
            size={20}
            alt=""
          />
          <Heading.H3>Aptible</Heading.H3>
        </Flex>
      }
      footerSlot={
        <Button.Group justify={JUSTIFY.CENTER}>
          <Button variant={BUTTON_VARIANT.SECONDARY} onClick={onButtonClick}>
            Action
          </Button>
        </Button.Group>
      }
    />
  </Story>
</Preview>

### Not Clickable

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

### As Placeholder

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

## `Card.Group` Demos

### 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

<Preview>
  <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>
</Preview>

#### 300px

<Preview>
  <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>
</Preview>

#### Custom

<Preview>
  <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>
</Preview>

### Gap

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

#### Default

<Preview>
  <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>
</Preview>

#### 40px

<Preview>
  <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>
</Preview>

### Without Accents

<Preview>
  <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>
</Preview>

### Mixed Accents

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

### With Accents

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