import { Meta, Preview, Props, Story } from "@storybook/addon-docs/blocks";
import { ComponentHeading } from "../../storybook-components";
import { Stack, ORIENTATION } from "../..";
import { Avatar } from "./Avatar";
import { AVATAR_TYPE } from "./types";

<Meta title="Components/Images/Avatar" component={Avatar} />

<ComponentHeading
  componentName="Avatar"
  description="Profile images for users"
  sourcePath="src/components/Avatar/Avatar.tsx"
/>

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

export const sizes = ["small", "medium", "large", "xlarge"];

export const people = [
  {
    name: "Jason Wallace",
    email: "jason.wallace@aptible.com",
  },
  {
    name: "Heather Brownfield",
    email: "heather.brownfield@aptible.com",
  },
  {
    name: "Sheila Collier",
    email: "sheila.collier@aptible.com",
  },
  {
    email: "soo.blanchard@aptible.com",
    name: "Soo Blanchard",
  },
  {
    name: "Twanna Benton",
    email: "twanna.benton@aptible.com",
  },
  {
    name: "Chaya Lacey",
    email: "chaya.lacey@aptible.com",
  },
  {
    name: "Galina Luis",
    email: "galina.luis@aptible.com",
  },
  {
    name: "Mikaela Gunther",
    email: "mikaela.gunther@aptible.com",
  },
];

For best results, provide every Avatar with `email` and `name` (or
`firstInitial` and `lastInitial`) props. If there is a Gravatar
associated with the email address, it will be used. Otherwise, the
initials will be displayed.

<Preview>
  <Story name="Avatar">
    <Avatar
      size="xlarge"
      type={AVATAR_TYPE.USER}
      email="skylar@aptible.com"
      firstInitial="S"
      lastInitial="A"
    />
  </Story>
</Preview>

## Props

### Avatar props

<Props of={Avatar} />

### Avatar.Group props

<Props of={Avatar.Group} />

## Demos

### Sizes

There are four sizes available for Avatar; `small` (16px), `medium`
(24px), `large` (32px) and `xlarge` (48px).

<Preview>
  <Story name="Avatar sizes">
    <Stack>
      {sizes.map((size) => (
        <Avatar
          key={size}
          size={size}
          type={AVATAR_TYPE.USER}
          email="skylar@aptible.com"
          firstInitial="S"
          lastInitial="A"
        />
      ))}
    </Stack>
  </Story>
</Preview>

### Square

Avatars can be square.

<Preview>
  <Story name="Avatar square">
    <Avatar
      size="xlarge"
      type={AVATAR_TYPE.USER}
      email="skylar@aptible.com"
      firstInitial="S"
      lastInitial="A"
      square
    />
  </Story>
</Preview>

### Bordered

Avatars can have a border, which also comes with a box shadow.

<Preview>
  <Story name="Avatar bordered">
    <Avatar
      size="xlarge"
      type={AVATAR_TYPE.USER}
      email="skylar@aptible.com"
      firstInitial="S"
      lastInitial="A"
      bordered
    />
  </Story>
</Preview>

### User with custom image

If an image url is provided to the `imgSrc`, it will be used as the
avatar. The `email`, `firstInitial`, and `lastInitial` props won’t have
any effect.

<Preview>
  <Story name="Avatar user with custom image">
    <Avatar
      size="xlarge"
      type={AVATAR_TYPE.USER}
      imgSrc="http://placekitten.com/400/400"
    />
  </Story>
</Preview>

### User with Gravatar

If no `imgSrc` is set, the provided `email` will be used to find the
corresponding Gravatar if there is one. If not, the user’s initials will
be used as a fallback (see [Initials demo](#user-with-initials)).

<Preview>
  <Story name="Avatar user with Gravatar">
    <Avatar
      size="xlarge"
      type={AVATAR_TYPE.USER}
      email="skylar@aptible.com"
      firstInitial="S"
      lastInitial="A"
    />
  </Story>
</Preview>

### User with initials

A random color is displayed behind the user’s initials if an `imgSrc`
isn’t provided and there is no Gravatar associated with the provided
email address. The email address acts as a seed for selecting the random
color, so the same color will always be returned if the email address
does not change.

You must provide either a `name` or both `firstInitial` and
`lastInitial` to the avatar to fall back on. If neither of these are
provided, then the first letter of the user’s email address will be
used.

<Preview>
  <Story name="Avatar user with initials">
    <Avatar.Group size="xlarge" spacing={2}>
      {people.map((person) => (
        <Avatar
          key={person.email}
          size="xlarge"
          type={AVATAR_TYPE.USER}
          name={person.name}
          email={person.email}
        />
      ))}
    </Avatar.Group>
  </Story>
</Preview>

<Preview>
  <Story name="Avatar user with initials from email address">
    <Avatar.Group size="xlarge" spacing={2}>
      {people.map((person) => (
        <Avatar
          key={person.email}
          size="xlarge"
          type={AVATAR_TYPE.USER}
          email={person.email}
        />
      ))}
    </Avatar.Group>
  </Story>
</Preview>

### User with tooltip

User avatars have the option of showing the user’s name in a tooltip
when the avatar is hovered. This works for any kind of user avatar;
Gravatar, custom image, and initials. Set the `enableTooltip` prop to
`true`.

<Preview>
  <Story name="Avatar user with tooltip">
    <Avatar.Group size="xlarge" spacing={2}>
      <Avatar
        size="xlarge"
        type={AVATAR_TYPE.USER}
        name="Skylar Anderson"
        email="skylar@aptible.com"
        enableTooltip
      />
      <Avatar
        size="xlarge"
        type={AVATAR_TYPE.USER}
        imgSrc="http://placekitten.com/400/400"
        name="Cute Kitten"
        enableTooltip
      />
      {people.map((person) => (
        <Avatar
          key={person.email}
          size="xlarge"
          type={AVATAR_TYPE.USER}
          name={person.name}
          email={person.email}
          enableTooltip
        />
      ))}
    </Avatar.Group>
  </Story>
</Preview>

### System

<Preview>
  <Story name="Avatar system">
    <Avatar size="xlarge" type={AVATAR_TYPE.SYSTEM} />
  </Story>
</Preview>

### Anonymous (deprecated)

**Using this variant should be avoided.** It will be removed as an
option in the next major version of Arrow. It is only included as a
fallback if both `imgSrc` and `email` props are not provided.

<Preview>
  <Story name="Avatar anonymous">
    <Avatar
      size="xlarge"
      type={AVATAR_TYPE.USER}
      firstInitial="S"
      lastInitial="A"
    />
  </Story>
</Preview>

### Kitchen sink

Here you can find examples of all possible combinations of size, shape
and border.

<Preview>
  <Story name="Avatar kitchen sink">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            email="skylar@aptible.com"
            firstInitial="S"
            lastInitial="A"
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            email="skylar@aptible.com"
            firstInitial="S"
            lastInitial="A"
            bordered
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            email="skylar@aptible.com"
            firstInitial="S"
            lastInitial="A"
            square
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            email="skylar@aptible.com"
            firstInitial="S"
            lastInitial="A"
            square
            bordered
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            imgSrc="http://placekitten.com/400/400"
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            imgSrc="http://placekitten.com/400/400"
            bordered
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            imgSrc="http://placekitten.com/400/400"
            square
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            imgSrc="http://placekitten.com/400/400"
            square
            bordered
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            name={people[0].name}
            email={people[0].email}
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            name={people[0].name}
            email={people[0].email}
            bordered
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            name={people[0].name}
            email={people[0].email}
            square
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            name={people[0].name}
            email={people[0].email}
            square
            bordered
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar key={size} size={size} type={AVATAR_TYPE.SYSTEM} />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar key={size} size={size} type={AVATAR_TYPE.SYSTEM} bordered />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar key={size} size={size} type={AVATAR_TYPE.SYSTEM} square />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.SYSTEM}
            square
            bordered
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            firstInitial="S"
            lastInitial="A"
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            firstInitial="S"
            lastInitial="A"
            bordered
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            firstInitial="S"
            lastInitial="A"
            square
          />
        ))}
      </Stack>
      <Stack>
        {sizes.map((size) => (
          <Avatar
            key={size}
            size={size}
            type={AVATAR_TYPE.USER}
            firstInitial="S"
            lastInitial="A"
            square
            bordered
          />
        ))}
      </Stack>
    </Stack>
  </Story>
</Preview>

### Avatars in a group

This example shows how you can use Avatar.Group to show a list of
avatars.

<Preview>
  <Story name="Avatars in a group">
    <Stack orientation={ORIENTATION.VERTICAL} spacing={8}>
      <Avatar.Group size="xlarge" spacing={4}>
        {people.map((person) => (
          <Avatar
            key={person.email}
            type={AVATAR_TYPE.USER}
            email={person.email}
            name={person.name}
            bordered
            enableTooltip
          />
        ))}
      </Avatar.Group>
      <Avatar.Group size="xlarge" spacing={2}>
        {people.map((person) => (
          <Avatar
            key={person.email}
            type={AVATAR_TYPE.USER}
            email={person.email}
            name={person.name}
            square
            enableTooltip
          />
        ))}
      </Avatar.Group>
    </Stack>
  </Story>
</Preview>

### Avatars overlapping in a group

Pass in the `overlap` value to the `spacing` prop on the Avatar.Group to
show a list of overlapping avatars. The `overlap` value sets a negative
margin on each avatar which is relative to the avatar’s size.

For best results, use the round bordered variant of the avatar.

<Preview>
  <Story name="Avatars overlapping in a stack">
    <Stack orientation={ORIENTATION.VERTICAL} spacing={8}>
      <Avatar.Group size="small" spacing="overlap">
        {people.map((person) => (
          <Avatar
            key={person.email}
            type={AVATAR_TYPE.USER}
            email={person.email}
            name={person.name}
            bordered
            enableTooltip
          />
        ))}
      </Avatar.Group>
      <Avatar.Group size="medium" spacing="overlap">
        {people.map((person) => (
          <Avatar
            key={person.email}
            type={AVATAR_TYPE.USER}
            email={person.email}
            name={person.name}
            bordered
            enableTooltip
          />
        ))}
      </Avatar.Group>
      <Avatar.Group size="large" spacing="overlap">
        {people.map((person) => (
          <Avatar
            key={person.email}
            type={AVATAR_TYPE.USER}
            email={person.email}
            name={person.name}
            bordered
            enableTooltip
          />
        ))}
      </Avatar.Group>
      <Avatar.Group size="xlarge" spacing="overlap">
        {people.map((person) => (
          <Avatar
            key={person.email}
            type={AVATAR_TYPE.USER}
            email={person.email}
            name={person.name}
            bordered
            enableTooltip
          />
        ))}
      </Avatar.Group>
    </Stack>
  </Story>
</Preview>
