{/* prettier-ignore */}
{/*
Copyright 2023 Comcast Cable Communications Management, LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

SPDX-License-Identifier: Apache-2.0
\*/}

import { Meta, Title } from '@storybook/blocks';
import * as InputStories from './Input.stories';

<Meta of={InputStories} />

<Title />

Text input field component

## Source

https://github.com/rdkcentral/Lightning-UI-Components/blob/develop/packages/@lightningjs/ui-components/src/components/Input/Input.js

## Usage

The `Input` component manages the state of a user's keyboard input. An important distinction between `Input` and the standard web `<input />` is that `Input` **does not do key handling for input**. Instead, you use the `insert()` method to add values based on the current cursor `position`.

```js
import { Input } from '@lightningjs/ui-components';

class Example extends lng.Component {
  static _template() {
    return {
      Input: {
        type: Input
      }
    };
  }

  _handleKey(event) {
    const { key } = event;
    if (key.length === 1) {
      this.tag('Input').input(key);
    }
    if (key === 'Backspace') {
      this.tag('Input').backspace();
    }
  }
}
```

### Setting \& Inserting values

The `Input` component provides different ways to manage the input text and cursor position. When the `listening` property is enabled, the cursor blinks as a placeholder, whether the component is in focused or unfocused mode.

The text displayed in the `Input` can be directly set via the `value` property. The following example will display the input with the text "Hello".
Setting the `value` on the `Input` directly like this will remove any existing text in the input and set the cursor `position` in the Input to `0` \( before the 'H' in 'Hello'\).
The cursor position can be manually updated by setting the `position` property. Setting `value` and `position` like this will update the `Input` regardless of whether or not `listening` is enabled.

```js
// dislay Hello in the input
this.tag('Input').value = 'Hello';

// update the cursor position in the input from index 0 (before the H in Hello) to index 5 (after the o in Hello)
this.tag('Input').position = 5;
```

To set the `value` _and_ update the `position` to after the last character in the added text, use the `insert()` method.
The `Input` must be in focused or unfocused mode and the `listening` property enabled to use `insert()`.

```js
this.tag('Input').insert('Hello');

// is the same as
this.tag('Input').value = 'Hello';
this.tag('Input').position = 5;
```

### Deletion

To clear the current value use `clear()`. This also repositions the cursor to index `0`.
The `Input` must be in focused or unfocused mode and the `listening` property enabled to use `clear()`.

```js
this.tag('Input').clear();
```

To remove the character 1 position before the cursor position, use `backspace()`. This will remove that character and move the cursor back one position.
The `Input` must be in focused or unfocused mode and the `listening` property enabled to use `backspace()`.

```js
this.tag('Input').value = 'foo';
this.tag('Input').position = 1;

this.tag('Input').backspace();
this.tag('Input').value; //=> 'oo'
this.tag('Input').position; //=> 0
```

### Listening

When `listening` is true, the cursor begins blinking and the user is able to enter text.

```js
this.tag('Input').listening = true;
//When listening is true, the cursor blinks and allows user to enter text.

this.tag('Input').listening = false;
//When listening is false, the cursor will not be visible and does not allow user to enter text.
```

### Cursor position

The `Input` component has left and right key handlers to manage cursor position, so it works out of the box!

```js
this.tag('Input').value = 'foo';

this.tag('Input')._handleRight();
this.tag('Input').position; //=> 1

this.tag('Input')._handleLeft();
this.tag('Input').position; //=> 0
```

The cursor position stays within the bounds of the current `value`, so it is always \>\= 0 and \<\= `value.length`

### Password

Inputs commonly mask the value of passwords and other secure values. To enable input masking, set password to true.

```js
this.tag('Input').password = true;
//The character used to mask input can be changed as well.

this.tag('Input').mask = '•';
//To reveal the input, simply set password back to false.

this.tag('Input').password = false;
//When password is true, the Announcer will say "Input hidden" when the Input is focused.
```

## API

### Properties

| name        | type    | required | default   | description                                                                                                                                                    |
| ----------- | ------- | -------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| actualTitle | string  | false    | undefined | actualTitle is a proxy element for title which is used to store actual value typed when password is enabled                                                    |
| cursor      | string  | false    | undefined | cursor lets us know the current insert or delete position of title.                                                                                            |
| eyebrow     | string  | false    | undefined | Eyebrow of input container                                                                                                                                     |
| helpText    | string  | false    | undefined | HelpText of input container                                                                                                                                    |
| listening   | boolean | false    | undefined | when true, input will accept changes from clear, insert, and backspace methods. When false, effects of those methods will be ignored and not affect the input. |
| mask        | string  | false    | undefined | character to use as a mask when password is true                                                                                                               |
| password    | boolean | false    | undefined | determines whether input should be masked                                                                                                                      |
| position    | number  | false    | undefined | index of current cursor position                                                                                                                               |

### Style Properties

| name             | type             | description                                                                            |
| ---------------- | ---------------- | -------------------------------------------------------------------------------------- |
| cursorStyle      | object           | styles of the cursor                                                                   |
| eyebrowTextStyle | string \| object | text style to apply to the eyebrow                                                     |
| helpTextStyle    | string \| object | text style to apply to the helpText                                                    |
| minWidth         | number           | used as a fallback width if no width is passed into the component and `fixed` is false |
| paddingX         | number           | space between the button horizontal edge and the content                               |
| paddingY         | number           | space between the button vertical edge and the content                                 |
