import { Meta, Story, ArgsTable, Canvas } from '@storybook/addon-docs/blocks'
import {
  ContainerUI,
  PHONE_OPTIONS,
  PAINT_OPTIONS,
  ARSENAL,
  ATLAS,
  BARCELONA,
  ValidationApp,
} from './EditableField.storiesHelpers'
import EditableField from './'

<Meta
  title="Components/Forms/EditableField"
  component={EditableField}
  parameters={{
    design: {
      type: 'figma',
      url:
        'https://www.figma.com/file/Wp9mDxTvWicSTWtezj2ImkMP/HSDS-Product?node-id=2582%3A9042',
    },
  }}
/>

# EditableField

A special type of inputs that allow you to edit it inline

<Canvas>
  <Story name="default">
    <div>
      <EditableField
        label="Company"
        name="company"
        placeholder="Add a company name"
        type="text"
      />
      <EditableField
        label="Team"
        name="team"
        placeholder="Add a sports team name"
        type="text"
        value="Atlas"
      />
    </div>
  </Story>
</Canvas>

#### Reference

- **Designer**: Jared
- **Engineering**: Juan Pablo
- **Usage**: Customer properties/profile

<br />
<br />

### Props

<ArgsTable of={EditableField} />

### actions

- Predefined actions:
  - `"delete"`: Clear a field
  - `"link"`: For url types, adds a button to open a new tab/window with the url
- By default `EditableField` incorporates one action: “delete”
- To override either of the predefined actions, pass them in the array using the same action name
- If the user doesn't want any action, she needs to explicitly pass `null`
- `icon` should be the name of an Icon that is present in HSDS
- Pass a `buttonAttrs` object to attach attributes directly on the html button (such as aria labels): `{ buttonAttrs: { 'aria-label': 'My important button' } }`

### onCommit

Fires:

- On pressing Enter on the Input
- On input blur
- On selecting an option
- On deleting/clearing the input value with “x”
- On deleting a value from multi-value fields

### onDelete

Fires:

- On deleting/clearing the input value with “x”
- On deleting a value from multi-value fields

### onDiscard

Fires:

- On pressing ESC on an input
- On adding a value and clicking outside the field and the value is empty

### disabled

To disable the entire field, use the `disabled` prop, to disable a single input in a multi-value
field, add the the `disabled` key to the value object, like:

```jsx
const BARCELONA = {
  value: 'FC Barcelona',
  id: 'TEAM_1',
  someOtherProp: 'the best, Jerry, the best',
}
const ARSENAL = {
  value: 'Arsenal',
  disabled: true,
  id: 'TEAM_2',
  someOtherProp: 'the best, Jerry, the best',
}
const ATLAS = {
  value: 'Atlas',
  disabled: true,
  id: 'TEAM_3',
  someOtherProp: 'the best, Jerry, the best',
}

<EditableField
  label="Teams (individual fields disabled)"
  name="teams"
  type="text"
  placeholder="Add a team name"
  value={[ARSENAL, ATLAS, BARCELONA]}
/>
```

### Stories

#### Large

<Canvas>
  <Story name="Large">
    <ContainerUI>
      <EditableField
        label="Team"
        name="team"
        placeholder="Add a sports team name"
        size="lg"
        type="text"
        value="Barcelona FC"
      />
    </ContainerUI>
  </Story>
</Canvas>

#### Floating Labels

<Canvas>
  <Story name="Floating Labels">
    <ContainerUI>
      <EditableField
        label="Company"
        name="company"
        placeholder="Company"
        type="text"
        floatingLabels
      />
      <EditableField
        label="Team"
        name="team"
        placeholder="Sports team"
        type="text"
        value="Atlas"
        floatingLabels
      />
    </ContainerUI>
  </Story>
</Canvas>

#### Multiple value fields

<Canvas>
  <Story name="Multiple value fields">
    <ContainerUI>
      <EditableField
        label="Films"
        name="films"
        type="text"
        multipleValues
        placeholder="Add a film name"
        addButtonProps={{
          className: 'my-classname',
          'aria-label': 'testtt',
          onClick: e => {
            console.log(e)
          },
        }}
      />
      <EditableField
        label="Musicians"
        name="musicians"
        type="text"
        placeholder="Add a musician name"
        value={['George Harrison', 'Neil Young']}
      />
      <EditableField
        emphasizeTopValue
        label="Emails"
        name="email"
        placeholder="Add your email"
        type="email"
        value={[
          'a@hello.com',
          'art_vandelay@vandelayindustries.com',
          'john_locke@dharma.org',
          'pennypacker@kramerica.com',
          'this_is_kind_of_long@annoyingemails.com',
          'this_is_kind_of_long@evenmoreannoyingemails.com',
        ]}
      />
    </ContainerUI>
  </Story>
</Canvas>

#### Url field

<Canvas>
  <Story name="Url field">
    <ContainerUI>
      <EditableField
        label="Website"
        name="website"
        placeholder="Add a website address"
        type="url"
        value="http://mysite.net"
        actions={{
          name: 'link',
          callback(obj) {
            console.log('HSDS: EditableFieldApp -> callback -> obj', obj)
          },
        }}
      />
      <EditableField
        label="Website Without Protocol"
        name="website2"
        placeholder="Add a website address"
        type="url"
        value="mysite.net"
        actions={{
          name: 'link',
          callback(obj) {
            console.log('HSDS: EditableFieldApp -> callback -> obj', obj)
          },
          buttonAttrs: {
            'aria-label': 'some aria label',
          },
        }}
      />
    </ContainerUI>
  </Story>
</Canvas>

#### With options

<Canvas>
  <Story name="With options">
    <ContainerUI>
      <EditableField
        label="Mobile Phone"
        name="mobilephone"
        placeholder="Add a mobile phone"
        type="tel"
        valueOptions={PHONE_OPTIONS}
      />
      <EditableField
        label="Phone"
        name="Phone"
        placeholder="Add phone"
        type="tel"
        valueOptions={PHONE_OPTIONS}
        defaultOption={PHONE_OPTIONS[2]}
        value={{ option: 'Work', value: '123456789' }}
      />
      <EditableField
        label="Favourite Paint Colour"
        name="paint"
        placeholder="Add a colour"
        type="text"
        onCommit={({ name, value }) => {
          value.forEach(val => {
            console.group(`Filed: ${name}`)
            console.log('🚀 ~ option', val.option)
            console.log('🚀 ~ value', val.value)
            console.groupEnd()
          })
        }}
        valueOptions={PAINT_OPTIONS}
        value={[
          { option: PAINT_OPTIONS[0], value: 'Anthraquinone Blue PB60' },
          { option: PAINT_OPTIONS[3], value: 'Ultramarine Violet' },
          { option: PAINT_OPTIONS[1], value: 'Bismuth Yellow' },
        ]}
      />
    </ContainerUI>
  </Story>
</Canvas>

#### disabled

<Canvas>
  <Story name="disabled">
    <ContainerUI>
      <EditableField
        label="Film"
        name="film"
        placeholder="Add a film name"
        type="text"
        disabled
      />
      <EditableField
        label="Company"
        name="company"
        placeholder="Add a company name"
        type="text"
        value="Help Scout"
        disabled
      />
      <EditableField
        label="Musicians"
        name="musicians"
        type="text"
        placeholder="Add a musician name"
        value={['George Harrison', 'Neil Young']}
        disabled
      />
      <EditableField
        label="Teams (individual fields disabled)"
        name="teams"
        type="text"
        placeholder="Add a team name"
        value={[ARSENAL, ATLAS, BARCELONA]}
      />
      <EditableField
        label="Phone"
        name="Phone"
        placeholder="Add phone"
        type="tel"
        valueOptions={PHONE_OPTIONS}
        defaultOption={PHONE_OPTIONS[2]}
        value={{ option: 'Work', value: '123456789' }}
        disabled
      />
    </ContainerUI>
  </Story>
</Canvas>

#### Validation

To enable field validation use the function prop `validate`, it provides the following payload:

```jsx
<EditableField
  validate={payload => {
    /**
      payload.data = { cause, item, operation } => data associated with the operation
      payload.name => the field name that we are validating
      payload.value => the new field value to validate
      payload.values => in multiple value fields, get all items as an array
    **/

    const { name, value } = payload // this is usually all you need
    const isValid = value !== 'valid' // determine what makes it valid or not

  // always return a promise...
  return return new Promise(resolve => {
    if (isValid) {
      resolve({
        isValid, // required
        name,
        value,
        updatedProps // if you need to update some props on the validated item
      })
    } else {
      resolve({
        isValid, // required
        name,
        value,
        type: 'error' || 'warning' || 'custom', // the first two are provided (makes things red or yellow),
        message: 'That is definitely not right', // gets put in the tooltip
        icon, // name of a hsds button to put there, 'alert-small' is the default
        color, // pass a valid custom color
      })
    }
  })
  }}
/>
```

<Canvas>
  <Story name="Validation">
    <ValidationApp />
  </Story>
</Canvas>
