import {
  ExampleCodeBlock,
  Specifications,
  SymbolDoc,
} from '@workday/canvas-kit-docs';
import Basic from './examples/Basic';
import Disabled from './examples/Disabled';
import Grow from './examples/Grow';
import Icons from './examples/Icons';
import LabelPosition from './examples/LabelPosition';
import Placeholder from './examples/Placeholder';
import RefForwarding from './examples/RefForwarding';
import Required from './examples/Required';


# Canvas Kit Text Input

Text Inputs allow users to enter words or characters without styling.

[> Workday Design Reference](https://design.workday.com/components/inputs/text-input)

## Installation

```sh
yarn add @workday/canvas-kit-react
```

## Usage

### Basic Example

Text Input should be used in tandem with [Form Field](/components/inputs/form-field/) to ensure
proper label association and screen reader support.

<ExampleCodeBlock code={Basic} />

### Disabled

Set the `disabled` prop of the Text Input to prevent users from interacting with it.

<ExampleCodeBlock code={Disabled} />

### Placeholder

Set the `placeholder` prop of the Text Input to display a sample of its expected format or value
before a value has been provided.

<ExampleCodeBlock code={Placeholder} />

> **Accessibility Note**: Always provide a persistent `FormField.Label` and never rely on
> placeholder text as the only label for an input. Placeholders can disappear or lack sufficient
> contrast. Use placeholders only for short format examples (e.g., "name@example.com"), and place
> detailed instructions or guidance in `FormField.Hint` instead of the placeholder.

### Ref Forwarding

Text Input supports [ref forwarding](https://reactjs.org/docs/forwarding-refs.html). It will forward
`ref` to its underlying `<input type="text">` element.

<ExampleCodeBlock code={RefForwarding} />

### Grow

Set the `grow` prop of the wrapping Form Field to `true` to configure the Text Input to expand to
the width of its container.

<ExampleCodeBlock code={Grow} />

The `grow` prop may also be applied directly to the Text Input if Form Field is not being used.

### Label Position Horizontal

Set the `orientation` prop of the Form Field to designate the position of the label relative to the
input component. By default, the orientation will be set to `vertical`.

<ExampleCodeBlock code={LabelPosition} />

### Required

Set the `required` prop of the wrapping Form Field to `true` to indicate that the field is required.
Labels for required fields are suffixed by a red asterisk.

<ExampleCodeBlock code={Required} />

### Icons

`InputGroup` is available to add icons to the `TextInput`. Internally, a container `div` element is
used with relative position styling on the `div` and absolute position styling on the start and end
icons. `InputGroup.InnerStart` and `InputGroup.InnerEnd` are used to position elements at the start
and end of the input. "start" and "end" are used instead of "left" and "right" to match
[CSS Logical Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties)
and will be semantically correct in left-to-right and right-to-left languages.

`InputGroup.InnerStart` and `InputGroup.InnerEnd` subcomponents can handle any child elements, but
are built for icons. The default width is `40px`, which is perfect for icons. If you need to use
something else, be sure to set the `width` property of `InputGroup.InnerStart` or
`InputGroup.InnerEnd` to match the intended width of the element. Do not use the `cs` prop or any
method to change width. The `width` prop is used to correctly position other inner elements.

<ExampleCodeBlock code={Icons} />

> **Accessibility Note**: In this example, the mail icon is decorative and hidden from screen
> readers. If icons are used for conveying meaning in addition to the label text, a text alternative
> must be provided for screen readers.

### Error States

Form Field provides error and caution states for Text Input. Set the `error` prop on Form Field to
`"error"` or `"caution"` and use `FormField.Hint` to provide error messages. See
[Form Field's Error documentation](/components/inputs/form-field/#error-states) for examples and
accessibility guidance.

## Accessibility

`TextInput` should be used with [Form Field](/components/inputs/form-field/) to ensure proper
labeling, error handling, and help text association. See
[FormField's accessibility documentation](/components/inputs/form-field/#accessibility) for
comprehensive guidance on form accessibility best practices.

### Autocomplete Attribute

- Add appropriate `autoComplete` values to indicate the input's purpose (e.g., `"email"`, `"name"`,
  `"street-address"`, `"tel"`). Read more about
  [Identify Input Purpose](https://www.w3.org/WAI/WCAG22/Understanding/identify-input-purpose.html).
- Autocomplete enables browser autofill and helps assistive technologies understand the field's
  purpose, benefiting users with cognitive disabilities and motor impairments.
- Autocomplete also helps password managers identify the correct fields.

### Input Type for Mobile Keyboards

`TextInput` defaults to `<input type="text">`, but for better mobile keyboard support, use more
specific `type` attributes (like `"email"`, `"tel"`, `"url"`, or `"search"`) as needed.

### Screen Reader Experience

When properly implemented with `FormField`, screen readers will announce:

- The label text when the input receives focus.
- Required, disabled, or read-only status.
- Help text and error messages (via `aria-describedby`).
- The current value or "blank" if empty.

## Component API

<SymbolDoc name="TextInput" fileName="/react/" />

<SymbolDoc name="InputGroup" fileName="/react/" />

## Specifications

<Specifications file="./cypress/component/TextInput.spec.tsx" name="TextInput" />