---
title: "टेक्स्ट फ़ील्ड"
description: "लोगों को टेक्स्ट दर्ज और संपादित करने देता है — एक पंक्ति में, या कई पंक्तियों में जो टेक्स्ट के साथ बढ़ती हैं या हाथ से छोटी-बड़ी की जाती हैं — या लोकेल के रूप में इकाई-दर-इकाई दर्ज की जाने वाली तारीख़ या समय, या ठीक वैसे ही रखा गया कोड जैसा वह लिखा गया है, ऐसे लेबल के साथ जो बता सकता है कि फ़ील्ड ज़रूरी है या वैकल्पिक, और वैकल्पिक आइकन, प्रीफ़िक्स और सफ़िक्स, सहायक टेक्स्ट, अक्षरों की गिनती और पिकर बटन के साथ।"
url: "https://tanrei.chnotchy.com/hi/components/text-field/"
last_updated: 2026-10-26T22:31:32.000Z
---

# टेक्स्ट फ़ील्ड

> लोगों को टेक्स्ट दर्ज और संपादित करने देता है — एक पंक्ति में, या कई पंक्तियों में जो टेक्स्ट के साथ बढ़ती हैं या हाथ से छोटी-बड़ी की जाती हैं — या लोकेल के रूप में इकाई-दर-इकाई दर्ज की जाने वाली तारीख़ या समय, या ठीक वैसे ही रखा गया कोड जैसा वह लिखा गया है, ऐसे लेबल के साथ जो बता सकता है कि फ़ील्ड ज़रूरी है या वैकल्पिक, और वैकल्पिक आइकन, प्रीफ़िक्स और सफ़िक्स, सहायक टेक्स्ट, अक्षरों की गिनती और पिकर बटन के साथ।

## अवलोकन

> [!NOTE]
> **संशोधित स्पेक, जो अभी हर प्लैटफ़ॉर्म पर नहीं है**
>
> यह पेज टेक्स्ट फ़ील्ड को वैसा बताता है जैसा स्पेक में वह अभी है: एक `stacked` वेरिएंट, जो डिफ़ॉल्ट है और जिसका लेबल फ़ील्ड के ऊपर रहता है; `filled` और `outlined`, जो सिर्फ़ Material और cupertino प्रीसेट के लिए रखे गए हैं; 32, 40 और 56 की ऊँचाइयाँ (filled या outlined फ़ील्ड की, जिसके भीतर लेबल फ़्लोट होता है, 40, 48 और 56); तारीख़ और समय के टाइप, पिकर बटन के साथ; कई पंक्तियों वाला फ़ील्ड, जो अपने टेक्स्ट के साथ बढ़ता है या हैंडल से छोटा-बड़ा किया जाता है (`resize`); सेगमेंट में इकाई-दर-इकाई दर्ज की जाने वाली तारीख़ या समय; और `required` व `optional`, जो फ़ील्ड को ज़रूरी या वैकल्पिक के रूप में चिह्नित करते हैं। वेब कंपोनेंट यह सब पहले से करता है, और डेमो भी। फ़ील्ड कोड भी रख सकता है (`type="code"`, और उसकी पंक्तियों के लिए `wrap`): वेब ने इसे बना लिया है, और किसी दूसरे प्लैटफ़ॉर्म ने अभी नहीं। टेक्स्ट फ़ील्ड टेक्स्ट इनपुट के चारों ओर का फ़ील्ड है, जैसा यह पेज बताता है: वेब ने यह भी बना लिया है, और वहाँ `required` ऐट्रिब्यूट अब नहीं है। SwiftUI, Compose, Flutter और React Native ऊपर “पीछे” के रूप में चिह्नित हैं: जब तक वे बराबरी पर नहीं आते, वे पिछला संशोधन देते हैं, जो डिफ़ॉल्ट रूप से outlined है और 36 और 40 की ऊँचाई पर है, जिसका `required` फ़्लैग कोई निशान नहीं बनाता, और जिसमें न `stacked` वेरिएंट है, न तारीख़ या समय के टाइप, न पिकर बटन और न resize के मोड। उनके उदाहरण वही संशोधन दिखाते हैं।

जहाँ भी फ़ॉर्म टेक्स्ट माँगता है, वहाँ टेक्स्ट फ़ील्ड इस्तेमाल करें: यह आम स्थिति के लिए है, और इस्तेमाल के लिए तैयार है, लेबल, बॉक्स, सहायता की एक पंक्ति, ग़लत मान के लिए शब्दों और गिनती के साथ।

**किनसे बना है:** एक [फ़ील्ड](https://tanrei.chnotchy.com/hi/components/field/) और एक [टेक्स्ट इनपुट](https://tanrei.chnotchy.com/hi/components/text-input/) से। फ़ील्ड फ़्रेम है: लेबल, ज़रूरी या वैकल्पिक का निशान, सहायता, त्रुटि और गिनती। टेक्स्ट इनपुट कंट्रोल है: बॉक्स, और वह सब जो उसमें टाइप किया जाता है। टेक्स्ट फ़ील्ड अपना कुछ नहीं बनाता और उसका कोई टोकन नहीं है: उसकी हर प्रॉपर्टी इन दोनों में से किसी एक की प्रॉपर्टी है, जो उसी को बिना बदले दे दी जाती है।

यह एक ब्लॉक है, उतना ही चौड़ा जितनी वह जगह जिसमें इसे रखा गया है, और इसका बॉक्स उसे पूरा भरता है। इसकी अपनी कोई चौड़ाई नहीं है: फ़ील्ड कम चौड़ा चाहिए, तो उसे कम चौड़ी जगह दें।

### इस्तेमाल

**Web**

```html
<form>
  <tanrei-text-field name="email" label="ईमेल" type="email" autocomplete="email" required required-text="ज़रूरी"
    supporting-text="हम इसका इस्तेमाल सिर्फ़ आपको साइन इन कराने के लिए करते हैं।"></tanrei-text-field>
  <tanrei-text-field name="company" label="कंपनी" optional optional-text="वैकल्पिक"></tanrei-text-field>
  <!-- 3 से 8 पंक्तियों तक अपने टेक्स्ट के साथ बढ़ता है, फिर स्क्रॉल होता है। -->
  <tanrei-text-field name="message" label="संदेश" multiline min-rows="3" max-rows="8"></tanrei-text-field>
  <!-- हैंडल से, हाथ से छोटा-बड़ा किया जाता है। -->
  <tanrei-text-field name="notes" label="नोट" multiline resize="manual" resize-label="नोट का साइज़ बदलें"></tanrei-text-field>
</form>

<!-- टूलबार में सिर्फ़ बॉक्स: एक टेक्स्ट इनपुट, जिसे नाम उसके अपने label से मिलता है। टेक्स्ट फ़ील्ड को इंपोर्ट करने से वह डिफ़ाइन हो जाता है। -->
<tanrei-text-input label="खोजें" type="search" placeholder="कंपोनेंट खोजें">
  <span slot="leading-icon">search</span>
</tanrei-text-input>

<!-- कोड: पेज की हर दिशा में बाएँ से दाएँ, कोड के टाइपफ़ेस में, जिसे न कभी अपने आप सुधारा जाता है, न जिसकी स्पेलिंग जाँची जाती है। -->
<tanrei-text-field label="पैटर्न" type="code" value="tanrei.comp.button.*.container.color"></tanrei-text-field>
<tanrei-text-field label="वेबहुक की बॉडी" type="code" multiline min-rows="4" supporting-text="JSON"></tanrei-text-field>
<!-- रैप नहीं होता: कोड की हर पंक्ति एक ही पंक्ति में रहती है, और लंबी पंक्ति फ़ील्ड के भीतर स्क्रॉल होती है। -->
<tanrei-text-field label="पंक्तियाँ" type="code" multiline no-wrap></tanrei-text-field>

<!-- लोकेल के क्रम में इकाई-दर-इकाई दर्ज की गई तारीख़, जो 2026-09-27 के रूप में रखी जाती है, पिकर बटन के साथ। -->
<tanrei-text-field id="start" label="शुरू होने की तारीख़" type="date" min="2026-01-01" disabled-dates="2026-05-01 2026-12-25"
  invalid-text="तारीख़ पूरी करें।" unavailable-text="2026 या उसके बाद का कोई कार्य दिवस चुनें।"
  picker picker-label="शुरू होने की तारीख़ चुनें" segment-empty-text="ख़ाली"></tanrei-text-field>
<tanrei-date-time-picker id="start-picker" presentation="docked" anchor="start" label="शुरू होने की तारीख़"></tanrei-date-time-picker>

<script type="module">
  import '@tanrei/web/components/text-field';
  const email = document.querySelector('[name="email"]');
  email.addEventListener('input', () => draft(email.value)); // हर संपादन पर
  email.addEventListener('change', () => save(email.value)); // फ़ोकस हटने या Enter पर, जब मान बदला हो
  // वैलिडेशन आपका काम है: फ़ील्ड ख़ुद कभी error सेट नहीं करता।
  email.error = submitted && !isValid(email.value);
  email.errorText = 'पूरा ईमेल पता दर्ज करें।';

  // फ़ील्ड माँगता है; प्रॉडक्ट पिकर दिखाता है और मान वापस लिखता है।
  const start = document.querySelector('#start');
  const picker = document.querySelector('#start-picker');
  start.addEventListener('pickerrequest', (e) => {
    Object.assign(picker, { value: e.detail.value, min: e.detail.min, max: e.detail.max, disabledDates: start.disabledDates, open: true });
  });
  picker.addEventListener('change', () => (start.value = picker.value));
  picker.addEventListener('close', () => (picker.open = false));
</script>
```

**React**

```tsx
import { TextField } from '@tanrei/react';

<TextField
  label="ईमेल"
  type="email"
  autocomplete="email"
  value={email}
  onInput={(e) => setEmail(e.currentTarget.value)}
  onChange={() => save(email)}
  required
  requiredText="ज़रूरी"
  error={submitted && !isValid(email)}
  errorText="पूरा ईमेल पता दर्ज करें।"
/>

<TextField label="संदेश" multiline minRows={3} maxRows={8} value={message}
  onInput={(e) => setMessage(e.currentTarget.value)} />

// तारीख़: मान ISO 8601 में होता है, या जब तक कोई सेगमेंट ख़ाली है तब तक ख़ाली।
<TextField
  label="शुरू होने की तारीख़"
  type="date"
  min="2026-01-01"
  value={start}
  invalidText="तारीख़ पूरी करें।"
  unavailableText="2026 या उसके बाद की कोई तारीख़ चुनें।"
  segmentEmptyText="ख़ाली"
  picker
  pickerLabel="शुरू होने की तारीख़ चुनें"
  onChange={(e) => setStart(e.currentTarget.value)}
  onEntryError={(e) => report(e.detail.reason)}
  onPickerRequest={() => setPickerOpen(true)}
/>
```

**SwiftUI**

```swift
import Tanrei

TanreiTextField("ईमेल", text: $email, type: .email,
                supportingText: "हम इसका इस्तेमाल सिर्फ़ आपको साइन इन कराने के लिए करते हैं।",
                errorText: "पूरा ईमेल पता दर्ज करें।",
                error: submitted && !isValid(email),
                textContentType: "email", // HTML का ऑटोफ़िल नाम
                onCommit: save,
                // क्रिया यहीं दें: बाहर का .onSubmit, onCommit से पहले चलता है।
                onSubmit: signIn)

// कई पंक्तियों वाला फ़ील्ड, पंक्तियों की सीमा की रेंज के साथ खड़ा अक्ष है।
TanreiTextField("संदेश", text: $message, axis: .vertical, lineLimit: 3...8)
```

**Compose**

```kotlin
import androidx.compose.foundation.text.KeyboardActions
import io.github.chnotchy.tanrei.components.TanreiTextField
import io.github.chnotchy.tanrei.components.TanreiTextFieldType

var email by remember { mutableStateOf("") }
TanreiTextField(
    value = email,
    onValueChange = { email = it },
    label = "ईमेल",
    type = TanreiTextFieldType.Email,
    contentType = "email", // HTML का ऑटोफ़िल नाम
    supportingText = "हम इसका इस्तेमाल सिर्फ़ आपको साइन इन कराने के लिए करते हैं।",
    isError = submitted && !isValid(email),
    errorText = "पूरा ईमेल पता दर्ज करें।",
    onCommit = { save(it) },
    keyboardActions = KeyboardActions(onDone = { signIn() }),
)

// singleLine, स्पेक के multiline का उलटा है।
TanreiTextField(value = message, onValueChange = { message = it }, label = "संदेश", singleLine = false, minLines = 3)
```

**Flutter**

```dart
import 'package:tanrei/tanrei.dart';

TanreiTextField(
  controller: email, // या initialValue: '…'
  labelText: 'ईमेल',
  type: TanreiTextFieldType.email,
  autofillHints: TanreiTextField.autofillHintsFromHtml('email'),
  helperText: 'हम इसका इस्तेमाल सिर्फ़ आपको साइन इन कराने के लिए करते हैं।',
  isError: submitted && !isValid(email.text),
  errorText: 'पूरा ईमेल पता दर्ज करें।',
  onCommit: save,
  onSubmitted: (String value) => signIn(),
);

TanreiTextField(labelText: 'संदेश', multiline: true, minLines: 3);
```

**React Native**

```tsx
import { TextField } from '@tanrei/react-native';

<TextField
  label="ईमेल"
  type="email"
  autoComplete="email"
  value={email}
  onChangeText={setEmail}
  supportingText="हम इसका इस्तेमाल सिर्फ़ आपको साइन इन कराने के लिए करते हैं।"
  error={submitted && !isValid(email)}
  errorText="पूरा ईमेल पता दर्ज करें।"
  onEndEditing={save}
  onSubmitEditing={signIn}
/>
<TextField label="संदेश" multiline minRows={3} value={message} onChangeText={setMessage} />
```

### एक स्तर नीचे

वही फ़ील्ड, उसके दोनों सदस्यों से हाथ से लिखा जाए, तो वैसा ही दिखता है, और सहायक तकनीक के लिए वही टेक्स्ट बॉक्स होता है, उसी नाम, विवरण और स्टेट के साथ:

```html
<tanrei-field label="ईमेल" required required-text="ज़रूरी"
  supporting-text="हम इसका इस्तेमाल सिर्फ़ आपको साइन इन कराने के लिए करते हैं।">
  <tanrei-text-input name="email" type="email" autocomplete="email"></tanrei-text-input>
</tanrei-field>
```

एक स्तर नीचे तब जाएँ जब आपको ऐसी व्यवस्था चाहिए जो टेक्स्ट फ़ील्ड नहीं देता:

| आपको चाहिए | इस्तेमाल करें |
| --- | --- |
| लेबल, बॉक्स, सहायता, त्रुटि और गिनती | टेक्स्ट फ़ील्ड |
| फ़्रेम के भीतर, बॉक्स के बग़ल में या उसके नीचे अपनी कोई चीज़ | एक [फ़ील्ड](https://tanrei.chnotchy.com/hi/components/field/), जिसके भीतर एक [टेक्स्ट इनपुट](https://tanrei.chnotchy.com/hi/components/text-input/) और आपका अपना एलिमेंट है |
| सिर्फ़ बॉक्स, ऐसे लेबल के नीचे जो कहीं और है: टूलबार का फ़िल्टर, टेबल का कोई सेल, ऐसी पंक्ति जिसका लेबल उसके बग़ल में है | अकेला [टेक्स्ट इनपुट](https://tanrei.chnotchy.com/hi/components/text-input/), जिसे नाम उसके अपने `label` से मिलता है |

एक स्तर नीचे जो बदलता है, वह यह है कि कौन-सी बात कहाँ कही जाती है। `name` और `value` टेक्स्ट इनपुट पर होते हैं, जो तब वह कंट्रोल है जो फ़ॉर्म को मिलता है, और उसके इवेंट उसी पर सुने जाते हैं। `label`, `error`, `disabled` और ज़रूरी या वैकल्पिक होना फ़ील्ड पर ही रहते हैं, जो उन्हें कंट्रोल तक पहुँचाता है: इनपुट के अपने सेट न करें।

टेक्स्ट फ़ील्ड एक काम ऐसा करता है जो हाथ से लिखे गए फ़ील्ड और टेक्स्ट इनपुट नहीं करते: वह गिनती को सिंक में रखता है। हाथ से लिखते समय, `counter` सेट हो, तो हर बदलाव पर फ़ील्ड को इनपुट की गिनती दें:

```js
field.countText = input.countText;
input.addEventListener('input', () => (field.countText = input.countText));
```

## स्पेक

### हर सदस्य क्या देता है

| पहलू | फ़ील्ड से | टेक्स्ट इनपुट से |
| --- | --- | --- |
| प्रॉपर्टी | `label`, `labelHidden`, `supportingText`, `errorText`, `error`, `disabled`, `required`, `optional`, `requiredMark`, `requiredText`, `optionalText` | बाक़ी सभी: `variant`, `size`, `type`, `value`, `placeholder`, `readOnly`, पंक्तियाँ और resize, `wrap`, `maxLength`, `counter`, प्रीफ़िक्स और सफ़िक्स, `autocomplete`, और तारीख़ या समय की हर चीज़ |
| इवेंट | — | `input`, `change`, `action`, `pickerRequest`, `entryError` |
| स्लॉट | `label-icon` | `leading-icon`, `trailing-icon` |
| टोकन | `comp.field.*` | बॉक्स के लिए `comp.input-box.*`, जिन्हें हर इनपुट बॉक्स पढ़ता है; `comp.text-input.*` उसके लिए जो सिर्फ़ टेक्स्ट इनपुट बनाता है |

टेक्स्ट इनपुट के अपने `label`, `labelHidden`, `error` और `disabled` होते हैं। टेक्स्ट फ़ील्ड इन्हें सेट नहीं करता: उसका `label` फ़ील्ड का है, जो इनपुट को नाम देता है और filled या outlined फ़ील्ड में वही है जो बॉक्स में फ़्लोट होता है।

### टोकन

टेक्स्ट फ़ील्ड का अपना कोई टोकन नहीं है। उसका बॉक्स [टेक्स्ट इनपुट के टोकन](https://tanrei.chnotchy.com/hi/components/text-input/#%E0%A4%B8%E0%A5%8D%E0%A4%AA%E0%A5%87%E0%A4%95) पढ़ता है, और उसकी पंक्तियाँ, यानी लेबल, निशान, सहायता, त्रुटि और गिनती, [फ़ील्ड के टोकन](https://tanrei.chnotchy.com/hi/components/field/#%E0%A4%B8%E0%A5%8D%E0%A4%AA%E0%A5%87%E0%A4%95) पढ़ती हैं, वे जहाँ भी सेट हों। नीचे की टेबल में फ़ील्ड के टोकन हैं। किसी एक इंस्टेंस को बदलने के लिए, उस पर सदस्य का टोकन सेट करें:

```html
<tanrei-text-field label="ईमेल"
  style="--tanrei-comp-field-label-gap: 12px"></tanrei-text-field>
```

- Category: Text inputs
- Level: composed
- Listing: default
- Built from: Field, Text input
- Page: https://tanrei.chnotchy.com/components/text-field/
- Spec: https://github.com/chnotchy/tanrei/blob/main/specs/text-field.spec.json

### Availability

| Design system | Has it | Notes |
| --- | --- | --- |
| Tanrei (`tanrei`) | Yes | Variants left out: `filled`, `outlined`. |
| Cupertino (Apple HIG-inspired) (`cupertino`) | Yes | — |
| M3 Expressive-like (Material 3 Expressive-inspired) (`m3-expressive-like`) | Yes | — |
| M3-like (Material 3-inspired) (`m3-like`) | Yes | — |

### Platforms

- Web: the element `<tanrei-text-field>`, registered by importing `@tanrei/web` (or only its own module, `@tanrei/web/components/text-field`).
- React: `TextField` from `@tanrei/react`.

| Platform | Name | Status |
| --- | --- | --- |
| Web | `tanrei-text-field` | lagging |
| SwiftUI | `TanreiTextField` | lagging |
| Jetpack Compose | `TanreiTextField` | lagging |
| Flutter | `TanreiTextField` | lagging |
| React Native | `TextField` | lagging |

Names a platform gives in its own idiom:

| Spec | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
| --- | --- | --- | --- | --- | --- |
| `value` (prop) | `value` | `text` | `value` | `controller` | `value` |
| `label` (prop) | `label` | `label` | `label` | `labelText` | `label` |
| `labelHidden` (prop) | `labelHidden` | `labelsHidden` | `labelHidden` | `labelHidden` | `labelHidden` |
| `placeholder` (prop) | `placeholder` | `prompt` | `placeholder` | `hintText` | `placeholder` |
| `supportingText` (prop) | `supportingText` | `supportingText` | `supportingText` | `helperText` | `supportingText` |
| `error` (prop) | `error` | `error` | `isError` | `isError` | `error` |
| `disabled` (prop) | `disabled` | `disabled` | `enabled` | `enabled` | `disabled` |
| `required` (prop) | `required` | `isRequired` | `required` | `required` | `required` |
| `optional` (prop) | `optional` | `isOptional` | `optional` | `optional` | `optional` |
| `multiline` (prop) | `multiline` | `axis` | `singleLine` | `multiline` | `multiline` |
| `minRows` (prop) | `minRows` | `lineLimit` | `minLines` | `minLines` | `minRows` |
| `maxRows` (prop) | `maxRows` | `lineLimit` | `maxLines` | `maxLines` | `maxRows` |
| `resizeLabel` (prop) | `resizeLabel` | `resizeLabel` | `resizeContentDescription` | `resizeSemanticLabel` | `resizeAccessibilityLabel` |
| `wrap` (prop) | `noWrap` | `wrap` | `softWrap` | `softWrap` | `wrap` |
| `counter` (prop) | `counter` | `counter` | `counter` | `showCounter` | `counter` |
| `counterText` (prop) | `counterText` | `counterText` | `counterText` | `counterSemanticText` | `counterAccessibilityText` |
| `counterNoLimitText` (prop) | `counterNoLimitText` | `counterNoLimitText` | `counterNoLimitText` | `counterNoLimitSemanticText` | `counterNoLimitAccessibilityText` |
| `prefixText` (prop) | `prefixText` | `prefix` | `prefix` | `prefixText` | `prefix` |
| `suffixText` (prop) | `suffixText` | `suffix` | `suffix` | `suffixText` | `suffix` |
| `autocomplete` (prop) | `autocomplete` | `textContentType` | `contentType` | `autofillHints` | `autoComplete` |
| `picker` (prop) | `picker` | `onPickerRequest` | `onPickerRequest` | `onPickerRequest` | `onPickerRequest` |
| `pickerLabel` (prop) | `pickerLabel` | `pickerLabel` | `pickerContentDescription` | `pickerSemanticLabel` | `pickerAccessibilityLabel` |
| `input` (event) | `input` | `text` | `onValueChange` | `onChanged` | `onChangeText` |
| `change` (event) | `change` | `onCommit` | `onCommit` | `onCommit` | `onEndEditing` |
| `action` (event) | `action` | `onSubmit` | `keyboardActions` | `onSubmitted` | `onSubmitEditing` |
| `pickerRequest` (event) | `pickerrequest` | `onPickerRequest` | `onPickerRequest` | `onPickerRequest` | `onPickerRequest` |
| `entryError` (event) | `entryerror` | `onEntryError` | `onEntryError` | `onEntryError` | `onEntryError` |
| `resizeEnd` (event) | `resizeend` | `onResizeEnd` | `onResizeEnd` | `onResizeEnd` | `onResizeEnd` |

Statuses: `planned` — In the inventory. Nothing shippable exists yet. `lagging` — An implementation of an earlier spec exists; it has not caught up with the current one. `alpha` — Implemented with tests. The API may still change. `beta` — Feature complete and at parity. Only fixes are expected. `stable` — Covered by semantic versioning. `deprecated` — Still shipped; scheduled for removal.

### Anatomy

- `field`: The Field: the label row with its glyph and its requirement mark, and the supporting row with the help, the error text and the count the text field gives it (TXF-67). In a look whose input floats the label it draws no label row.
- `text-input`: The text input, as the Field's one control: the box and everything typed in it, the icons, the prefix and the suffix, the segments of a date, the picker button, the resize handle, and the label that floats in the box in the looks that float one.

### Props

| Prop | Type | Default | Web attribute | Description |
| --- | --- | --- | --- | --- |
| `variant` | `enum`: `stacked`, `filled`, `outlined` | `"stacked"` | `variant` | Stacked is a filled box that shows focus and error with a line inside its edge and draws no label: the label of the Field that frames it stands above it. Filled and outlined float the label inside the box, marked by a tinted box and a bottom line, or by a border. Use one style per form. A design system may leave some out (the Tanrei system ships stacked only) or add values. (From Text input.) |
| `size` | `enum`: `small`, `medium`, `large` | `"medium"` | `size` | Minimum height of a single-line input's container: stacked 32 / 40 / 56, as tall as a Button of the same size, so that an input and a Button side by side in one row stand as tall as each other; filled and outlined 40 / 48 / 56, which hold the label that floats inside them. Medium and large are for forms; small is for an input in an app bar, a toolbar or a dense row of controls, beside a small select or button. The hit area always meets the minimum target. (From Text input.) |
| `type` | `enum`: `text`, `email`, `password`, `number`, `search`, `tel`, `url`, `code`, `date`, `time`, `date-time` | `"text"` | `type` | What the value is: chooses the keyboard, autocorrection, obscured entry and semantics. code is text written for a machine rather than for a reader — a snippet of configuration, a pattern, an identifier, a query, a key: a left-to-right run in the code face that the platform does not correct, capitalise, check for spelling or complete, on one line or, with multiline, on many. date, time and date-time are entered segment by segment in the locale's numeric form and held as ISO 8601. The value is a string for every type. (From Text input.) |
| `value` | `string` | `""` | `value` | The text in the field; for date, time and date-time, the ISO 8601 form of what its segments give (2026-09-27, 14:30, 2026-09-27T14:30), or empty while a segment is empty or the value is not available. (From Text input.) |
| `label` | `string` | `""` | `label` | Names the control, visibly and to assistive technology. Required, unless the control names itself (a checkbox or a switch with its own label): then leave it empty and the field adds only help and an error. (From Field: Names the text input. In a filled or outlined look the input draws it, floating in its box, and the Field draws no label row (FLD-25, TXI-13).) |
| `labelHidden` | `boolean` | `false` | `label-hidden` | Does not draw the label, which stays the accessible name. For a control whose visible label is elsewhere (a table column, a toolbar). (From Field: Hides the label wherever it would be drawn: the Field's row, or the input's floating label (FLD-25).) |
| `placeholder` | `string` | `""` | `placeholder` | A hint shown while the value is empty and the label is not in the input line (above, floated or hidden). Never a replacement for label. In a code field it is an example of the code and is drawn as code (TXI-53, TXI-54); a hint in words belongs in the supportingText of its Field. Ignored by a date, time or date-time field, whose empty segments each show their own. (From Text input.) |
| `supportingText` | `string` | `""` | `supporting-text` | Help shown below the control and given to assistive technology as the control's description. While the field is in error it gives way to errorText, unless the design system keeps both (comp.field.error-text.placement append). (From Field.) |
| `errorText` | `string` | `""` | `error-text` | Shown while error is true, in supportingText's place — or below it, which then stays, where the design system's comp.field.error-text.placement is append: what is wrong and how to put it right, in words. (From Field.) |
| `error` | `boolean` | `false` | `error` | Puts the field in the error condition: the error text is drawn, the control is exposed as invalid and, where it has an error condition of its own, drawn in it. What a value means is the product's to validate; the field never sets this itself. (From Field: The Field puts its text input in the input's own error condition (FLD-8, TXI-11).) |
| `disabled` | `boolean` | `false` | `disabled` | Disables the control and draws the frame as disabled. Disable a framed control here, not on the control, so that its label follows. (From Field: The Field disables its text input (FLD-14, TXI-5); the text field is then left out of its form (TXF-63).) |
| `readOnly` | `boolean` | `false` | `readonly` | The value can be focused, selected and copied, but not changed. (From Text input.) |
| `required` | `boolean` | `false` | `required` | What the form asks of the control: true exposes it as required and draws the required mark beside the label. It never validates: a missing answer is the product's to report with error. (From Field: The Field exposes its text input as required (FLD-10, TXI-23).) |
| `optional` | `boolean` | `false` | `optional` | Draws the optional tag after the label and adds optionalText to the control's description, because assistive technology has no state for it. Ignored while required is true: a control is never both. (From Field.) |
| `requiredMark` | `enum`: `auto`, `tag`, `asterisk`, `none` | `"auto"` | `required-mark` | How this control shows that it is required: tag is a small filled Tag with requiredText, asterisk is "*" after the label, none draws nothing and keeps the semantics. Auto takes comp.field.requirement.mark, which follows sys.behavior.requirement-mark, the system's one answer. Ignored unless required is true. (From Field.) |
| `requiredText` | `string` | `""` | `required-text` | The text of the required tag, in the product's language ("Required", "必須"). The product's: Tanrei has no word for it. Empty reads the product's words; with neither, FLD-24 says what is drawn. (From Field.) |
| `optionalText` | `string` | `""` | `optional-text` | The text of the optional tag, in the product's language ("Optional", "任意"); also read to assistive technology as part of the description. The product's: Tanrei has no word for it. Empty reads the product's words. (From Field.) |
| `multiline` | `boolean` | `false` | `multiline` | Accepts line breaks and shows several lines, sized as resize says. Ignored for password, date, time and date-time. (From Text input.) |
| `minRows` | `number` | `2` | `min-rows` | The fewest lines a multi-line field shows: the height of an empty auto-resized field, the starting and smallest height of a manually resized one, and the height of a fixed one. (From Text input.) |
| `maxRows` | `number` | `0` | `max-rows` | The most lines an auto-resized field grows to before it scrolls, and the tallest a manually resized one can be made; 0 is no limit. Ignored while resize is fixed. (From Text input.) |
| `resize` | `enum`: `auto`, `manual`, `fixed` | `"auto"` | `resize` | How a multi-line field gets its height. auto: it follows the number of lines between minRows and maxRows, with an animated change, and has no handle. manual: it starts at minRows lines and the person resizes it with the handle in its bottom end corner. fixed: it stays at minRows lines, with no handle. Ignored unless multiline. (From Text input.) |
| `resizeAxis` | `enum`: `vertical`, `both` | `"vertical"` | `resize-axis` | What the person can resize by hand: the height only, or the height and the width. Ignored unless resize is manual. (From Text input.) |
| `resizeLabel` | `string` | `""` | `resize-label` | The accessible name of the resize handle, in the product's language ("Resize"). The product's: Tanrei has no word for it. Empty reads the product's words. Required while the handle is shown. (From Text input.) |
| `wrap` | `boolean` | `true` | — | Whether a multi-line code field continues a line that does not fit on following rows (true), or keeps every line of the code on one row and scrolls sideways inside its container (false) — for code whose lines are read as rows: a table of values, a log, a file in which a line break means something. The value is the same either way. Ignored unless type is code and multiline is true: prose always wraps, and a single line always scrolls in its line. (From Text input.) |
| `maxLength` | `number` | `0` | `maxlength` | The most user-perceived characters the user can enter; 0 is no limit. Ignored for date, time and date-time. (From Text input.) |
| `counter` | `boolean` | `false` | `counter` | Keeps the character count (and maxLength, when set): part of the input's description and announced when typing pauses (TXI-19). The input draws none: a text field gives the count to its Field, which draws it at the end of its supporting row, and a product that frames the input by hand gives it to the Field's countText. (From Text input: The input keeps the count, the text field gives it to its Field, and the Field draws it (TXI-19, TXF-67, FLD-27).) |
| `counterText` | `string` | `""` | `counter-text` | The count said to assistive technology while counter is true and maxLength is greater than 0: the whole sentence in the product's language with three places the input fills — {count} with the characters entered, {limit} with maxLength and {remaining} with how many more can be entered ("{remaining} characters left", "{limit}文字中{count}文字"). Empty reads the product's words; with neither, the count is said as the digits it is drawn in ("12/40"). A sentence that is right for every number, or a prop set per count where the language needs another form for one. (From Text input.) |
| `counterNoLimitText` | `string` | `""` | `counter-no-limit-text` | The count said to assistive technology while counter is true and maxLength is 0: the whole sentence with one place, {count}, filled with the characters entered ("{count} characters", "{count}文字"). Empty reads the product's words; with neither, the count is said as its digits. (From Text input.) |
| `prefixText` | `string` | `""` | `prefix-text` | Fixed text before the value, not part of it. In a code field it is code: drawn in the code face at the left of the value in every layout direction (TXI-53). (From Text input.) |
| `suffixText` | `string` | `""` | `suffix-text` | Fixed text after the value, not part of it. In a code field it is code: drawn in the code face at the right of the value in every layout direction (TXI-53). (From Text input.) |
| `autocomplete` | `string` | `""` | `autocomplete` | The autofill hint, as an HTML autofill field name (email, current-password, new-password, one-time-code, tel, postal-code, …); each platform maps it to its own content type. A code field left without one asks the platform to offer no remembered entry (TXI-55). (From Text input.) |
| `locale` | `string` | `""` | `locale` | A BCP 47 language tag ("en-US", "ja-JP") for how a date, time or date-time field shows and reads its value: the order of the year, month and day segments, the separators, the clock, the digits and the names of the units. Empty uses the platform's current locale. The calendar is the Gregorian calendar in every locale. (From Text input.) |
| `min` | `string` | `""` | `min` | The earliest value a date, time or date-time field accepts from the person, in its ISO 8601 form; empty for no limit. (From Text input.) |
| `max` | `string` | `""` | `max` | The latest value a date, time or date-time field accepts from the person, in its ISO 8601 form; empty for no limit. (From Text input.) |
| `disabledDates` | `strings` | `` | `disabled-dates` | Dates inside min and max that a date or date-time field does not accept from the person, as ISO 8601 calendar dates — the same list the product gives its DateTimePicker. Ignored by a time field. (From Text input.) |
| `invalidText` | `string` | `""` | `invalid-text` | The words for a date, time or date-time input committed with some segments filled and others empty: given to the Field that frames it, which shows them as its error text (TXI-30). (From Text input: Shown by the Field, in its supporting row (FLD-28).) |
| `unavailableText` | `string` | `""` | `unavailable-text` | The words for a date, time or date-time input committed with a value before min, after max or, for a date, listed in disabledDates: given to the Field that frames it, which shows them as its error text (TXI-30). (From Text input: Shown by the Field, in its supporting row (FLD-28).) |
| `segmentEmptyText` | `string` | `""` | `segment-empty-text` | What assistive technology reads as the value of a date or time segment that holds nothing yet, in the product's language ("Empty"). The product's: Tanrei has no word for it. Empty reads the product's words; with neither, an empty segment has no value text. (From Text input.) |
| `picker` | `boolean` | `false` | `picker` | Shows the picker button in a date, time or date-time field. The field presents no picker itself: it emits pickerRequest, and the product presents a DateTimePicker in the matching mode and sets value to what was picked. (From Text input.) |
| `pickerLabel` | `string` | `""` | `picker-label` | The accessible name of the picker button ("Choose date"). Required while picker is shown. (From Text input.) |

### Events

| Event | Description |
| --- | --- |
| `input` | The user changed the value; carries the new value. Emitted for every change, not when the product sets value. A date, time or date-time field emits it when its value changes — when its last segment is filled, a filled field is edited, or it is emptied — not for a segment that leaves the value empty. (From Text input.) |
| `change` | The user committed a changed value (focus left the field, or the action key was pressed in a single-line field); carries the value. (From Text input.) |
| `action` | The user pressed the keyboard's action key (Enter, Return, Go, Search, Done) in a single-line field. (From Text input.) |
| `pickerRequest` | The user activated the picker button of a date, time or date-time field; carries the value, type, min and max. The product presents the picker and sets value to the picked value. (From Text input.) |
| `entryError` | The user committed a date, time or date-time field that is half-filled or whose value is not available; carries the reason (invalid: some segments are empty; unavailable: before min, after max or a listed date) and the text of the row of segments as drawn. The entry error itself is shown by the Field that frames the input (TXI-30). (From Text input.) |
| `resizeEnd` | The person finished changing the size of a field resized by hand: a drag of its handle ended, or a key or an activation of the handle changed the size (TXI-69). Carries lines, the number of lines the input shows, and width, the field's width in pixels WHILE resizeAxis is both (null otherwise). Not emitted when a change of resize, resizeAxis, minRows or maxRows gives the size back. (From Text input.) |

### Slots

| Slot | Description |
| --- | --- |
| `leading-icon` | An icon at the start of the input. (From Text input.) |
| `trailing-icon` | An icon at the end of the input, or the product's own icon-only Button (clear, reveal password). A date or time field's picker button comes after it. (From Text input.) |
| `label-icon` | A glyph before the label. (From Field.) |

### States

`enabled`, `disabled`, `hovered`, `focused`, `error`

### Accessibility

- Role: `textbox`
- Labeling: The text field adds nothing to what its members expose, and the one thing it coordinates — the drawn count (TXF-67) — is kept from assistive technology, which hears the count from the input: the Field gives the text input its name, its description and its required, invalid and disabled states (FLD-8, FLD-10, FLD-11, FLD-14), and the text input carries them on its own element (TXI-23). Assistive technology meets one text box — or, for a date or a time, one group of spin buttons — named by label, exactly as it meets a Field around a text input written by hand.
- Minimum target size: yes

| Keys | Action |
| --- | --- |
| Every key | The text input's (its accessibility block; TXI-3, TXI-41, TXI-43 to TXI-45, TXI-59). The text field handles no key and adds no focus stop (TXF-64). |

- One level down is the same thing: a Field with a text input in it. Every fixture has that pair as its twin, and the accessibility tree of the two is the same (TXF-62). What the pair by hand does not do by itself is keep the Field's count text equal to the input's count as the person types (TXF-67): the product writes it at each input.
- On the web the two members stand in the text field's own shadow root, so the form meets the text field and not the input (TXF-63); focus passes through to the input (TXF-64).

### Behaviour

Requirements in EARS form, each with its stable id.

- **TXF-62** THE text field SHALL be a Field that frames one text input, and nothing else. It SHALL give label, labelHidden, supportingText, errorText, error, disabled, required, optional, requiredMark, requiredText and optionalText to its Field and every other prop to its text input, each unchanged; SHALL hold the label-icon slot for its Field and the leading-icon and trailing-icon slots for its text input; and SHALL emit its text input's events as its own, each once. THE text field SHALL be as wide as the place it stands in, and its text input SHALL fill it: it is a block with no width of its own, as its Field is (FLD-1), around a control that fills the width it is given (TXI-63). It SHALL draw no part of its own, have no token of its own and hold no state of its own but the count it carries from one member to the other (TXF-67): what it shows, how it behaves and what it exposes to assistive technology SHALL be exactly what that Field and that text input do when a product places the one in the other (FLD-1 to FLD-28; TXI-1 to TXI-63), with the Field given the input's count — the label row and its requirement mark (FLD-2 to FLD-6), or the label that floats in the box with the Field's row left out (FLD-25, TXI-13, TXI-50); the supporting row, the error and the count (FLD-7 to FLD-9, FLD-26, FLD-27, TXI-19, TXF-67); the name, the description and the states (FLD-10, FLD-11, FLD-14, TXI-23); and a date's entry error shown in the Field's row (FLD-28, TXI-30).
- **TXF-63** WHERE the platform has forms (the web) THE text field SHALL be the one control the form sees: it SHALL take name, submit its text input's value, reset to the value it was first given, restore it on navigation, report to the form's constraint validation exactly what its text input would report there (TXI-23, TXI-30), and be left out WHILE disabled is true or a disabled group of the form holds it; its text input and its Field SHALL take no part in the form themselves. WHEN the action key asks for the form's submission (TXI-3) the form asked SHALL be the text field's own.
- **TXF-64** WHEN the text field is given focus — by the product, by a press on any part of it that FLD-12 or TXI-8 gives to the input, or by a form that reports its validity — THE text field SHALL pass the focus to its text input (in a date, time or date-time field, to the segment TXI-43 names) and SHALL add no stop to the focus order: the stops inside it are its text input's, in that input's order (an interactive slot element, the picker button, the resize handle). WHILE focus is anywhere inside it THE text field SHALL count as focused for its Field (FLD-13).
- **TXF-65** IF the text field is placed in a Field THE text field SHALL in debug builds report that it is a field already and that the bare control is the text input, and both SHALL still render (FLD-15). WHILE it stands in a field group THE text field SHALL follow that group's disabled, through its own Field, and take nothing else from the group (FGR-20).
- **TXF-66** THE text field SHALL have no words of its own and SHALL read none: requiredText and optionalText are read by its Field (FLD-24), resizeLabel and segmentEmptyText by its text input (TXI-52), each from the instance's prop and then from the product's words.
- **TXF-67** WHILE counter is true THE text field SHALL give its Field, as its count text (FLD-27), the count its text input keeps (TXI-19), as the input writes it, and SHALL give the new one in the same frame in which the value changes — by typing, by a paste, because the product set value or maxLength — without a motion and without an announcement of its own: the input describes and announces its count itself (TXI-19) and the Field keeps the drawn text from assistive technology (FLD-27). WHILE counter is false THE text field SHALL give its Field no count text. THE text field SHALL NOT count, format or write a digit itself.
- **TXF-68** WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE text field SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on the element that carries its role — an id reference by the elements it names in the host's tree or a tree around it, an error message as part of the description while the text field is invalid — except those the text field owns (aria-label, aria-labelledby, aria-disabled), which it SHALL move and not expose: its name is label (TXF-62). WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE text field SHALL take it off that element. WHEN the product sets an aria- attribute the text field owns THE text field SHALL report it in debug builds.

### Tokens

As written in the token documents (DTCG): an alias in braces names the token it takes its value from, which each design system resolves. On the web each token is a CSS custom property: `--tanrei` and the name after `tanrei`, joined by hyphens (`tanrei.comp.field.…` → `--tanrei-comp-field-…`).

#### `tanrei.comp.field`

| Token | Type | Value |
| --- | --- | --- |
| `comp.field.label.typescale` | `typography` | `{tanrei.sys.typescale.label}` |
| `comp.field.label.gap` | `dimension` | `{tanrei.sys.space.space100}` |
| `comp.field.label-icon.size` | `dimension` | `{tanrei.sys.icon.small}` |
| `comp.field.label-icon.gap` | `dimension` | `{tanrei.sys.space.space100}` |
| `comp.field.requirement.mark` | `number` | `{tanrei.sys.behavior.requirement-mark}` |
| `comp.field.requirement.gap` | `dimension` | `{tanrei.sys.space.space100}` |
| `comp.field.requirement.asterisk-gap` | `dimension` | `{tanrei.sys.space.space25}` |
| `comp.field.supporting-text.typescale` | `typography` | `{tanrei.sys.typescale.label-small}` |
| `comp.field.supporting-text.gap` | `dimension` | `{tanrei.sys.space.space50}` |
| `comp.field.counter.gap` | `dimension` | `{tanrei.sys.space.space200}` |
| `comp.field.motion.state-duration` | `duration` | `{tanrei.sys.motion.role.state.default}` |
| `comp.field.motion.state-easing` | `cubicBezier` | `{tanrei.sys.motion.easing.state}` |
| `comp.field.standard.label.color` | `color` | `{tanrei.sys.color.on-surface}` |
| `comp.field.standard.label-icon.color` | `color` | `{tanrei.sys.color.on-surface-variant}` |
| `comp.field.standard.supporting-text.color` | `color` | `{tanrei.sys.color.on-surface-variant}` |
| `comp.field.standard.counter.color` | `color` | `{tanrei.sys.color.on-surface-variant}` |
| `comp.field.standard.required-asterisk.color` | `color` | `{tanrei.sys.color.primary}` |
| `comp.field.standard.error.label.color` | `color` | `{tanrei.sys.color.on-surface}` |
| `comp.field.standard.error.label-icon.color` | `color` | `{tanrei.sys.color.on-surface-variant}` |
| `comp.field.standard.error.supporting-text.color` | `color` | `{tanrei.sys.color.on-surface-variant}` |
| `comp.field.standard.error.counter.color` | `color` | `{tanrei.sys.color.on-surface-variant}` |
| `comp.field.standard.error.required-asterisk.color` | `color` | `{tanrei.sys.color.primary}` |
| `comp.field.standard.error.value-text.color` | `color` | `{tanrei.sys.color.on-surface-variant}` |
| `comp.field.standard.value-text.color` | `color` | `{tanrei.sys.color.on-surface-variant}` |
| `comp.field.standard.error-text.color` | `color` | `{tanrei.sys.color.error}` |
| `comp.field.value-text.typescale` | `typography` | `{tanrei.sys.typescale.label}` |
| `comp.field.value-text.gap` | `dimension` | `{tanrei.sys.space.space200}` |
| `comp.field.error-text.gap` | `dimension` | `{tanrei.sys.space.space50}` |
| `comp.field.error-text.placement` | `number` | `0` |

Per-state tokens, valued by the design system's pattern rules (not written by hand):

- `comp.field.<variant>.<state>.<property>` for the variants `standard`, the states `focused`, `disabled` and the properties `label.color`, `label-icon.color`, `supporting-text.color`, `required-asterisk.color`, `error.label.color`, `error.label-icon.color`, `error.supporting-text.color`, `error.required-asterisk.color`, `counter.color`, `error.counter.color`, `value-text.color`, `error.value-text.color`, `error-text.color`.

### वेब क्या अलग ढंग से बनाता है

- एलिमेंट के शैडो रूट में एक `<tanrei-field>` रहता है, जिसके भीतर एक `<tanrei-text-input>` है, और कुछ नहीं। एलिमेंट को इंपोर्ट करने से दोनों डिफ़ाइन हो जाते हैं।
- एलिमेंट एक ब्लॉक है जो अपनी जगह को पूरा भरता है, ब्राउज़र के अपने टेक्स्ट इनपुट जितना चौड़ा इनलाइन बॉक्स नहीं।
- एलिमेंट फ़ॉर्म से जुड़ा एलिमेंट है। वह `name` और `form` लेता है, मान सबमिट करता है (अक्षम रहते कुछ नहीं), रीसेट होने पर `value` ऐट्रिब्यूट पर लौटता है, नेविगेशन पर बहाल होता है, अक्षम `<fieldset>` के साथ अक्षम होता है, और जब तक `required` सेट है और वह ख़ाली है, फ़ॉर्म को बताता है कि मान नहीं है। उसके दोनों सदस्य फ़ॉर्म में कोई एंट्री नहीं जोड़ते। एक पंक्ति वाले फ़ील्ड में Enter एलिमेंट के फ़ॉर्म के डिफ़ॉल्ट बटन को दबाती है; इसे रोकने के लिए `action` को रद्द करें।
- `input`, `change`, `action`, `pickerrequest` और `entryerror` टेक्स्ट इनपुट के अपने इवेंट हैं। उनका टार्गेट यही एलिमेंट है, और हर लिसनर में `event.target.value` नया मान होता है। detail के टाइप इनपुट के हैं: `TanreiTextInputActionDetail`, `TanreiTextInputPickerRequestDetail` और `TanreiTextInputEntryErrorDetail`।
- भाग: `field` और `text-input` दोनों सदस्य हैं। उनके अपने भागों के नाम यहाँ वही हैं जो एक स्तर नीचे हैं: `label-icon`, `supporting-text`, `counter`; `container`, `outline`, `active-indicator`, `input`, `segment`, `prefix`, `suffix`, `leading-icon`, `trailing-icon`, `picker-button`, `resize-handle`। `label` और `requirement-label` वे हैं जो दिखाए जाते हैं, उन्हें जो भी सदस्य बनाए; `field-label`, `text-input-label`, `field-requirement-label` और `text-input-requirement-label` सिर्फ़ किसी एक सदस्य के भाग के नाम हैं।
- एलिमेंट पर ख़ुद फ़ोकस नहीं जा सकता और उसका कोई रोल नहीं है: `focus()` इनपुट पर जाता है। लेबल की पंक्ति, बॉक्स या फ़्लोट होते लेबल पर दबाने से फ़ोकस इनपुट पर जाता है। सहायता, त्रुटि टेक्स्ट, गिनती या किसी पंक्ति और बॉक्स के बीच की ख़ाली जगह पर दबाने से कुछ नहीं होता।
- उसे `label` से नाम दें, और जहाँ लेबल नहीं दिखाना है वहाँ साथ में `label-hidden` दें। उसे `aria-label` से कभी नाम न दें, जो यहाँ किसी चीज़ को नाम नहीं देता।
- ऐट्रिब्यूट सदस्यों के अपने हैं: kebab-case में, जैसे `supporting-text`, `error-text`, `min-rows` और `no-wrap`, सिवाय `readonly`, `maxlength`, `autocomplete`, `min` और `max` के। `required` ऐट्रिब्यूट नहीं है: `required` लिखें।
- एलिमेंट के डिफ़ाइन होने से पहले उसका कोई साइज़ नहीं होता। ऊँचाई के लिए जगह रखें।

## दिशानिर्देश

### कब इस्तेमाल करें

टेक्स्ट फ़ील्ड तब इस्तेमाल करें जब लोग कोई मान टाइप करते हैं: नाम, ईमेल पता, खोज, संदेश। जब वे मानों के किसी ज्ञात सेट में से चुनते हैं, तो चुनने के लिए बना कंट्रोल इस्तेमाल करें। जहाँ सिर्फ़ बॉक्स चाहिए, क्योंकि लेबल कहीं और है, जैसे टूलबार का फ़िल्टर या टेबल का कोई सेल, वहाँ [टेक्स्ट इनपुट](https://tanrei.chnotchy.com/hi/components/text-input/) इस्तेमाल करें।

### वेरिएंट और साइज़ चुनना

पूरे फ़ॉर्म में एक ही वेरिएंट इस्तेमाल करें।

| वेरिएंट | पहचान | कहाँ |
| --- | --- | --- |
| Stacked (डिफ़ॉल्ट) | बिना किनारे वाले, हल्के रंग के बॉक्स के ऊपर लेबल। फ़ोकस होने पर बॉक्स के किनारे के भीतर एक रेखा बनती है, जिससे कुछ भी नहीं खिसकता; त्रुटि होने पर सामान्य अवस्था में एक पतली रेखा बनती है। | हर सिस्टम। Tanrei सिस्टम सिर्फ़ यही वेरिएंट देता है। |
| Filled | हल्के रंग का बॉक्स और नीचे की रेखा, जिसके भीतर लेबल फ़्लोट होता है | Material और cupertino प्रीसेट |
| Outlined | एक बॉर्डर जो फ़ोकस होने पर मोटा हो जाता है, जिसमें लेबल फ़्लोट होकर बैठ जाता है | Material और cupertino प्रीसेट |

डिफ़ॉल्ट हर सिस्टम में stacked है, प्रीसेट में भी। जिस Material प्रॉडक्ट को Material का फ़्लोट होने वाला लेबल चाहिए, वह अपने फ़ील्ड पर `variant` को `outlined` या `filled` सेट करता है। Tanrei सिस्टम में `filled` और `outlined` फिर भी काम करते हैं, डेवलपमेंट में एक चेतावनी के साथ।

`medium` (40) घना फ़ील्ड है और `large` (56) सामान्य फ़ील्ड। फ़िल्टर और घनी सेटिंग में `medium` इस्तेमाल करें, और साइन-इन और चेकआउट फ़ॉर्म में `large`। `small` (32) छोटे सेलेक्ट की ऊँचाई है, ऐप बार, टूलबार या कंट्रोल की घनी पंक्ति में रखे फ़ील्ड के लिए, जहाँ उसके इनपुट का टेक्स्ट 14 है। डिफ़ॉल्ट सिस्टम में बाक़ी दोनों साइज़ पर इनपुट का टेक्स्ट 16 है। ऊँचाइयाँ न्यूनतम हैं: बड़े टेक्स्ट के साथ फ़ील्ड बढ़ता है, और हिट एरिया हमेशा न्यूनतम टार्गेट पूरा करता है।

### लेबल और प्लेसहोल्डर

- हर फ़ील्ड को एक `label` चाहिए। stacked फ़ील्ड में वह बॉक्स के ऊपर, उसके शुरुआती किनारे से शुरू होकर रहता है, और न कभी खिसकता है, न उसका साइज़ बदलता है; लंबा लेबल काटा नहीं जाता, अगली पंक्ति में चला जाता है। `label-icon` स्लॉट उसके पहले एक ग्लिफ़ रख सकता है। filled या outlined फ़ील्ड में, जब तक फ़ील्ड ख़ाली है, लेबल फ़ील्ड के भीतर रहता है, और फ़ील्ड पर फ़ोकस आने या उसके भरे होने पर फ़्लोट होता है।
- `labelHidden` लेबल को बनाना बंद कर देता है, पर वह एक्सेसिबल नाम बना रहता है, और सहायता और त्रुटि बॉक्स के नीचे ही रहती हैं। जहाँ सिर्फ़ बॉक्स चाहिए, जैसे टूलबार का फ़िल्टर, कोई सेल, या ऐसी पंक्ति जिसका लेबल उसके बग़ल में है, वहाँ इसकी जगह अपने `label` वाला [टेक्स्ट इनपुट](https://tanrei.chnotchy.com/hi/components/text-input/) इस्तेमाल करें।
- प्लेसहोल्डर एक संकेत है, जैसे मान का कोई उदाहरण। वह तब दिखता है जब फ़ील्ड ख़ाली हो और लेबल इनपुट की पंक्ति में न हो: stacked फ़ील्ड में हमेशा, और बाक़ी में सिर्फ़ तब, जब लेबल फ़्लोट हो चुका हो या छिपा हो। वह कभी नाम नहीं होता।

### ज़रूरी और वैकल्पिक

`required` और `optional` बताते हैं कि फ़ॉर्म किसी फ़ील्ड से क्या माँगता है: `required` कि उसे भरना ज़रूरी है, `optional` कि उसे ख़ाली छोड़ा जा सकता है। कोई फ़ील्ड एक साथ दोनों नहीं होता: दोनों सेट हों तो वह ज़रूरी है।

- **ज़रूरी** सहायक तकनीक को फ़ील्ड ज़रूरी के रूप में देता है और लेबल के बग़ल में ज़रूरी का निशान बनाता है।
- **वैकल्पिक** वैकल्पिक का टैग बनाता है और उसका टेक्स्ट फ़ील्ड के विवरण में जोड़ता है।
- **निशान** डिफ़ॉल्ट रूप से stacked लेबल के बाद एक छोटा टैग है: ज़रूरी के लिए filled, वैकल्पिक के लिए tonal। उसके शब्द `requiredText` और `optionalText` हैं, और वे आपके हैं: फ़ील्ड पर, या `setWords()` से पूरे प्रॉडक्ट के लिए एक बार। Tanrei अपना कोई शब्द साथ नहीं देता: `requiredText` के बिना टैग की जगह तारांकन दिखता है, और `optionalText` के बिना कोई टैग नहीं दिखता। वह लेबल की पंक्ति को ऊँचा नहीं करता, और जब लेबल उसके लिए जगह नहीं छोड़ता, तो वह अपनी अलग पंक्ति में चला जाता है।
- **उसकी जगह तारांकन।** ज़रूरी फ़ील्ड कौन-सा निशान बनाता है, यह हर फ़ॉर्म के लिए डिज़ाइन सिस्टम का एक ही चुनाव है, `sys.behavior.requirement-mark`: डिफ़ॉल्ट सिस्टम में टैग, Material प्रीसेट में तारांकन, cupertino में कुछ नहीं। `requiredMark` किसी एक फ़ील्ड के लिए इसे बदल देता है (`tag`, `asterisk`, या `none`, जो सिमैंटिक्स बनाए रखता है और कुछ नहीं बनाता)। filled या outlined फ़ील्ड वहाँ तारांकन बनाता है जहाँ टैग माँगा गया हो।
- **फ़्लोट होते लेबल में वैकल्पिक।** filled या outlined फ़ील्ड में फ़्लोट होते लेबल के बग़ल में वैकल्पिक टैग के लिए जगह नहीं होती: वह इसकी जगह लेबल के बाद `optionalText` को एक शब्द की तरह दिखाता है (“Company Optional”, “कंपनी (वैकल्पिक)”), जो लेबल के साथ टिका रहता है और उसके साथ फ़्लोट होता है। शब्द वैसा ही लिखें जैसा आपके फ़ॉर्म उसे दिखाते हैं, कोष्ठक के साथ या उसके बिना।
- **यह कुछ भी वैलिडेट नहीं करता।** मान न होने पर फ़ील्ड कभी `error` सेट नहीं करता। यह आप करते हैं, `error` और `errorText` से।

फ़ॉर्म में दोनों में से उसे चिह्नित करें जो कम हों: जहाँ ज़्यादातर फ़ील्ड ज़रूरी हैं, वहाँ वैकल्पिक फ़ील्ड चिह्नित करें, और जहाँ ज़्यादातर वैकल्पिक हैं, वहाँ ज़रूरी। अगर आप तारांकन इस्तेमाल करते हैं — और filled या outlined फ़ील्ड ज़रूरी फ़ील्ड के लिए हमेशा करता है — तो फ़ॉर्म में, उसके ऊपरी हिस्से के पास, एक बार बताएँ कि उसका क्या मतलब है (“\* ज़रूरी”): तारांकन एक परिपाटी है, शब्द नहीं, और हर कोई उसे नहीं जानता।

ज़रूरी फ़ील्ड एक निशान दिखाता है: जहाँ आपको निशान नहीं चाहिए, वहाँ `requiredMark` को `none` सेट करें।

### सहायता और त्रुटि का टेक्स्ट

- `supportingText` फ़ील्ड के नीचे सहायता की एक पंक्ति है। इसे फ़ील्ड के विवरण के रूप में भी पढ़ा जाता है।
- वैलिडेशन आपका काम है। जब कोई मान ग़लत हो, तो `error` सेट करें और `errorText` लिखें: फ़ील्ड के त्रुटि में रहते वह सहायक टेक्स्ट की जगह ले लेता है, इसलिए त्रुटि वाला फ़ॉर्म सामान्य से ज़्यादा ऊँचा नहीं होता। जहाँ सहायता की बात अब भी काम की है, उसे इसमें कहें। जो डिज़ाइन सिस्टम सहायता को दिखता रखता है, वह `comp.field.error-text.placement` को `append` पर सेट करता है: तब त्रुटि टेक्स्ट सहायता के नीचे दिखाया जाता है, और त्रुटि में रहते फ़ील्ड एक पंक्ति ज़्यादा ऊँचा होता है ([फ़ील्ड](https://tanrei.chnotchy.com/hi/components/field/) देखें)।
- सिर्फ़ यह नहीं कि मान ग़लत है, यह बताएँ कि उसे कैसे ठीक किया जाए: “पूरा ईमेल पता दर्ज करें।”, न कि “अमान्य”।
- त्रुटि तब दिखाएँ जब व्यक्ति फ़ील्ड छोड़ दे या फ़ॉर्म सबमिट कर दे, तब नहीं जब वह अभी टाइप कर रहा हो।

### काउंटर

- `maxLength` सीमित करता है कि व्यक्ति कितना टाइप कर सकता है। यह अक्षरों को वैसे गिनता है जैसे लोग उन्हें देखते हैं, इसलिए एक इमोजी या मात्रा-चिह्न वाला अक्षर एक ही बार गिना जाता है। पेस्ट किया गया टेक्स्ट सीमा में समाने के लिए छोटा कर दिया जाता है। जो मान आप सेट करते हैं, वह कभी छोटा नहीं किया जाता।
- `counter` सहायक पंक्ति के अंत में गिनती दिखाता है, और `maxLength` सेट होने पर उसके बाद सीमा भी (“12/40”)।
- काउंटर सिर्फ़ तब दिखाएँ जब सीमा व्यक्ति के लिए मायने रखती हो, जैसे दिखने वाला नाम या छोटा परिचय।

### इनपुट के टाइप

`type` कीबोर्ड, ऑटोकरेक्शन और छिपाकर की जाने वाली एंट्री चुनता है। हर टाइप के लिए मान एक स्ट्रिंग है।

| टाइप | कीबोर्ड और व्यवहार |
| --- | --- |
| `text` | सामान्य कीबोर्ड। |
| `email` | ईमेल कीबोर्ड, बिना ऑटोकैपिटलाइज़ेशन या ऑटोकरेक्शन के। |
| `password` | छिपाई हुई, सुरक्षित एंट्री, बिना ऑटोकरेक्शन के। हमेशा एक पंक्ति। |
| `number` | दशमलव सेपरेटर वाला संख्या कीबोर्ड। मान को न पार्स किया जाता है, न राउंड, न वैलिडेट। |
| `search` | सामान्य कीबोर्ड, जिसकी ऐक्शन कुंजी पर खोज लिखा होता है। |
| `tel` | फ़ोन का कीपैड। |
| `url` | URL कीबोर्ड, बिना ऑटोकैपिटलाइज़ेशन या ऑटोकरेक्शन के। |
| `code` | सामान्य कीबोर्ड, और टेक्स्ट के साथ कुछ नहीं किया जाता: न ऑटोकरेक्शन, न ऑटोकैपिटलाइज़ेशन, न स्पेलिंग की जाँच, न किसी अक्षर की जगह कोई दूसरा अक्षर। एक पंक्ति, या `multiline` के साथ कई। [कोड](https://tanrei.chnotchy.com/hi/components/text-field/#%E0%A4%95%E0%A5%8B%E0%A4%A1) देखें। |
| `date`, `time`, `date-time` | तारीख़, समय, या दोनों, जो लोकेल के अंकों वाले रूप में इकाई-दर-इकाई दर्ज किए जाते हैं। हमेशा एक पंक्ति। [तारीख़ और समय](https://tanrei.chnotchy.com/hi/components/text-field/#%E0%A4%A4%E0%A4%BE%E0%A4%B0%E0%A5%80%E0%A4%96%E0%A4%BC-%E0%A4%94%E0%A4%B0-%E0%A4%B8%E0%A4%AE%E0%A4%AF) देखें। |

`autocomplete` में HTML का कोई ऑटोफ़िल नाम (`email`, `current-password`, `one-time-code` …) जोड़ें, ताकि प्लैटफ़ॉर्म फ़ील्ड भर सके। हर प्लैटफ़ॉर्म उसे अपने कॉन्टेंट टाइप से जोड़ता है। तय लंबाई का छोटा कोड, जो सेल में दिखाया जाता है, [वन-टाइम कोड इनपुट](https://tanrei.chnotchy.com/hi/components/one-time-code-input/) है।

### कई पंक्तियाँ

`multiline` लाइन ब्रेक स्वीकार करता है और कई पंक्तियाँ दिखाता है। `resize` बताता है कि फ़ील्ड को उसकी ऊँचाई कैसे मिलती है:

| `resize` | ऊँचाई | हैंडल | `minRows` और `maxRows` |
| --- | --- | --- | --- |
| `auto` (डिफ़ॉल्ट) | पंक्तियों की संख्या के साथ चलती है, एक छोटे मोशन के साथ | नहीं | सबसे कम और सबसे ज़्यादा पंक्तियाँ। सबसे ज़्यादा के बाद यह स्क्रॉल होता है; 0 का मतलब कोई सीमा नहीं |
| `manual` | जितनी व्यक्ति उसे देता है। यह `minRows` से शुरू होता है | निचले कोने में, अंतिम किनारे पर | जितना छोटा और जितना ऊँचा इसे बनाया जा सकता है |
| `fixed` | `minRows` पंक्तियाँ | नहीं | `maxRows` को अनदेखा किया जाता है |

- **Auto** ज़्यादातर फ़ील्ड के लिए ठीक है: टिप्पणी, संदेश, विवरण। जहाँ लंबे टेक्स्ट को फ़ॉर्म के बाक़ी हिस्से को दूर नहीं धकेलना चाहिए, वहाँ `maxRows` सेट करें।
- **Manual** उस टेक्स्ट के लिए ठीक है जिसे व्यक्ति दोबारा पढ़ता और सँवारता है: नोट, लंबा विवरण, कोड। `resizeAxis` डिफ़ॉल्ट रूप से `vertical` है; `both` व्यक्ति को फ़ील्ड की चौड़ाई भी बदलने देता है, उतनी ही जितनी उसका लेआउट होने देता है। साइज़ बना रहता है, और टेक्स्ट उसके भीतर अगली पंक्ति में जाता और स्क्रॉल होता है।
- **Fixed** उस फ़ॉर्म के लिए ठीक है जिसका लेआउट हिलना नहीं चाहिए, जैसे पते का ब्लॉक।
- **हैंडल ड्रैग के बिना भी काम करता है।** वह नीचे के अंतिम कोने में small साइज़ का [हैंडल](https://tanrei.chnotchy.com/hi/components/handle/) है, जो तब तक नहीं दिखता जब तक पॉइंटर फ़ील्ड के ऊपर न आए या फ़ील्ड पर फ़ोकस न हो, और फ़ोकस का एक पड़ाव है, जिसका नाम `resizeLabel` से आता है। ऐरो कुंजियाँ एक-एक पंक्ति से और Page Up और Page Down `minRows` पंक्तियों से साइज़ बदलती हैं, Home और End सबसे छोटे और सबसे ऊँचे साइज़ पर ले जाती हैं, और क्लिक, Enter या Space ऊँचाई को टेक्स्ट के बराबर कर देती है, या जब वह पहले से बराबर हो तो उसे `minRows` पर लौटा देती है। जहाँ `resizeAxis` `both` है, वही क्लिक फ़ील्ड को उसकी जगह जितना चौड़ा भी कर देता है, और अगला क्लिक उसे वह चौड़ाई लौटा देता है जो उसकी थी, ताकि पॉइंटर ड्रैग के बिना भी चौड़ाई बदल सके। उसका टार्गेट न्यूनतम टार्गेट है, हालाँकि उसकी लाइन छोटी है। जब व्यक्ति साइज़ बदल चुका हो, तो फ़ील्ड दिख रही पंक्तियों की संख्या के साथ (और जहाँ वह दोनों तरफ़ छोटा-बड़ा होता है, अपनी चौड़ाई के साथ) `resizeend` फ़ायर करता है, ताकि आप उसका चुना हुआ साइज़ रख सकें। अक्षम फ़ील्ड में हैंडल नहीं होता; सिर्फ़ पढ़ने वाला फ़ील्ड उसे बनाए रखता है, क्योंकि पढ़ने के लिए जगह की ज़रूरत पड़ सकती है।
- **टेक्स्ट के ऊपर कुछ नहीं खिसकता।** कई पंक्तियों वाले फ़ील्ड की पहली पंक्ति वहीं रहती है जहाँ एक पंक्ति वाला फ़ील्ड अपनी पंक्ति बनाता है, और उसके आइकन, प्रीफ़िक्स और सफ़िक्स उसी पंक्ति के बीचोबीच रहते हैं। आगे की हर पंक्ति उसके नीचे रहती है, इसलिए ऊँचाई बदलने पर लेबल और पहली पंक्ति अपनी जगह रहते हैं।

### कोड

`type="code"` उस टेक्स्ट के लिए है जो पाठक के लिए नहीं, मशीन के लिए लिखा जाता है: पैटर्न, आइडेंटिफ़ायर, कुंजी, क्वेरी, JSON या YAML का टुकड़ा। फ़ील्ड वही है, उसी लेबल, सहायता, त्रुटि, काउंटर, साइज़ और फ़ॉर्म के व्यवहार के साथ; बस इनपुट की पंक्ति कोड को ठीक वैसे रखती है जैसा वह लिखा गया है।

- **बाएँ से दाएँ, हर भाषा में।** मान, उसका कैरेट, प्लेसहोल्डर, प्रीफ़िक्स और सफ़िक्स बाएँ से दाएँ चलने वाली एक पंक्ति हैं, जो बाईं ओर से शुरू होती है, दाएँ से बाएँ वाले पेज में भी, और कोड का पहला अक्षर चाहे जो हो: ख़ाली फ़ील्ड, वह फ़ील्ड जिसमें सिर्फ़ `{` है, और वह जिसकी पहली स्ट्रिंग अरबी में है, तीनों एक ही तरह रखे जाते हैं। बाक़ी सब पेज के साथ चलता है: लेबल, आइकन, सहायता या त्रुटि टेक्स्ट, काउंटर और साइज़ हैंडल। दाएँ से बाएँ वाली लिपि की स्ट्रिंग या टिप्पणी अपनी पंक्ति के भीतर ही रखी जाती है और अपने आसपास का क्रम नहीं बदलती।
- **कोड का टाइपफ़ेस, इनपुट के साइज़ पर।** फ़ॉन्ट फ़ैमिली कोड रोल की है; साइज़ और लाइन हाइट इनपुट के ही रहते हैं, इसलिए कोड का फ़ील्ड उतना ही ऊँचा होता है जितना उसके बग़ल का टेक्स्ट फ़ील्ड। हर स्पेस बना रहता है, टैब अक्षर अगले टैब स्टॉप तक पहुँचता है, और कोई दो अक्षर लिगेचर में नहीं जोड़े जाते। किसी चीज़ को उसके अर्थ के हिसाब से रंग नहीं दिया जाता।
- **जैसा है वैसा छोड़ा गया।** प्लैटफ़ॉर्म से कहा जाता है कि वह मान को न सुधारे, न उसके अक्षर बड़े करे, न उसकी स्पेलिंग जाँचे, न उसका अनुवाद करे, न उसे अपने आप पूरा करे, और सीधे उद्धरण चिह्नों को घुमावदार में न बदले। पेस्ट किया गया टेक्स्ट सादा टेक्स्ट होता है, अक्षर-दर-अक्षर। मान को न कभी ट्रिम किया जाता है, न पार्स, न वैलिडेट: वह सही बना है या नहीं, यह बताना आपका काम है, `error` और `errorText` से।
- **एक पंक्ति या कई।** एक पंक्ति पैटर्न या कुंजी के लिए ठीक है। `multiline` के साथ, जो पंक्ति नहीं समाती, वह डिफ़ॉल्ट रूप से अगली पंक्तियों में जारी रहती है; मान में सिर्फ़ कोड के अपने लाइन ब्रेक होते हैं।
- **पंक्तियाँ जो रैप नहीं होतीं।** `wrap` का false होना, जो वेब पर `no-wrap` है, कोड की हर पंक्ति को फ़ील्ड की एक ही पंक्ति में रखता है: मानों की टेबल, लॉग, या ऐसी फ़ाइल के लिए जिसमें लाइन ब्रेक का कोई अर्थ होता है। लंबी पंक्ति फ़ील्ड के भीतर आड़ी स्क्रॉल होती है और कुछ भी चौड़ा नहीं करती। `wrap` को सिर्फ़ कई पंक्तियों वाला कोड फ़ील्ड पढ़ता है: प्रोज़ हमेशा रैप होता है, और अकेली पंक्ति हमेशा अपनी पंक्ति में स्क्रॉल होती है।
- **Tab फ़ोकस आगे ले जाती है।** किसी कुंजी का अर्थ नहीं बदलता: Tab कभी इंडेंट नहीं करती, Enter कोई इंडेंट नहीं जोड़ती, और कोई ब्रैकेट आपके लिए बंद नहीं किया जाता। टैब अक्षर पेस्ट से या आपके प्रॉडक्ट से आता है, और बना रहता है।
- **यह एडिटर नहीं है।** इसमें न सिंटैक्स के रंग हैं, न पंक्ति संख्याएँ, न फ़ोल्डिंग, न पंक्ति-दर-पंक्ति त्रुटि के निशान। जो कोड दिखाया जाता है और टाइप नहीं किया जाता, उसके लिए [कोड ब्लॉक](https://tanrei.chnotchy.com/hi/components/code-block/) इस्तेमाल करें; एडिटर चाहिए तो वही एम्बेड करें जो आपके प्रॉडक्ट ने चुना है।
- **प्लेसहोल्डर कोड का एक उदाहरण है**, जो कोड की तरह दिखाया जाता है। शब्दों में दिया गया संकेत `supportingText` में रहता है, और वहीं फ़ील्ड यह भी बताता है कि उसे क्या चाहिए (“JSON”)।

दाएँ से बाएँ वाले फ़ील्ड में कोड का मान बाईं ओर से शुरू होता है, जबकि `email`, `url`, `tel`, `number` या `password` का मान बाएँ से दाएँ चलता है पर फ़ील्ड के शुरुआती किनारे, यानी दाईं ओर, रहता है। बाक़ी प्लैटफ़ॉर्म ने कोड टाइप अभी नहीं बनाया है।

### तारीख़ और समय

`date`, `time` या `date-time` फ़ील्ड इनपुट की पंक्ति में सेगमेंट की एक क़तार है, हर इकाई के लिए एक: महीना, दिन और साल, घंटा, मिनट और, 12 घंटे वाली घड़ी पर, दिन का हिस्सा। वे लोकेल के क्रम में, उसके सेपरेटर के साथ रहते हैं। फ़ील्ड मान को ISO 8601 में रखता है, बिना टाइम ज़ोन के।

| टाइप | मान | en-US में क़तार | ja-JP में क़तार |
| --- | --- | --- | --- |
| `date` | `2026-09-27` | 09/27/2026 | 2026/09/27 |
| `time` | `14:30` | 2:30 PM | 14:30 |
| `date-time` | `2026-09-27T14:30` | 09/27/2026, 2:30 PM | 2026/09/27 14:30 |

- **लोकेल।** `locale`, या प्लैटफ़ॉर्म का लोकेल, क्रम, सेपरेटर, घड़ी और अंक तय करता है। ख़ाली सेगमेंट अपना प्लेसहोल्डर दिखाता है (“mm”, “dd”, “yyyy”), इसलिए क़तार हमेशा अपना रूप दिखाती है। हर सेगमेंट अपने प्लेसहोल्डर और अपने सबसे चौड़े मान में से जो चौड़ा हो, उतना चौड़ा होता है, इसलिए टाइप करते या मिटाते समय क़तार नहीं खिसकती। ये टाइप `placeholder`, `prefixText`, `suffixText`, `maxLength` और `multiline` को अनदेखा करते हैं।
- **आगे-पीछे जाना।** Tab हर सेगमेंट पर जाती है, फिर पिकर बटन पर। Left और Right Arrow उस ओर के सेगमेंट पर ले जाती हैं, लेआउट की हर दिशा में: क़तार बाएँ से दाएँ लिखी जाती है, जैसे अंकों में तारीख़ लिखी जाती है। किसी सेगमेंट को दबाने पर फ़ोकस उस पर आ जाता है। फ़ोकस वाला सेगमेंट चयनित टेक्स्ट की तरह बनाया जाता है, बिना कैरेट के।
- **एक-एक करके बदलना।** Up और Down Arrow सेगमेंट को एक से बदलती हैं और सिरे पर पहुँचकर दूसरे सिरे से शुरू करती हैं; ख़ाली सेगमेंट पर वे आज की तारीख़ या मौजूदा समय से शुरू करती हैं। Page Up और Page Down बड़े क़दम से बदलती हैं, और Home और End रेंज के सिरों पर ले जाती हैं।
- **टाइप करना।** एक अंक सेगमेंट को भरता है, और जब कोई और अंक उसे आगे नहीं बढ़ा सकता, या जब सेपरेटर टाइप किया जाता है, तो फ़ोकस आगे बढ़ जाता है। Backspace एक अंक हटाती है, और ख़ाली सेगमेंट पर पीछे ले जाती है। साल को चार अंक चाहिए। जो तारीख़ होती ही नहीं, वह दर्ज नहीं की जा सकती: नए चुने गए महीने के अंत से आगे का दिन उस महीने का आख़िरी दिन बन जाता है।
- **पेस्ट करना।** किसी भी सेगमेंट पर पेस्ट की गई पूरी तारीख़ या समय पूरी क़तार भर देता है। उसे लोकेल के क्रम में अंकों के तीन समूहों के रूप में पढ़ा जाता है, और चार अंकों वाला पहला समूह साल के रूप में पढ़ा जाता है, इसलिए पेस्ट की गई ISO तारीख़ हर जगह काम करती है। कॉपी और कट पूरी क़तार लेते हैं।
- **मान** तब तक ख़ाली रहता है जब तक हर सेगमेंट भर न जाए और नतीजा उपलब्ध न हो। `input` तब एमिट होता है जब मान बदलता है — आख़िरी सेगमेंट भरा जाता है, भरी हुई क़तार संपादित की जाती है, या उसे ख़ाली किया जाता है — और उस सेगमेंट के लिए नहीं, जो मान को ख़ाली ही छोड़ता है। `change` तब एमिट होता है जब फ़ोकस फ़ील्ड के सेगमेंट और पिकर बटन से हट जाता है, या ऐक्शन कुंजी दबाई जाती है, और मान बदला हुआ हो। सेगमेंट के बीच जाने से कुछ भी कमिट नहीं होता।
- **एंट्री की त्रुटि।** आधा भरा छोड़ा गया फ़ील्ड `invalidText` दिखाता है। जो फ़ील्ड `min` से पहले के, `max` के बाद के या `disabledDates` में दिए गए मान के साथ छोड़ा गया हो, वह `unavailableText` दिखाता है। दोनों त्रुटि के रूप में बनाए जाते हैं और अपने कारण (`invalid` या `unavailable`) के साथ `entryError` एमिट करते हैं; अगला संपादन उसे ख़त्म कर देता है। यह अकेली त्रुटि है जिसे फ़ील्ड ख़ुद सेट करता है, और वह आपकी `error` प्रॉपर्टी को नहीं छूती।
- **जो आप सेट करते हैं** वह जैसा है वैसा ही दिखाया जाता है, कभी वैलिडेट नहीं किया जाता, और उससे कोई इवेंट एमिट नहीं होता।

फ़ील्ड की घड़ी उसके लोकेल की घड़ी है: उसमें 12 या 24 घंटे की कोई सेटिंग नहीं है और मिनट का कोई स्टेप नहीं है, जैसा DateTimePicker में है।

**पिकर बटन।** `picker` के साथ फ़ील्ड अपने अंत में सिर्फ़ आइकन वाला एक Button बनाता है, तारीख़ के लिए `calendar_month` और समय के लिए `schedule`, जिसका नाम `pickerLabel` से आता है। उसे सक्रिय करने पर मान, टाइप, `min` और `max` के साथ `pickerRequest` एमिट होता है; आधी भरी क़तार ख़ाली मान भेजती है और एंट्री की कोई त्रुटि नहीं दिखाती, क्योंकि पिकर एक पूरा मान देने ही वाला है। फ़ील्ड ख़ुद कुछ नहीं दिखाता: आपका प्रॉडक्ट मेल खाते मोड में एक [DateTimePicker](https://tanrei.chnotchy.com/hi/components/date-time-picker/) खोलता है, जो docked होने पर फ़ील्ड से ऐंकर किया जाता है, और पिकर के `change` से फ़ील्ड का `value` सेट करता है। पिकर को वही `min`, `max` और `disabledDates` दें जो फ़ील्ड के हैं। पिकर बंद होने पर फ़ोकस बटन पर लौटता है। बटन फ़ील्ड के साथ अक्षम होता है और जब फ़ील्ड सिर्फ़ पढ़ने के लिए हो, तब नहीं दिखाया जाता।

### करें

- जो स्थिर टेक्स्ट मान का हिस्सा नहीं है, उसे `prefixText` और `suffixText` में रखें: मुद्रा का चिह्न, इकाई।
- मिटाने या पासवर्ड दिखाने की क्रिया को अंतिम स्लॉट में अपने, सिर्फ़ आइकन वाले Button के रूप में रखें, उसके अपने नाम के साथ। पिकर बटन अकेली क्रिया है जो फ़ील्ड में पहले से बनी है, और वह आपके बटन के बाद आता है।
- जो टेक्स्ट कई पंक्तियों तक जा सकता है, उसके लिए `multiline` इस्तेमाल करें। डिफ़ॉल्ट रूप से यह `minRows` से `maxRows` तक बढ़ता है, फिर स्क्रॉल होता है।
- जिन फ़ील्ड को फ़ॉर्म माँगता है, उन पर `required` सेट करें, और फ़ॉर्म सबमिट होने पर फिर भी `errorText` में बताएँ कि क्या कमी है।
- जिस मान को मशीन पढ़ती है, जैसे पैटर्न, कुंजी या कॉन्फ़िगरेशन का टुकड़ा, उसके लिए `type="code"` इस्तेमाल करें, और लेबल और `supportingText` में बताएँ कि वह क्या होना चाहिए।

### न करें

- प्लेसहोल्डर को लेबल की तरह इस्तेमाल न करें। जैसे ही कोई टाइप करता है, वह ग़ायब हो जाता है।
- जो मान मात्रा नहीं हैं, जैसे कार्ड नंबर या पिन कोड, उनके लिए `number` इस्तेमाल न करें। सही `autocomplete` के साथ `text` इस्तेमाल करें।
- एक फ़ॉर्म में वेरिएंट न मिलाएँ।
- टेक्स्ट फ़ील्ड को फ़ील्ड के भीतर न रखें। वह पहले से एक फ़ील्ड है; डीबग बिल्ड इसकी रिपोर्ट करता है। फ़ील्ड जिस कंट्रोल को फ़्रेम देता है, वह टेक्स्ट इनपुट है।
- तारीख़ के लिए `text` फ़ील्ड और अपनी पार्सिंग इस्तेमाल न करें। `date` इस्तेमाल करें, ताकि लोकेल का क्रम, सेगमेंट की कुंजियाँ और एंट्री की त्रुटि उसके साथ मिलें।
- `required` सेट करने के साथ-साथ लेबल में “(ज़रूरी)” भी न लिखें। निशान यह पहले ही कहता है, और स्क्रीन रीडर इसे दो बार सुनाएगा।
- हाथ से छोटे-बड़े किए जाने वाले फ़ील्ड को लंबा टेक्स्ट देखने का अकेला तरीक़ा न बनने दें। उसे इतने `minRows` दें कि वह खुलते ही काम का हो।
- किसी फ़ील्ड को सिर्फ़ ऐसा मान दिखाने के लिए अक्षम न करें जो बदल नहीं सकता। `readOnly` इस्तेमाल करें, ताकि लोग फिर भी उस पर फ़ोकस ला सकें, उसे चुन सकें और कॉपी कर सकें।
- टेक्स्ट फ़ील्ड पर बाहर से, `::part(input)` या अपने किसी स्टाइल से, कोड का टाइपफ़ेस न लगाएँ, और एलिमेंट में `dir` या `spellcheck` न जोड़ें। `type="code"` इस्तेमाल करें: सिर्फ़ टाइपफ़ेस बदलने से ऐसा फ़ील्ड बनता है जो सही दिखता है, पर टाइप किए गए टेक्स्ट को फिर भी सुधारता रहता है।
- कोड फ़ील्ड को एडिटर की तरह इस्तेमाल न करें, और लंबा कोड दिखाने के लिए अक्षम कोड फ़ील्ड इस्तेमाल न करें: अक्षम फ़ील्ड में कैरेट नहीं होता जिससे उसे स्क्रॉल किया जा सके। `readOnly` इस्तेमाल करें, या कोड ब्लॉक।

## सुलभता

### कंपोनेंट क्या सँभालता है

- टेक्स्ट प्लैटफ़ॉर्म के अपने टेक्स्ट एलिमेंट में संपादित होता है, इसलिए इनपुट मेथड, डिक्टेशन, ऑटोफ़िल, चयन और क्लिपबोर्ड वैसे ही काम करते हैं जैसे प्लैटफ़ॉर्म पर बाक़ी जगह। तारीख़ या समय इसका घोषित अपवाद है: उसके सेगमेंट की क़तार फ़ील्ड की अपनी है।
- तारीख़ या समय का फ़ील्ड एक ग्रुप है, जिसका नाम लेबल से आता है। हर सेगमेंट एक स्पिन बटन है, जिसका नाम उसकी इकाई और लेबल से बनता है (“माह, शुरू होने की तारीख़”), अपनी रेंज और अपने मान के साथ; ख़ाली सेगमेंट `segmentEmptyText` पढ़ता है।
- ज़रूरी फ़ील्ड ज़रूरी के रूप में दिया जाता है। निशान ख़ुद सहायक तकनीक से छिपा रहता है, इसलिए वह दो बार नहीं पढ़ा जाता; वैकल्पिक का टेक्स्ट फ़ील्ड के विवरण के साथ पढ़ा जाता है।
- साइज़ हैंडल फ़ोकस का एक पड़ाव है, जिसका नाम `resizeLabel` से आता है, और जो ऐसे सेपरेटर के रूप में दिया जाता है जिसका मान पंक्तियों की संख्या है। ऐरो कुंजियाँ, Home और End साइज़ बदलती हैं, इसलिए कुछ भी ड्रैग पर निर्भर नहीं करता, और उसका हिट एरिया न्यूनतम टार्गेट पूरा करता है।
- लेबल ही एक्सेसिबल नाम है, चाहे वह दिखाया गया हो या छिपाया गया हो। प्लेसहोल्डर कभी नाम नहीं होता।
- दिखाया जा रहा सहायक या त्रुटि टेक्स्ट और गिनती फ़ील्ड का विवरण हैं। प्रीफ़िक्स और सफ़िक्स भी, जब तक वे दिखते हैं, इसलिए इकाई या मुद्रा मान के साथ पढ़ी जाती है।
- यह सहायक तकनीक को अक्षम स्टेट देता है, और जहाँ प्लैटफ़ॉर्म में हों, वहाँ अमान्य, ज़रूरी और सिर्फ़ पढ़ने वाले स्टेट भी। तारीख़ या समय के फ़ील्ड में एंट्री की त्रुटि ठीक वैसे ही दी जाती है जैसे `error`।
- पिकर बटन एक Button है, जिसका नाम `pickerLabel` से आता है, जो डायलॉग खोलने वाले के रूप में दिया जाता है, और जो आख़िरी सेगमेंट के बाद एक Tab स्टॉप है।
- जब फ़ील्ड पर फ़ोकस रहते हुए कोई त्रुटि आती या बदलती है, तो उसे एक बार, बिना टोके (polite), पढ़कर सुनाया जाता है। गिनती वैसे ही पढ़कर सुनाई जाती है जैसे वह दिखती है (“12/40”), जब टाइपिंग एक सेकंड के लिए रुकती है, हर कीस्ट्रोक पर कभी नहीं।
- खोज फ़ील्ड, जहाँ प्लैटफ़ॉर्म के पास वह रोल है, खोज बॉक्स के रूप में दिया जाता है।
- कोड फ़ील्ड वही टेक्स्ट बॉक्स है जो हर दूसरा टाइप है, और `multiline` के साथ कई पंक्तियों वाला: कोई रोल, रोल का विवरण या शब्द यह नहीं कहता कि उसमें कोड है, और उसके मान का कोई हिस्सा ग़लत स्पेलिंग के रूप में चिह्नित नहीं होता। Tab हमेशा उससे बाहर ले जाती है। जहाँ उसकी पंक्तियाँ रैप नहीं होतीं, वहाँ कैरेट उसे स्क्रॉल करता है, और फ़ोकस कंटेनर पर दिखाया जाता है, जो स्क्रॉल नहीं होता।
- फ़ोकस फ़ील्ड के अपने किनारे से दिखाया जाता है, चाहे वह कीबोर्ड से आया हो या पॉइंटर से: stacked फ़ील्ड के बॉक्स के भीतर एक रेखा, और filled या outlined फ़ील्ड का ज़्यादा मोटा, रंगीन किनारा। हिट एरिया न्यूनतम टार्गेट पूरा करता है।
- लेबल या बॉक्स पर दबाने से फ़ोकस इनपुट पर जाता है और कुछ ऑपरेट नहीं होता। सहायता, त्रुटि टेक्स्ट या गिनती पर दबाने से कुछ नहीं होता।
- नाम, विवरण और स्टेट ठीक वैसे ही जोड़े जाते हैं जैसे फ़ील्ड उन्हें अपने फ़्रेम में रखे किसी भी कंट्रोल से जोड़ता है। एक स्तर नीचे, हाथ से लिखा गया फ़ील्ड वही टेक्स्ट बॉक्स है।
- लेबल का न होना डीबग बिल्ड में रिपोर्ट किया जाता है।

प्लैटफ़ॉर्म की ज्ञात कमियाँ:

- SwiftUI, Compose, Flutter और React Native `required` फ़्लैग रखते हैं, जो कोई निशान नहीं बनाता, और उनमें न resize के मोड हैं, न हैंडल, न सेगमेंट।
- Web: जब महीना या मिनट अपना पहला अंक लेता है, तो सेगमेंट की क़तार कुछ पिक्सल खिसकती है; जहाँ लोकेल के आख़िरी सेगमेंट में दो अंक हैं, वहाँ `input` दो बार फ़ायर हो सकता है; Android के ऑन-स्क्रीन कीबोर्ड पर ख़ाली सेगमेंट पर Backspace पीछे नहीं ले जा सकती; और सँकरे फ़ील्ड से चौड़ी क़तार स्क्रॉल होने की जगह बाहर निकल जाती है।
- प्रॉडक्ट आधी भरी तारीख़ की क़तार को, `value` को वही ख़ाली स्ट्रिंग देकर जो उसके पास पहले से है, ख़ाली नहीं कर सकता।
- Web: ग्लो वाली फ़ोकस शैली में filled फ़ील्ड का ग्लो निचले कोनों पर गोल होता है, जबकि वे कोने चौकोर हैं।
- Web: इनपुट मेथड की कंपोज़िशन और ऑटोफ़िल होने पर लेबल की जाँच सिर्फ़ Chromium में की गई है।
- Web: सिर्फ़ पढ़ने वाला कोड फ़ील्ड, जिसकी पंक्तियाँ रैप नहीं होतीं, कीबोर्ड से वैसे ही स्क्रॉल होता है जैसे ब्राउज़र ऐसे किसी भी टेक्स्ट को स्क्रॉल करता है जिसे वह संपादित नहीं करता: Firefox में कैरेट से, Chrome में ऐरो कुंजियों से, Safari में Option और ऐरो कुंजियों से। पेज की दिशा बदलने पर Firefox ऐसे फ़ील्ड को उसके बाएँ किनारे पर लौटा देता है।
- SwiftUI, Compose, Flutter और React Native ने कोड टाइप नहीं बनाया है: वहाँ `type` में `code` नहीं है और फ़ील्ड में `wrap` नहीं है।
- SwiftUI में अमान्य, ज़रूरी या सिर्फ़ पढ़ने वाले स्टेट नहीं हैं। वे बनाए या लागू किए जाते हैं, पढ़कर सुनाए नहीं जाते। त्रुटि सिर्फ़ विवरण में अपने टेक्स्ट के रूप में सुनाई देती है।
- SwiftUI इनपुट मेथड की कंपोज़िशन को नहीं देख सकता, इसलिए `maxLength` उस टेक्स्ट पर भी लागू होता है जो अभी कंपोज़ हो रहा है, और कंपोज़िशन के दौरान आपका सेट किया हुआ मान रोका नहीं जाता।
- SwiftUI: चयनित टेक्स्ट कैरेट के टिंट में हाइलाइट होता है, फ़ील्ड के चयन के रंग में नहीं।
- SwiftUI सिर्फ़ पढ़ने वाले फ़ील्ड का मान चुने जा सकने वाले टेक्स्ट के रूप में बनाता है, टेक्स्ट फ़ील्ड के रूप में नहीं।
- SwiftUI `.labelsHidden()` को सिर्फ़ iOS 18 और macOS 15 से पढ़ता है। पहले के वर्शन पर लेबल फिर भी दिखाया जाता है।
- React Native इनपुट मेथड की कंपोज़िशन को नहीं देख सकता। कंपोज़िशन के दौरान आपका बदला हुआ मान, और `maxLength` की सीमा, तुरंत लागू होते हैं और कंपोज़िशन को ख़त्म कर सकते हैं।
- React Native में अमान्य, ज़रूरी या सिर्फ़ पढ़ने वाले स्टेट नहीं हैं। त्रुटि सिर्फ़ विवरण में अपने टेक्स्ट के रूप में सुनाई देती है; ज़रूरी होना और सिर्फ़ पढ़ने के लिए होना पढ़कर नहीं सुनाया जाता।
- React Native: पढ़कर सुनाई जाने वाली सूचनाएँ, ऑटोफ़िल और हर टाइप का कीबोर्ड सिर्फ़ मॉक के साथ जाँचे गए हैं, अभी किसी डिवाइस पर नहीं।
- iOS पर React Native में कैरेट और चयन के हाइलाइट के लिए एक ही टिंट है। फ़ील्ड कैरेट का रंग बनाए रखता है, इसलिए हाइलाइट फ़ील्ड के चयन के रंग की जगह उसी का एक टिंट होता है।
- React Native: filled फ़ील्ड का ग्लो सिर्फ़ उसके ऊपरी कोनों के साथ चलता है, और प्लेसहोल्डर और कैरेट के रंग स्टेट के मोशन के दौरान बदलने की जगह एक झटके में बदल जाते हैं।
- Flutter खोज फ़ील्ड को खोज इनपुट टाइप के रूप में देता है, खोज बॉक्स के रोल के रूप में नहीं।
- Flutter Android और दूसरी टच स्क्रीन पर चयन के हैंडल या चयन का टूलबार नहीं बनाता। देर तक दबाना और कीबोर्ड शॉर्टकट फिर भी चुनते और कॉपी करते हैं; iOS अपना सिस्टम मेन्यू दिखाता है।
- Flutter: शुरुआती स्लॉट का इंटरैक्टिव एलिमेंट फ़ोकस के क्रम में इनपुट से पहले आता है, उसके बाद नहीं।
- Compose में ज़रूरी स्टेट नहीं है: उसकी जगह फ़ील्ड अपने स्टेट के विवरण के रूप में “Required” पढ़ता है।
- Compose: `maxLength` और काउंटर अक्षरों को वैसे गिनते हैं जैसे लोग उन्हें देखते हैं, पर इमोजी के सीक्वेंस और झंडों की जाँच नहीं की गई है। टेस्ट JVM पर Robolectric में चलते हैं, जिसके अक्षरों के नियम उन्हें नहीं जानते।
- Compose: TalkBack का त्रुटि और गिनती को पढ़कर सुनाना, असली इनपुट मेथड और असली ऑटोफ़िल सर्विस किसी डिवाइस पर नहीं जाँचे गए हैं।

### आपको क्या करना है

- ऐसा लेबल लिखें जो मान का नाम बताए, और उसे छिपाने पर भी बनाए रखें।
- ऐसा त्रुटि टेक्स्ट लिखें जो बताए कि मान को कैसे ठीक किया जाए, और `error` ख़ुद सेट करें। SwiftUI और React Native पर वही टेक्स्ट त्रुटि के सुनाई देने का अकेला तरीक़ा है। तारीख़ या समय के फ़ील्ड के लिए `invalidText` और `unavailableText` भी लिखें, और `segmentEmptyText` दें: इसके बिना ख़ाली सेगमेंट बिना किसी मान के पढ़ा जाता है।
- पिकर बटन को उसका `pickerLabel` अपने प्रॉडक्ट की भाषा में दें, और पिकर को `pickerRequest` से खोलें।
- `required` या `optional` सेट करें, और `requiredText` और `optionalText` दें: फ़ील्ड पर, या `setWords({ requiredText, optionalText })` से पूरे प्रॉडक्ट के लिए एक बार, जैसे `resizeLabel` और `segmentEmptyText` भी दिए जा सकते हैं। वेब पर Tanrei अपना कोई शब्द साथ नहीं देता; छूटे हुए शब्द की डेवलपमेंट में रिपोर्ट होती है। देखें [प्रॉडक्ट के शब्द](https://tanrei.chnotchy.com/hi/foundations/words/)। जब तक SwiftUI, Compose, Flutter और React Native बराबरी पर नहीं आते, उनके फ़ील्ड कोई निशान नहीं बनाते, और SwiftUI और React Native ज़रूरी स्टेट को पढ़कर नहीं सुनाते: वहाँ लेबल में “ज़रूरी” कहें।
- साइज़ हैंडल को `resizeLabel` से नाम दें। इसके बिना हैंडल दिखता है और काम करता है, पर उसका कोई नाम नहीं होता।
- इकाई या मुद्रा को मान में नहीं, `prefixText` या `suffixText` में रखें, ताकि वह मान के साथ पढ़ी जाए और टाइप न करनी पड़े।
- कोड फ़ील्ड के लिए `label` और `supportingText` में बताएँ कि कोड क्या होना चाहिए (“वेबहुक की बॉडी”, “JSON”), और `errorText` में बताएँ कि उसमें क्या ग़लत है: फ़ील्ड को भाषा का पता नहीं होता।
- अंतिम आइकन बटन को अपने प्रॉडक्ट की भाषा में उसका अपना नाम दें।
- Compose पर “Invalid” और “Required” शब्द लाइब्रेरी के स्ट्रिंग रिसोर्स (`tanrei_invalid`, `tanrei_required`) से आते हैं। उनका अनुवाद करने के लिए उन्हें अपने रिसोर्स में ओवरराइड करें।
- वेब पर iOS Safari उस इनपुट पर ज़ूम कर देता है जिसका टेक्स्ट 16 px से छोटा हो। डिफ़ॉल्ट सिस्टम के फ़ील्ड दोनों साइज़ पर 16 px का टेक्स्ट इस्तेमाल करते हैं; जो लेयर उसे छोटा करती है, वह ज़ूम वापस ले आती है।
