चिप फ़ील्ड
छोटे टेक्स्ट की एक लिस्ट इकट्ठा करता है — ईमेल पते, टेलीफ़ोन नंबर, कीवर्ड — जो एक ही फ़ील्ड में एक के बाद एक टाइप किए जाते हैं। आपकी जाँच जिस टेक्स्ट को स्वीकार करती है, वह एक चिप बन जाता है जिसे हटाया जा सकता है, या बदलने के लिए टाइप करने वाले भाग में वापस रखा जा सकता है, और यह लिस्ट फ़ील्ड का एक ही मान है।
- श्रेणी
- टेक्स्ट इनपुट
- टोकन
comp.field- स्तर
- संयोजित
- इनसे बना है
- Field, Text input, Chip
- Web
tanrei-chip-fieldschedule - SwiftUI
TanreiChipFieldradio_button_unchecked - Jetpack Compose
TanreiChipFieldradio_button_unchecked - Flutter
TanreiChipFieldradio_button_unchecked - React Native
ChipFieldradio_button_unchecked
- वे वेरिएंट जो इनमें शामिल नहीं
- tanrei: filled, outlined
इससे जनरेट किया गया: docs/status/status.json, specs/chip-field.spec.json
दो पतों वाला एक चिप फ़ील्ड, और एक जिसका तीसरा पता माना नहीं गया
चिप फ़ील्ड वहाँ इस्तेमाल करें जहाँ व्यक्ति एक ही प्रकार के कई छोटे टेक्स्ट दर्ज करता है: किसी संदेश को पाने वाले, वे लोग जिनके साथ कोई दस्तावेज़ शेयर किया गया है, वे नंबर जिन पर कोई अलर्ट भेजा जाता है, किसी लेख के कीवर्ड। हर टेक्स्ट अलग से जाँचा जाता है, इसलिए बारह पतों में से एक ग़लत टाइप हुआ पता बाक़ी को नहीं बिगाड़ता, और हर एंट्री अकेले हटाई या बदली जा सकती है।
किनसे बना है: एक फ़ील्ड, एक टेक्स्ट इनपुट और चिप से। फ़ील्ड फ़्रेम है: लेबल, ज़रूरी या वैकल्पिक का निशान, सहायता और त्रुटि। टेक्स्ट इनपुट बॉक्स है, और वह जगह जहाँ अगली एंट्री टाइप की जाती है। हर एंट्री एक छोटी इनपुट चिप है जो बॉक्स में, टाइप किए गए टेक्स्ट से पहले रहती है। चिप फ़ील्ड अपना कुछ नहीं बनाता और उसका कोई टोकन नहीं है, इसलिए हर डिज़ाइन सिस्टम में वह अपने बग़ल के टेक्स्ट फ़ील्ड जैसा दिखता है।
यह उतना ही चौड़ा है जितनी वह जगह जिसमें इसे रखा गया है। एंट्री और टाइप किया गया टेक्स्ट ऐसी पंक्तियों में रहते हैं जो रैप होती हैं, और बॉक्स पूरी-पूरी पंक्तियों में बढ़ता है। हर एंट्री दिखाई जाती है: कोई छिपाई नहीं जाती, “+3” जैसी किसी गिनती में समेटी नहीं जाती और स्क्रॉल होकर नज़र से बाहर नहीं जाती।
वेब पर यह <tanrei-chip-field> है। बाक़ी प्लैटफ़ॉर्म ने इसे अभी इम्प्लीमेंट नहीं किया है।
value एंट्री की लिस्ट है, टेक्स्ट का एक ऐरे। inputValue वह टेक्स्ट है जो टाइप किया गया है और अभी एंट्री नहीं बना है।
टाइप किए गए टेक्स्ट से एंट्री बनती है:
- Enter से;
- उस सेपरेटर से जो आप
separatorsमें देते हैं। डिफ़ॉल्ट रूप से कोई सेपरेटर नहीं है, क्योंकि कॉमा ईमेल पते को ख़त्म करता है और “Lovelace, Ada” का हिस्सा है; - जब फ़ोकस फ़ील्ड से हटता है;
- पेस्ट किए गए उस टेक्स्ट से जिसमें कोई सेपरेटर या लाइन ब्रेक है: हर टुकड़ा क्रम से पेश किया जाता है।
Tanrei नहीं जानता कि ईमेल पता या टेलीफ़ोन नंबर क्या होता है। type कीबोर्ड चुनता है और कुछ नहीं जाँचता। हर संभावित एंट्री आपको check के साथ पेश की जाती है: उसे अस्वीकार करें, तो वह बॉक्स में टेक्स्ट के रूप में रहती है और फ़ील्ड त्रुटि दिखाता है। वही टेक्स्ट दूसरी बार, और maxEntries से आगे का टेक्स्ट, आपसे पूछे बिना अस्वीकार हो जाते हैं।
<form>
<tanrei-chip-field name="to" label="पाने वाले" type="email"
supporting-text="पतों को कॉमा से अलग करें।"
invalid-text="पूरा पता डालें, जैसे [email protected]।"
duplicate-text="यह पहले से लिस्ट में है।"
remove-label="{entry} को हटाएँ"
added-text="{entry} जोड़ा गया" added-count-text="{count} जोड़े गए" removed-text="{entry} हटाया गया"></tanrei-chip-field>
</form>
<script type="module">
import '@tanrei/web/components/chip-field';
const to = document.querySelector('tanrei-chip-field');
to.separators = [',', ';', ' '];
// एक एंट्री के लिए आपकी जाँच, एक पंक्ति में। इवेंट के लौटने से पहले जवाब दें।
to.addEventListener('check', (e) => {
if (!/^\S+@\S+\.\S+$/.test(e.detail.text)) e.preventDefault();
});
// व्यक्ति ने लिस्ट बदली। `value` में नई लिस्ट आ चुकी है।
to.addEventListener('change', (e) => save(e.detail.value));
</script>import { ChipField } from '@tanrei/react';
<ChipField name="to" label="पाने वाले" type="email" separators={[',', ';', ' ']}
supportingText="पतों को कॉमा से अलग करें।"
invalidText="पूरा पता डालें, जैसे [email protected]।"
removeLabel="{entry} को हटाएँ" addedText="{entry} जोड़ा गया" removedText="{entry} हटाया गया"
value={recipients}
onCheck={(event) => { if (!isAddress(event.detail.text)) event.preventDefault(); }}
onChange={(event) => setRecipients(event.detail.value)} />किसी एक अस्वीकृति का कारण अपने शब्दों में देने के लिए, check के लिसनर में event.detail.reason सेट करें। वरना फ़ील्ड कारण के हिसाब से invalidText, duplicateText या limitText दिखाता है, और जहाँ वह ख़ाली है वहाँ errorText। reject आपको अस्वीकार हुआ हर टेक्स्ट, उसका कारण और दिखाए गए शब्द बताता है।
जो एंट्री आपको बाद में ग़लत मिले, जैसे वह पता जिसे सर्वर अनजान बताता है, उसकी बात बताना आपका काम है: error और errorText सेट करें, और शब्दों में उस एंट्री का नाम लें। व्यक्ति उसे हटाता है, या बदलने के लिए उसका टेक्स्ट टाइप करने वाले भाग में वापस रखता है।
| क्या करना है | कैसे |
|---|---|
| टाइप करने वाले भाग से एंट्री तक पहुँचना | टेक्स्ट की शुरुआत में Backspace, या वह ऐरो कुंजी जो पंक्ति की शुरुआत की ओर इशारा करती है |
| एंट्री के बीच आगे-पीछे जाना | Left और Right Arrow, Home और End |
| एंट्री हटाना | उस पर Backspace या Delete, या उसकी हटाने की क्रिया |
| एंट्री बदलना | उस पर Enter या Space, या चिप को दबाना: उसका टेक्स्ट टाइप करने वाले भाग में वापस चला जाता है |
| टाइप करने वाले भाग में लौटना | Escape, Tab, या कोई अक्षर टाइप करना |
पहली Backspace सिर्फ़ आख़िरी एंट्री तक पहुँचती है। दूसरी बार दबाने पर वह हटती है, और दबाकर रखी गई कुंजी का जवाब एक ही बार दिया जाता है, इसलिए टाइप किया गया टेक्स्ट मिटाते-मिटाते लिस्ट कभी नहीं मिटने लगती।
वही फ़ील्ड, अपने सदस्यों से हाथ से लिखा हुआ, वही तस्वीर है:
<tanrei-field label="पाने वाले" supporting-text="पतों को कॉमा से अलग करें।">
<tanrei-text-input type="email">
<tanrei-chip slot="entries" kind="input" size="small" label="[email protected]"
remove-label="[email protected] को हटाएँ"></tanrei-chip>
<tanrei-chip slot="entries" kind="input" size="small" label="[email protected]"
remove-label="[email protected] को हटाएँ"></tanrei-chip>
</tanrei-text-input>
</tanrei-field>वही फ़ील्ड हाथ से लिखा हुआ: एक फ़ील्ड, एक टेक्स्ट इनपुट, और उसके entries स्लॉट में दो चिप
हाथ से लिखे गए सदस्य जो नहीं करते, वही चिप फ़ील्ड जोड़ता है:
| चिप फ़ील्ड क्या जोड़ता है | हाथ से |
|---|---|
| एंट्री बनाना: Enter, सेपरेटर, फ़ोकस का हटना, पेस्ट की गई लिस्ट | आप टेक्स्ट इनपुट को सुनते हैं और टेक्स्ट को टुकड़ों में काटते हैं |
| जाँचें और एंट्री की त्रुटि | आप फ़ील्ड पर error और errorText सेट करते हैं |
| एक Tab स्टॉप और एंट्री के बीच की कुंजियाँ | हर चिप और हर हटाने की क्रिया अपना अलग पड़ाव है; चिप आप हटाते हैं और फ़ोकस आप ले जाते हैं |
| सहायक तकनीक को एक लिस्ट के रूप में दी गई एंट्री, और तीन घोषणाएँ | आप अपनी लिखते हैं |
| फ़ॉर्म में एक मान के रूप में लिस्ट | छिपे हुए इनपुट, या आपका अपना सबमिशन |
एक स्तर नीचे उस व्यवस्था के लिए जाएँ जो चिप फ़ील्ड नहीं देता, जैसे ऐसी एंट्री जो चिप नहीं हैं, या बॉक्स में कोई आइकन।
ज़रूरी, सिर्फ़ पढ़ने के लिए, अक्षम, और ऐसे कीवर्ड जो सिर्फ़ Enter से बनते हैं
| पहलू | फ़ील्ड से | टेक्स्ट इनपुट से | चिप फ़ील्ड का अपना |
|---|---|---|---|
| प्रॉपर्टी | label, labelHidden, supportingText, errorText, error, disabled, required, optional, requiredMark, requiredText, optionalText |
variant, size, type, placeholder, readOnly, autocomplete, और inputValue (टेक्स्ट इनपुट का value) |
value, separators, maxEntries, invalidText, duplicateText, limitText, removeLabel, addedText, addedCountText, removedText |
| इवेंट | — | input, action |
change, check, reject |
| स्लॉट | label-icon |
— | — |
| टोकन | comp.field.* |
बॉक्स के लिए comp.input-box.*; एंट्री की जगह के लिए comp.text-input.* |
कोई नहीं; एंट्री comp.chip.* पढ़ती हैं |
- एंट्री छोटी चिप हैं, बॉक्स के दोनों साइज़ में। लंबी एंट्री अपनी अलग पंक्ति लेती है और चिप उसे काट देती है; उसका पूरा टेक्स्ट उसका नाम और उसका मान बना रहता है। उनकी हटाने की क्रियाएँ सादी हैं, जैसे किसी चिप की डिफ़ॉल्ट रूप से होती हैं: हटाई गई एंट्री फिर से टाइप की जा सकती है।
- प्लेसहोल्डर सिर्फ़ तब तक दिखाया जाता है जब तक लिस्ट ख़ाली है।
- सिर्फ़ पढ़ने के लिए: एंट्री तक पहुँचा जा सकता है और उन्हें पढ़ा जा सकता है, और वे सबमिट होती हैं। कोई एंट्री न बनाई जा सकती है, न हटाई जा सकती है, न टाइप करने वाले भाग में वापस रखी जा सकती है, और हर चिप अपनी हटाने की क्रिया के बिना दिखाई जाती है। फ़ील्ड चिप की अपनी आख़िरी पंक्ति पर ख़त्म होता है: वह टाइप करने के लिए कोई जगह नहीं रखता। अक्षम फ़ील्ड वह जगह रखता है, ताकि फिर से सक्षम होने पर उसका आकार वही रहे।
- अक्षम: फ़ील्ड, बॉक्स और हर चिप अक्षम है, और कुछ सबमिट नहीं होता।
maxEntriesएक और एंट्री कोlimitTextके साथ अस्वीकार करता है। पहले से न कुछ अक्षम होता है, न चिह्नित: सीमाsupportingTextमें बताएँ।typeका मानtext,email,telयाurlहोता है। कोई भी दूसरा टाइपtextकी तरह चलता है।
चिप फ़ील्ड का अपना कोई टोकन नहीं है। किसी एक इंस्टेंस को बदलने के लिए, उस पर किसी सदस्य का टोकन सेट करें:
<tanrei-chip-field label="पाने वाले"
style="--tanrei-comp-text-input-entries-row-gap: 12px"></tanrei-chip-field>संरचना
संरचना
email-empty बनाता है, उसी के ऊपर बनाया गया।| भाग | विवरण |
|---|---|
1 field | The Field: the label row with its glyph and its requirement mark, and the supporting row with the help and the error text. The Field's own, from the Field's tokens. |
2 text-input | The Text input the Field frames: the box, its states, the typing part, and the lines in which its entries and its typing part stand. The Text input's own, from the Text input's tokens. |
3 chip · वैकल्पिक | One entry of the list: an input Chip at its small size, with its remove action, standing in the Text input's box before the typing part. The Chip's own, from the Chip's tokens. |
प्रॉपर्टी
| प्रॉपर्टी | टाइप | डिफ़ॉल्ट | विवरण |
|---|---|---|---|
value | strings | | The entries, in the order they were made: the one value the chip field holds. Each is a text; none is empty, and no two are the same text. The chip field writes it as the person makes, removes and takes back entries, and emits change; what the product sets is shown as given and is not checked (CHF-3). |
inputValue | string | "" | 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. — Text input The text being typed that is not an entry yet. The chip field empties it when the text becomes an entry and writes it when an entry is taken back to be changed (CHF-15). It is never part of value and is never submitted. |
separators | strings | | The texts that end an entry when they are typed or found in what is pasted, as the product names them for what its entries are: a comma, a semicolon and a space for e-mail addresses ([",", ";", " "]); a comma for keywords that may hold a space. Empty, the default: Enter and a line break alone make an entry, because Tanrei knows no grammar of entries and a name such as "Lovelace, Ada" must not be cut in two by a default. |
maxEntries | number | 0 | The most entries the list may hold; 0 is no limit. An entry that would exceed it is refused with the reason limit (CHF-10); the typing part stays usable. It never cuts a list the product sets. |
variant | stacked | filled | outlined | "stacked" | 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. — Text input |
size | small | medium | large | "medium" | 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. — Text input The least height of the box: it grows by whole lines as entries wrap (CHF-18). The entries are small chips at either size. |
type | text | email | password | number | search | tel | url | code | date | time | date-time | "text" | 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. — Text input What one entry is: it chooses the keyboard of the typing part and checks nothing. Only a type the Text input draws as one line of plain text is an entry of a list (text, email, tel, url); any other behaves as text (CHF-26). |
placeholder | string | "" | 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. — Text input Shown only while the list is empty and nothing is typed (CHF-17). |
readOnly | boolean | false | The value can be focused, selected and copied, but not changed. — Text input Also of the entries: none can be made, removed or taken back, and each is drawn without its remove action (CHF-20). |
autocomplete | string | "" | 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). — Text input What the platform fills in is typed text: it becomes an entry as typed text does (CHF-8). |
label | string | "" | 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. — Field Always given. It names the typing part and the list of entries (CHF-21). |
labelHidden | boolean | false | Does not draw the label, which stays the accessible name. For a control whose visible label is elsewhere (a table column, a toolbar). — Field |
supportingText | string | "" | 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). — Field The place to say what an entry is and how one is made ("Separate addresses with a comma."): the chip field has no words for it. |
errorText | string | "" | 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. — Field Also shown while an entry was refused and no text of its own reason is given (CHF-6). |
error | boolean | false | 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. — Field For a reason that is the product's: the list as a whole, or an entry found wrong after it was made. A refused entry needs no setting: the chip field shows that itself (CHF-6). |
disabled | boolean | false | Disables the control and draws the frame as disabled. Disable a framed control here, not on the control, so that its label follows. — Field Also disables every entry (CHF-19). |
required | boolean | false | 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. — Field asks for at least one entry (CHF-25). |
optional | boolean | false | 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. — Field |
requiredMark | auto | tag | asterisk | none | "auto" | 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. — Field |
requiredText | string | "" | 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. — Field |
optionalText | string | "" | 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. — Field |
invalidText | string | "" | The error text shown while an entry was refused by the product's check and the check gave no reason of its own ("Enter a full address, such as [email protected]."). The product's, for this field: what makes an entry right differs from field to field, so it reads no word key. Empty, errorText is shown. |
duplicateText | string | "" | The error text shown while an entry was refused because the list already holds the same text ("That one is already in the list."). Empty reads the product's words; with neither, errorText is shown. |
limitText | string | "" | The error text shown while an entry was refused because the list holds maxEntries already ("No more can be added."). Empty reads the product's words; with neither, errorText is shown. |
removeLabel | string | "" | The accessible name of each entry's remove action. The product writes the whole name in its own language and marks one place in it, {entry}, which the chip field fills with that entry's text ("Remove {entry}", "{entry}を削除"), because the remove action is an element of its own and two of them must be told apart (CHP-18, CHP-28). Empty reads the product's words. Required: with neither, the action is exposed without a name and that is reported. |
addedText | string | "" | The sentence assistive technology is told when one entry is made, with the place {entry} filled by its text ("{entry} added", "{entry}を追加しました"). Empty reads the product's words; with neither, nothing is said and that is reported (CHF-22). |
addedCountText | string | "" | The sentence assistive technology is told when several entries are made at once, from pasted text, with the place {count} filled by how many ("{count} added"). Empty reads the product's words; with neither, addedText is said for the last of them. |
removedText | string | "" | The sentence assistive technology is told when an entry is removed, with the place {entry} filled by its text ("{entry} removed"). Empty reads the product's words; with neither, nothing is said and that is reported (CHF-22). |
स्लॉट
| स्लॉट | विवरण |
|---|---|
label-icon | A glyph before the label. — Field |
इवेंट
| इवेंट | विवरण |
|---|---|
change | The list changed by the person: an entry was made, several were made from pasted text, one was removed, or one was taken back to be changed. Carries the new value, and what was added and what was removed. Not emitted when the product sets value. |
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. — Text input Of the text being typed, never of the list (CHF-16). |
check | Asked of the product once for each candidate entry, before it is made: carries the candidate's text and the entries so far. The product refuses the candidate by answering no — cancelling the event on the web, returning its answer from the callback elsewhere — and may give the reason in its own words; left unanswered, the candidate is accepted. Answered at once, never later. Not asked for what the product sets, nor for a candidate already refused as a duplicate or over the limit. |
reject | A candidate entry was refused; carries its text, the reason (invalid: the product's check; duplicate: the list holds the same text; limit: the list holds maxEntries) and the words shown. Emitted once for each refused candidate. |
action | The user pressed the keyboard's action key (Enter, Return, Go, Search, Done) in a single-line field. — Text input Only while the typing part is empty: the action key pressed on text makes an entry and emits no action (CHF-4, CHF-16). |
स्टेट
व्यवहार
EARS रूप में लिखी गई आवश्यकताएँ। हर प्लैटफ़ॉर्म के इम्प्लीमेंटेशन को इन ID के आधार पर टेस्ट किया जाता है। आवश्यकताओं का पाठ स्पेक फ़ाइल से ज्यों का त्यों, अंग्रेज़ी में दिखाया गया है।
| ID | आवश्यकता |
|---|---|
CHF-1 | THE chip field SHALL be a Field that frames one Text input, with every entry of value drawn as a Chip in the place the Text input keeps inside its box for what was entered already, before the typing part. It SHALL draw nothing of its own: the label row, the requirement mark, the supporting row and the error are the Field's (FLD-1 to FLD-8), the box, its states, its typing part and the lines its entries stand in are the Text input's, and each entry is the Chip's (CHF-2). THE chip field SHALL give the Text input and the Chips no look they do not have anywhere else, and SHALL read no token of its own. THE chip 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); its entries wrap inside that width (CHF-18). |
CHF-2 | THE chip field SHALL draw each entry as a Chip of kind input, size small and the Chip's default variant, whose label is the entry's text and whose remove action is named by removeLabel with its place {entry} filled by that text (CHF-23), in the order of value, the first at the start of the first line. The Chip SHALL be drawn, measured, cut where it does not fit and answered as the Chip's own spec says (CHP-3, CHP-8 to CHP-10, CHP-16 to CHP-18, CHP-20, CHP-21, CHP-27, CHP-32); THE chip field SHALL give an entry no icon and no avatar. |
CHF-3 | WHEN the product sets value THE chip field SHALL show exactly those entries in that order, SHALL NOT ask the product's check about them, apply maxEntries to them or refuse one that is there twice, because the chip field checks what the person enters and the product what it sets, SHALL end an entry error (CHF-6), and SHALL NOT emit change, check or reject nor announce anything; an entry that is empty or only white space SHALL be left out and in debug builds reported. WHEN the product sets inputValue THE chip field SHALL show that text in the typing part and make no entry of it until the person does (CHF-4). IF an entry that has focus is no longer in the list the product set THE chip field SHALL move focus to the typing part. |
CHF-4 | WHILE the typing part holds text THE chip field SHALL offer that text, without the white space at its two ends, as a candidate entry (CHF-5) WHEN the person presses the keyboard's action key (Enter, Return, Done), WHEN a separator is entered (CHF-9), or WHEN focus leaves the chip field for another part of the product — not when focus moves between the typing part and an entry, and not when the window itself loses focus. A candidate that is empty after its ends are trimmed SHALL make no entry, SHALL empty the typing part and SHALL be refused to no one. The action key pressed on text SHALL NOT emit action and SHALL NOT submit a form: it has made an entry. |
CHF-5 | WHEN a candidate entry is offered THE chip field SHALL decide in this order, and stop at the first that refuses: IF value already holds the same text, compared character for character, it SHALL refuse the candidate with the reason duplicate; IF maxEntries is greater than 0 and value holds that many entries it SHALL refuse it with the reason limit (CHF-10); otherwise it SHALL emit check with the candidate and the entries so far and, IF the product refuses it there, refuse it with the reason invalid and the words the product gave, if any. A check that no one answers accepts. THE chip field SHALL wait for no answer that comes later: the product answers check before the event returns. WHEN the candidate is accepted THE chip field SHALL add it at the end of value, empty the typing part of it, keep focus where it is, end an entry error (CHF-6), emit change once with the new list, and announce the entry (CHF-22). |
CHF-6 | WHEN a candidate entry is refused THE chip field SHALL leave its text in the typing part as the person wrote it, with the caret at its end WHILE focus is still there, SHALL NOT add it to value, and SHALL enter an entry error: WHILE it lasts THE chip field SHALL be in the Field's error condition whatever error is (FLD-8), showing as the Field's error text, where FLD-31 puts it (FLD-28), the first of these that is not empty — the words the product's check gave; invalidText, duplicateText or limitText, by the reason; errorText — and SHALL emit reject once with the text, the reason (invalid, duplicate or limit) and the words shown. The Field announces those words as it announces any error under the person's focus (FLD-9), and the chip field SHALL announce nothing more for a refusal. WHERE none of those words is given THE chip field SHALL still mark the typing part invalid and in debug builds report that a refusal has no words. THE entry error SHALL end WHEN the person changes the text in the typing part, WHEN an entry is made, removed or taken back, or WHEN the product sets value or inputValue; it SHALL NOT end because focus leaves, SHALL NOT bring focus back to a field the person left, and SHALL NOT change error, which is the product's. |
CHF-7 | WHILE an input method is composing text in the typing part (TXI-4) THE chip field SHALL make no entry: the action key that commits a composition SHALL commit the composition and nothing else, and a separator inside text that is still being composed SHALL be left to the input method. WHEN the composition is committed THE chip field SHALL read the committed text for separators as it reads any entered text (CHF-9). |
CHF-8 | WHEN text that holds a line break or a separator is pasted, dropped or dictated into the typing part, or filled in by the platform, THE chip field SHALL read it together with the text already there as a row of candidates — cut at every line break and at every separator — and offer each in order (CHF-5), dropping the empty ones without a word; the accepted ones SHALL become entries in that order, change SHALL be emitted once for all of them, and they SHALL be announced once (CHF-22). The refused ones SHALL stay in the typing part in their order, joined by the first of separators followed by a space, or by one space WHERE separators is empty, and THE chip field SHALL enter the entry error of the first that was refused and emit reject for each. A piece after the last line break or separator SHALL be offered with the others when the text was pasted, dropped or filled in, and SHALL stay as typed text when it was typed. Text that holds neither SHALL be the Text input's own to take: it stays typed text and makes no entry. |
CHF-9 | THE chip field SHALL take as separators the texts separators lists, and always a line break. WHEN a separator comes to stand in the typing part by any means the person has — a key, a touch keyboard, a committed composition, dictation — THE chip field SHALL offer the text before it as a candidate (CHF-4), SHALL NOT keep the separator in the typing part or in the entry, and SHALL keep the text after it as typed text; a separator entered while nothing but white space stands before it SHALL be dropped and make no entry. It SHALL find a separator in the text and not by the key that was pressed, so that a keyboard that reports no key still ends an entry. An entry of separators that is empty SHALL be ignored and in debug builds reported; white space is a separator only where the product lists it. |
CHF-10 | WHILE maxEntries is greater than 0 and value holds that many entries THE chip field SHALL keep its typing part focusable and editable, SHALL refuse every candidate with the reason limit (CHF-5, CHF-6), and SHALL NOT disable, hide or mark anything beforehand: that the list is full is said by the product in supportingText and by limitText when one more is tried. WHEN maxEntries is not a whole number of 0 or more THE chip field SHALL behave as 0 and in debug builds report it. THE chip field SHALL draw no count of its entries. |
CHF-11 | THE chip field SHALL be one stop in the focus order: its typing part. WHILE it holds entries THE chip field SHALL take each Chip and each remove action out of the Tab order, in place of the stops CHP-23 gives a chip that stands alone, and SHALL keep each entry reachable from the keyboard by the keys of CHF-12 and CHF-13, by pointer and touch, and as an element of its own by assistive technology. WHILE an entry has focus Tab SHALL move focus to the typing part and Shift+Tab to what stands before the chip field. A press on the box outside every entry SHALL move focus to the typing part as the Text input says (TXI-8); a press on the label does what the Field says (FLD-12). |
CHF-12 | WHILE the typing part has focus, its caret stands at the start of its text and nothing in it is selected, WHEN the person presses the arrow key that points to where the line starts (Left Arrow; Right Arrow in a right-to-left layout) or Backspace THE chip field SHALL move focus to the last entry and remove nothing; WHILE value is empty it SHALL leave the key to the Text input. THE chip field SHALL NOT answer the repeats of a key that is held down: a Backspace held to erase the typed text SHALL stop at the start of the text and never reach an entry. |
CHF-13 | WHILE an entry has focus THE chip field SHALL move focus, without activating or removing anything: on Left Arrow to the entry drawn before it on the left and on Right Arrow to the one drawn after it on the right — in a right-to-left layout the same two keys the other way, so that an arrow always moves the way it points — on Home to the first entry and on End to the last; the arrow that points past the last entry SHALL move focus to the typing part with the caret at the start of its text, the arrow that points before the first entry SHALL do nothing, and focus SHALL NOT wrap. Up Arrow and Down Arrow SHALL do nothing: the entries are one row in their order, however many lines it is drawn on. Escape SHALL move focus to the typing part. WHEN the person types a character while an entry has focus THE chip field SHALL move focus to the typing part and that character SHALL be typed there. Focus that arrives on an entry from the keyboard SHALL show the Chip's focus ring (CHP-4) and bring the entry into view. |
CHF-14 | WHEN an entry's Chip emits remove — Backspace or Delete on the focused entry (CHP-19), or its remove action by pointer, touch or assistive technology (CHP-18) — THE chip field SHALL take that entry out of value, as CHP-22 leaves it to do, end an entry error (CHF-6), emit change once with the new list, and announce the removal (CHF-22). It SHALL then move focus: after Backspace to the entry that stood before the removed one, or to the one that followed WHERE it was the first; after Delete or the remove action to the entry that followed, always on the Chip and never on a remove action; and to the typing part WHERE no entry is left or none follows. THE chip field SHALL NOT answer the repeats of a held Backspace or Delete, so that one press removes one entry. |
CHF-15 | WHEN the person activates an entry's Chip itself — by pointer, touch, Enter or Space (CHP-1), not its remove action — and readOnly is false THE chip field SHALL take the entry back to be changed: it SHALL first offer any text in the typing part as a candidate (CHF-4) and, IF that is refused, do nothing more than CHF-6 says; otherwise it SHALL take the entry out of value, write its text into the typing part with the caret at its end, move focus there, and emit change once with the new list. The text is then typed text like any other: it becomes an entry again, at the end of the list, as CHF-4 says, and is checked again. THE chip field SHALL announce nothing for it: the typing part, focused with its text, is what assistive technology reads. |
CHF-16 | WHEN the person presses the action key while the typing part is empty THE chip field SHALL leave the key to the Text input, which emits action and, on the web, asks for the form's submission (TXI-3); WHEN the person changes the text in the typing part THE chip field SHALL emit input with the new text as the Text input does. THE chip field SHALL emit change only for a change of its list by the person (CHF-5, CHF-8, CHF-14, CHF-15), never for typed text, and never when focus leaves with nothing made. |
CHF-17 | WHILE value holds an entry THE chip field SHALL give the Text input no placeholder, so that a hint for the first entry does not stand after the last; WHILE variant is filled or outlined and value holds an entry the Text input shows its label floated, as it does for a value that is not empty (TXI-13), and THE chip field SHALL hide the Field's label row in those two looks as the text field does. |
CHF-18 | THE chip field SHALL show every entry it holds: it SHALL NOT hide an entry, stand a count in the place of some, scroll its lines or limit its height. The entries and the typing part stand in lines that wrap inside the box, which grows by whole lines from the height of its size, as the Text input says of its entries; an entry whose text is wider than a line SHALL have that line to itself and be cut by the Chip's own rule (CHP-17), its whole text staying its accessible name and its value. WHEN entries come, go or change the lines THE chip field SHALL keep focus where it is and add no motion of its own. |
CHF-19 | WHILE disabled is true THE chip field SHALL disable the Field, and through it the Text input (FLD-14, TXI-5), and every entry's Chip (CHP-2, CHP-6): nothing in it SHALL take focus, no entry SHALL be made, removed or taken back, and it SHALL emit no event; its entries SHALL stay drawn and readable to assistive technology as disabled, and it SHALL be left out of form submission. |
CHF-20 | WHILE readOnly is true and disabled is false THE chip field SHALL make no entry, remove none and take none back: the typing part is the Text input's read-only one (TXI-10), each entry SHALL be drawn as an input Chip without a remove action, a press or a key on an entry SHALL move focus and do nothing else (CHF-13), Backspace and Delete on an entry SHALL do nothing, and check, reject and change SHALL NOT be emitted. The entries SHALL stay reachable by the keys of CHF-12 and CHF-13 so that each can be read, and the list SHALL be submitted with its form. |
CHF-21 | THE chip field SHALL expose to assistive technology, in this order: the entries as one list named by label, each entry an item that holds its Chip — a button named by the entry's whole text — and beside it its remove action, a button named by removeLabel (CHF-2); then the typing part, a text box named by label and described by what the supporting row shows, invalid WHILE the field is in error or in an entry error and required WHILE required is true, all given by the Field (FLD-8, FLD-10, FLD-11). WHILE value is empty it SHALL expose no list. It SHALL add no role, role description or word of its own for being a field of several entries: what an entry is and how one is made is the product's to say in supportingText. |
CHF-22 | THE chip field SHALL hold one live region of its own, polite, empty at rest and not drawn. WHEN one entry is made (CHF-5) it SHALL put into it addedText with {entry} filled by the entry's text; WHEN several are made at once (CHF-8) addedCountText with {count} filled by how many, written as the platform writes a whole number in the language of the field, or addedText for the last of them WHERE addedCountText is not given; WHEN an entry is removed (CHF-14) removedText with {entry} filled by its text. An entry's text SHALL be put into the sentence as plain text of its own direction, isolated from it. A later sentence SHALL replace what the region holds and SHALL NOT queue behind it. THE chip field SHALL announce nothing when the product sets value, when an entry is taken back (CHF-15), or when one is refused (CHF-6: the Field says it). |
CHF-23 | THE chip field SHALL have no words of its own: it SHALL take requiredText and optionalText as the Field does (FLD-24), and duplicateText, limitText, removeLabel, addedText, addedCountText and removedText from the instance's prop and, WHILE that is empty, from the product's words under the key each names, and from nowhere else; invalidText is the instance's alone. It SHALL fill the places {entry} and {count} as a word with places is filled — wherever and however often the product's sentence has them, any other text between braces and a brace that opens or closes nothing left as it is written and in debug builds reported once per page or screen, naming the prop, and a brace written twice drawn as one brace — SHALL say or name with a sentence that has no place exactly as it is written, and in debug builds SHALL report a removeLabel without {entry}, because two remove actions would then have one name. IF neither gives removeLabel THE chip field SHALL still draw the remove action and keep it working, expose it without a name and in debug builds report it; IF neither gives addedText or removedText it SHALL say nothing for that and in debug builds report it. |
CHF-24 | WHERE the platform has forms that collect named values (the web's form) THE chip field SHALL take part in one itself, under its name, as a control that holds several values does: it SHALL submit one value for each entry, in the order of value, each under that same name, and none WHILE the list is empty; SHALL NOT submit the text in the typing part, which is not an entry; SHALL return to the list it was first given WHEN the form is reset, with an empty typing part and no entry error; and SHALL have the platform restore its list where it restores a form's state. Its members stand outside the form and SHALL submit nothing themselves. |
CHF-25 | WHILE required is true THE chip field SHALL expose its typing part as required (FLD-4, FLD-10) and, on the web, report an empty list to the form's constraint validation as a missing value — whatever text stands in the typing part, which is not an entry. THE chip field SHALL NOT validate otherwise because of required: it SHALL NOT set error or show an error text for an empty list, which is the product's to report. |
CHF-26 | THE chip field SHALL take from type only what the Text input gives its typing part for it (TXI-20) and SHALL hold no rule of its own for what an address, a number or a link is: a text of any type becomes an entry unless it is the same as another, exceeds maxEntries or is refused by the product's check (CHF-5). WHEN type names a value other than text, email, tel and url — a type the Text input draws as something else than one line of plain text, or one it does not know — THE chip field SHALL behave as text and in debug builds report it; WHEN variant or size names a value the active design system does not have, the Text input says what is drawn. |
CHF-27 | WHERE the layout direction is right-to-left THE chip field SHALL be mirrored as its members are (FLD-18, TXI-24, CHP-25): every line of entries starts at the right, the typing part follows the last entry to its left, and the order of value, of focus (CHF-13) and of reading (CHF-21) stays the order the entries were made in. THE chip field SHALL take its layout direction from where it is used and have no direction setting of its own (FLD-19); each entry's text keeps its own direction as the Chip says (CHP-31), so that an e-mail address or a telephone number reads left to right inside a right-to-left list. |
CHF-28 | WHILE the text size is enlarged THE chip field SHALL grow with its members (FLD-16, CHP-17): at twice the text size in a place 320 wide every entry SHALL still be shown, each on a line of its own where two no longer fit, cut only by the Chip's own rule with its whole text as its name, the typing part SHALL stay wide enough to type in on a line of its own where the last line leaves it too little, and nothing SHALL lie over another part or need scrolling in two directions. |
CHF-29 | WHERE the platform draws with a person's own forced colors THE chip field SHALL draw nothing of its own there either: the frame is drawn as the Field says (FLD-17) and the box and each entry as the Text input and the Chip are drawn there. It SHALL rely on no color to tell a refused entry from an accepted one: a refused entry is text in the typing part and an accepted one is a Chip, and the reason is in words (CHF-6). |
CHF-30 | WHILE disabled is false and readOnly is false THE chip field SHALL keep every entry's hit areas as the Chip gives them (CHP-5, CHP-21): the remove action's reaches sys.target.touch for touch input and sys.target.pointer for fine pointers, and WHERE the hit areas of neighbouring entries, on one line or on two, overlap THE chip field SHALL give a press on an entry's visible bounds to that entry and a press between two to the nearer one. A press that lands on no entry and no remove action SHALL be the typing part's (CHF-11). |
CHF-31 | 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 chip 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 chip field is invalid — except those the chip field owns (aria-label, aria-labelledby, aria-disabled), which it SHALL move and not expose: its name is label (CHF-21). 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 chip field SHALL take it off that element. WHEN the product sets an aria- attribute the chip field owns THE chip field SHALL report it in debug builds. |
प्लैटफ़ॉर्म के अनुसार नामों का मिलान
पैरिटी का मतलब एक जैसे API नहीं है। हर प्लैटफ़ॉर्म एक ही कॉन्ट्रैक्ट को अपने तरीक़े से व्यक्त करता है।
| स्पेक | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| कंपोनेंट | tanrei-chip-field | TanreiChipField | TanreiChipField | TanreiChipField | ChipField |
value · प्रॉपर्टी | value | entries | entries | entries | value |
inputValue · प्रॉपर्टी | inputValue | text | text | controller | text |
separators · प्रॉपर्टी | separators | separators | separators | separators | separators |
maxEntries · प्रॉपर्टी | maxEntries | maxEntries | maxEntries | maxEntries | maxEntries |
variant · प्रॉपर्टी | variant | variant | variant | variant | variant |
size · प्रॉपर्टी | size | size | size | size | size |
type · प्रॉपर्टी | type | contentType | keyboardType | keyboardType | inputMode |
placeholder · प्रॉपर्टी | placeholder | placeholder | placeholder | placeholder | placeholder |
readOnly · प्रॉपर्टी | readOnly | isReadOnly | readOnly | readOnly | readOnly |
autocomplete · प्रॉपर्टी | autocomplete | .textContentType(_:) | contentType | autofillHints | autoComplete |
label · प्रॉपर्टी | label | label | label | labelText | label |
labelHidden · प्रॉपर्टी | labelHidden | .labelsHidden() | labelHidden | labelHidden | labelHidden |
supportingText · प्रॉपर्टी | supportingText | supportingText | supportingText | helperText | supportingText |
errorText · प्रॉपर्टी | errorText | errorText | errorText | errorText | errorText |
error · प्रॉपर्टी | error | error | isError | error | error |
disabled · प्रॉपर्टी | disabled | .disabled(_:) | enabled | enabled | disabled |
required · प्रॉपर्टी | required | isRequired | required | required | required |
optional · प्रॉपर्टी | optional | isOptional | optional | optional | optional |
requiredMark · प्रॉपर्टी | requiredMark | requiredMark | requiredMark | requiredMark | requiredMark |
requiredText · प्रॉपर्टी | requiredText | requiredText | requiredText | requiredText | requiredText |
optionalText · प्रॉपर्टी | optionalText | optionalText | optionalText | optionalText | optionalText |
invalidText · प्रॉपर्टी | invalidText | invalidText | invalidText | invalidText | invalidText |
duplicateText · प्रॉपर्टी | duplicateText | duplicateText | duplicateText | duplicateText | duplicateText |
limitText · प्रॉपर्टी | limitText | limitText | limitText | limitText | limitText |
removeLabel · प्रॉपर्टी | removeLabel | removeLabel | removeLabel | removeLabel | removeLabel |
addedText · प्रॉपर्टी | addedText | addedText | addedText | addedText | addedText |
addedCountText · प्रॉपर्टी | addedCountText | addedCountText | addedCountText | addedCountText | addedCountText |
removedText · प्रॉपर्टी | removedText | removedText | removedText | removedText | removedText |
change · इवेंट | change | entries (Binding) | onEntriesChange | onChanged | onChange |
input · इवेंट | input | text (Binding) | onTextChange | controller (listener) | onChangeText |
check · इवेंट | check | check: | check | check | check |
reject · इवेंट | reject | onReject: | onReject | onRejected | onReject |
action · इवेंट | action | .onSubmit | onAction | onSubmitted | onSubmitEditing |
| टिप्पणियाँ | <tanrei-chip-field name="to" label="Recipients" type="email" remove-label="Remove {entry}"></tanrei-chip-field>. A composed element: a custom element with a shadow root, form-associated, that holds its members' own elements — <tanrei-field><tanrei-text-input>…<tanrei-chip slot="entries" kind="input" size="small">…</tanrei-text-input></tanrei-field> — and nothing drawn of its own; the host is display: block and as wide as its place (CHF-1); it writes none of their custom properties, exports their documented parts (exportparts; the Chip's under the prefix entry-), passes focus() to the typing part and its label-icon child on to the Field, all as every composed element does (the web package's README, Composed elements). What differs from the one-time-code field: (1) the value is a list — value is an array property; the value attribute is read once, as a JSON array of strings, for markup and the fixture harness, and is not reflected; setFormValue receives a FormData with one entry per value under name, as a <select multiple> submits; formResetCallback and formStateRestoreCallback carry the list; setValidity({ valueMissing }) carries CHF-25. (2) The chips are the element's own children of the Text input's entries slot, wrapped in one element with role="list", aria-label and display: contents, each chip in a role="listitem"; the element sets tabindex="-1" on every chip through the Chip's own way of being held in a set (CHF-11) and moves focus itself. (3) check is a cancelable, composed CustomEvent with detail = { text, values }: event.preventDefault() refuses the candidate and event.detail.reason = "…" gives the words; it is dispatched synchronously and an answer given later is not read. reject has detail = { text, reason, message }, change detail = { value, added, removed }. (4) Separators are found in beforeinput and input (inputType, data, isComposing), never in keydown, and a paste in beforeinput with insertFromPaste; keydown is read for Enter, Backspace, Delete, the arrows, Home, End and Escape only, with event.repeat ignored where CHF-12 and CHF-14 say. (5) The live region of CHF-22 is one visually hidden aria-live="polite" element in the shadow root. Attributes are kebab-case (input-value, max-entries, label-hidden, supporting-text, error-text, required-mark, required-text, optional-text, invalid-text, duplicate-text, limit-text, remove-label, added-text, added-count-text, removed-text) except readonly and autocomplete, which keep HTML's names; separators is an array property whose attribute is read as JSON. The typing part is the Text input's <input type="text"> with the inputmode of type: the browser's own e-mail check is not used and shows no message of its own. Before the element is defined, and without script, it has no size and shows nothing: a page that must not jump gives the tag a block size in its own stylesheet, and a page that must take a list without script writes a plain <input> or <textarea> in its own form and cuts the text on its server, as it would without Tanrei. One level down, by hand: <tanrei-field label="Recipients"><tanrei-text-input type="email"><tanrei-chip slot="entries" kind="input" size="small" label="[email protected]" remove-label="Remove [email protected]"></tanrei-chip></tanrei-text-input></tanrei-field> is the same picture with the same names; making entries, the keys among them, the one Tab stop, the announcements and the list as one form value are what the chip field adds. | TanreiChipField("Recipients", entries: $recipients, text: $pending, separators: [",", ";", " "], check: { text, entries in … }): a view built from TanreiField, TanreiTextInput and TanreiChip. entries is a Binding<[String]> and text an optional Binding<String>; check is a closure that returns .accept, .refuse or .refuse("…") at once. Separators are found in the bound text as it changes, not in key presses; marked text of an input method is left alone until it is committed. The entries are one accessibility container named by the label, each chip and its remove action its own element; arrow keys and Backspace move focus with @FocusState on a hardware keyboard, and VoiceOver reaches each element by its own navigation. Announcements are posted with AccessibilityNotification.Announcement. There is no form to take part in: the bound array is the value. | TanreiChipField(label = "Recipients", entries = recipients, onEntriesChange = { … }, separators = listOf(",", ";", " "), check = { text, entries -> … }): a composable built from TanreiField, TanreiTextInput and TanreiChip. enabled is the inverse flag. check returns EntryCheck.Accept or EntryCheck.Refuse(reason) at once. Separators are found in the text field value as it changes, with its composition range left alone until it is committed. The entries are a semantics collection named by the label; focus among them is moved with FocusRequesters on hardware keys, and TalkBack reaches each chip and its remove action as its own node. Announcements use a polite live region node. The value is the hoisted list; there is no form. | TanreiChipField(labelText: 'Recipients', entries: recipients, onChanged: (entries) { … }, separators: const [',', ';', ' '], check: (text, entries) => …): a widget built from TanreiField, TanreiTextInput and TanreiChip. enabled is the inverse flag; the names follow InputDecoration, as the text field's do. check returns null to accept or a TanreiEntryRefusal (with an optional message) at once. Separators are found in the controller's value outside its composing range. The entries are a Semantics container named by the label; focus among them is moved with FocusNodes and Shortcuts. Announcements use SemanticsService.announce. In a Form it is a FormField<List<String>>. | <ChipField label="Recipients" value={recipients} onChange={setRecipients} separators={[",", ";", " "]} check={(text, entries) => …} />: a component built from Field, TextInput (Tanrei's) and Chip. check returns true, false or a string, the reason, at once. Separators are found in onChangeText, because a touch keyboard reports no key; hardware arrow keys and Backspace among the entries are owed where the platform reports them (whether iOS and Android deliver them to a focused chip is not yet checked on a device), and a screen reader reaches each chip and its remove action as its own element. Announcements use AccessibilityInfo.announceForAccessibility. The value is the controlled list; there is no form. |
टोकन
| टोकन | किसका एलियास | रिज़ॉल्व किया गया मान (लाइट) |
|---|---|---|
--tanrei-comp-field-counter-gap | sys.space.space200 | 16px |
--tanrei-comp-field-error-text-gap | sys.space.space50 | 4px |
--tanrei-comp-field-error-text-placement | — | 0 |
--tanrei-comp-field-label-icon-gap | sys.space.space100 | 8px |
--tanrei-comp-field-label-icon-size | sys.icon.small | 20px |
--tanrei-comp-field-label-gap | sys.space.space100 | 8px |
--tanrei-comp-field-motion-state-duration | sys.motion.role.state.default | 250ms |
--tanrei-comp-field-motion-state-easing | sys.motion.easing.state | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-field-requirement-asterisk-gap | sys.space.space25 | 2px |
--tanrei-comp-field-requirement-gap | sys.space.space100 | 8px |
--tanrei-comp-field-requirement-mark | sys.behavior.requirement-mark | 0 |
--tanrei-comp-field-standard-counter-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-disabled-counter-color | — | |
--tanrei-comp-field-standard-disabled-error-text-color | — | |
--tanrei-comp-field-standard-disabled-error-counter-color | — | |
--tanrei-comp-field-standard-disabled-error-label-icon-color | — | |
--tanrei-comp-field-standard-disabled-error-label-color | — | |
--tanrei-comp-field-standard-disabled-error-required-asterisk-color | — | |
--tanrei-comp-field-standard-disabled-error-supporting-text-color | — | |
--tanrei-comp-field-standard-disabled-error-value-text-color | — | |
--tanrei-comp-field-standard-disabled-label-icon-color | — | |
--tanrei-comp-field-standard-disabled-label-color | — | |
--tanrei-comp-field-standard-disabled-required-asterisk-color | — | |
--tanrei-comp-field-standard-disabled-supporting-text-color | — | |
--tanrei-comp-field-standard-disabled-value-text-color | — | |
--tanrei-comp-field-standard-error-text-color | sys.color.error | |
--tanrei-comp-field-standard-error-counter-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-error-label-icon-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-error-label-color | sys.color.on-surface | |
--tanrei-comp-field-standard-error-required-asterisk-color | sys.color.primary | |
--tanrei-comp-field-standard-error-supporting-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-error-value-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-focused-counter-color | — | |
--tanrei-comp-field-standard-focused-error-text-color | — | |
--tanrei-comp-field-standard-focused-error-counter-color | — | |
--tanrei-comp-field-standard-focused-error-label-icon-color | — | |
--tanrei-comp-field-standard-focused-error-label-color | — | |
--tanrei-comp-field-standard-focused-error-required-asterisk-color | — | |
--tanrei-comp-field-standard-focused-error-supporting-text-color | — | |
--tanrei-comp-field-standard-focused-error-value-text-color | — | |
--tanrei-comp-field-standard-focused-label-icon-color | — | |
--tanrei-comp-field-standard-focused-label-color | — | |
--tanrei-comp-field-standard-focused-required-asterisk-color | — | |
--tanrei-comp-field-standard-focused-supporting-text-color | — | |
--tanrei-comp-field-standard-focused-value-text-color | — | |
--tanrei-comp-field-standard-label-icon-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-label-color | sys.color.on-surface | |
--tanrei-comp-field-standard-required-asterisk-color | sys.color.primary | |
--tanrei-comp-field-standard-supporting-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-value-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-supporting-text-gap | sys.space.space50 | 4px |
--tanrei-comp-field-value-text-gap | sys.space.space200 | 16px |
--tanrei-comp-field-label-typescale | sys.typescale.label | 500 14px/1.4286 |
--tanrei-comp-field-supporting-text-typescale | sys.typescale.label-small | 500 12px/1.3333 |
--tanrei-comp-field-value-text-typescale | sys.typescale.label | 500 14px/1.4286 |
फ़िक्स्चर
मानक रेंडरिंग। हर प्लैटफ़ॉर्म हर फ़िक्स्चर का स्नैपशॉट एक ही ID से लेता है, ताकि नतीजों की तुलना की जा सके।
variant: stacked (24)
email-empty
separators: [",",";"," "] type: email placeholder: [email protected] label: Recipients supportingText: Separate addresses with a comma. removeLabel: Remove {entry} email-entries
value: ["[email protected]","grace.hopper@example… separators: [",",";"," "] type: email label: Recipients removeLabel: Remove {entry} email-typing
value: ["[email protected]","grace.hopper@example… inputValue: alan@exam separators: [",",";"," "] type: email label: Recipients supportingText: Separate addresses with a comma. removeLabel: Remove {entry} email-refused
value: ["[email protected]","grace.hopper@example… inputValue: alan@ separators: [",",";"," "] type: email label: Recipients supportingText: Separate addresses with a comma. errorText: Enter a full address, such as name@examp… error: true removeLabel: Remove {entry} email-error
value: ["[email protected]","grace.hopper@exmaple… separators: [",",";"," "] type: email label: Recipients errorText: [email protected] could not be re… error: true removeLabel: Remove {entry} email-required
value: ["[email protected]"] separators: [",",";"," "] type: email label: Recipients required: true requiredText: Required removeLabel: Remove {entry} email-required-empty-error
separators: [",",";"," "] type: email label: Recipients errorText: Add at least one address. error: true required: true requiredText: Required removeLabel: Remove {entry} email-optional
value: ["[email protected]"] separators: [","] type: email label: Cc optional: true optionalText: Optional removeLabel: Remove {entry} email-limit
value: ["[email protected]","grace.hopper@example… separators: [",",";"," "] maxEntries: 3 type: email label: Recipients supportingText: Up to 3 addresses. removeLabel: Remove {entry} email-many
value: ["[email protected]","grace.hopper@example… separators: [",",";"," "] type: email label: Recipients removeLabel: Remove {entry} email-many-typing
value: ["[email protected]","grace.hopper@example… inputValue: [email protected] separators: [",",";"," "] type: email label: Recipients removeLabel: Remove {entry} email-long-entry
value: ["[email protected]","the-team-that-keeps-… separators: [",",";"," "] type: email label: Recipients removeLabel: Remove {entry} email-large
value: ["[email protected]","grace.hopper@example… separators: [",",";"," "] size: large type: email label: Recipients removeLabel: Remove {entry} email-disabled
value: ["[email protected]","grace.hopper@example… separators: [",",";"," "] type: email label: Recipients supportingText: Separate addresses with a comma. disabled: true removeLabel: Remove {entry} email-disabled-empty
separators: [",",";"," "] type: email label: Recipients disabled: true removeLabel: Remove {entry} email-read-only
value: ["[email protected]","grace.hopper@example… separators: [",",";"," "] type: email readOnly: true label: Recipients removeLabel: Remove {entry} email-label-hidden
value: ["[email protected]"] separators: [",",";"," "] type: email placeholder: [email protected] label: Recipients labelHidden: true removeLabel: Remove {entry} email-label-icon
value: ["[email protected]"] separators: [",",";"," "] type: email label: Recipients removeLabel: Remove {entry} slots: label-icon keywords
value: ["design tokens","accessibility","right-… separators: [","] label: Keywords supportingText: Press Enter or type a comma after each k… removeLabel: Remove {entry} keywords-enter-only
value: ["Lovelace, Ada","Hopper, Grace"] label: Authors supportingText: Press Enter after each name. removeLabel: Remove {entry} telephone
value: ["+81 3 1234 5678","+1 212 555 0100"] separators: [","] type: tel label: Numbers to notify removeLabel: Remove {entry} keywords-ja
value: ["デザイントークン","アクセシビリティ","多言語対応"] separators: ["、",","] label: キーワード supportingText: キーワードごとに Enter を押してください。 required: true requiredText: 必須 removeLabel: {entry}を削除 keywords-rtl
value: ["رموز التصميم","إمكانية الوصول","من الي… separators: ["،",","] label: الكلمات المفتاحية supportingText: اضغط Enter بعد كل كلمة. removeLabel: إزالة {entry} direction: rtl email-rtl
value: ["[email protected]","grace.hopper@example… inputValue: alan@ separators: [",",";"," "] type: email label: נמענים errorText: יש להזין כתובת מלאה, למשל [email protected]… error: true removeLabel: הסרת {entry} direction: rtl variant: filled (2)
email-filled
value: ["[email protected]","grace.hopper@example… separators: [",",";"," "] variant: filled type: email label: Recipients removeLabel: Remove {entry} email-filled-empty
separators: [",",";"," "] variant: filled type: email label: Recipients removeLabel: Remove {entry} variant: outlined (1)
email-outlined
value: ["[email protected]","grace.hopper@example… separators: [",",";"," "] variant: outlined type: email label: Recipients removeLabel: Remove {entry} इससे जनरेट किया गया: specs/chip-field.spec.json, tokens/comp/field.tokens.json, design/tokens/
- एलिमेंट के शैडो रूट में एक
<tanrei-field>रहता है, जिसके भीतर एक<tanrei-text-input>है, और टेक्स्ट इनपुट केentriesस्लॉट में हर एंट्री के लिए एक<tanrei-chip>। एलिमेंट को इंपोर्ट करने से तीनों डिफ़ाइन हो जाते हैं। valueऐरे वाली प्रॉपर्टी है: उसे बदलने के लिए नया ऐरे असाइन करें।valueऐट्रिब्यूट एक बार पढ़ा जाता है, स्ट्रिंग के JSON ऐरे के रूप में, और फ़ॉर्म रीसेट होने पर उसी पर लौटता है।separatorsभी ऐरे है; उसका ऐट्रिब्यूट एक JSON ऐरे है।- यह फ़ॉर्म से जुड़ा एलिमेंट है। वह हर एंट्री के लिए
nameसे एक मान सबमिट करता है, क्रम से, और जब तक लिस्ट ख़ाली है या फ़ील्ड अक्षम है, कुछ नहीं। टाइप किया गया टेक्स्ट कभी सबमिट नहीं होता। वह अक्षम<fieldset>के साथ अक्षम होता है, नेविगेशन पर बहाल होता है, और जब तकrequiredसेट है और लिस्ट ख़ाली है, फ़ॉर्म को बताता है कि मान नहीं है। change,checkऔरrejectCustomEvent हैं, जिन्हें एलिमेंट डिस्पैच करता है: उनकाdetailक्रम से{ value, added, removed },{ text, values }और{ text, reason, message }है।checkरद्द किया जा सकता है और उसके लौटते ही पढ़ा जाता है: बाद में दिया गया जवाब नहीं पढ़ा जाता।inputऔरactionटेक्स्ट इनपुट के अपने हैं।actionसिर्फ़ तब फ़ायर होता है जब टाइप करने वाला भाग ख़ाली हो और Enter दबाई जाए, और तब वह फ़ॉर्म से सबमिट होने को कहता है। टेक्स्ट पर Enter एंट्री बनाती है: कुंजी टेक्स्ट इनपुट के सुनने से पहले रोक ली जाती है, इसलिए बबलिंग फ़ेज़ काkeydownलिसनर वह दबाना नहीं सुनता।- भाग:
field,text-inputऔरchipसदस्य हैं। फ़ील्ड और टेक्स्ट इनपुट के अपने भाग अपने नाम रखते हैं (label,supporting-text,container,input,entriesवग़ैरह)। चिप के भागentry-container,entry-labelऔरentry-removeहैं। - एलिमेंट पर ख़ुद फ़ोकस नहीं जा सकता और उसका कोई रोल नहीं है:
focus()टाइप करने वाले भाग पर जाता है। उसेlabelसे नाम दें,aria-labelसे कभी नहीं। - टेक्स्ट में सेपरेटर तब खोजे जाते हैं जब टेक्स्ट बदलता है, दबाई गई कुंजी से कभी नहीं, इसलिए टच कीबोर्ड और डिक्टेशन भी एंट्री ख़त्म करते हैं। जब तक इनपुट मेथड कंपोज़ कर रहा है, कुछ नहीं बनता: जो कुंजी कंपोज़िशन को कमिट करती है, वह उसे कमिट करती है, और टेक्स्ट उसके बाद ही पढ़ा जाता है।
- ऐट्रिब्यूट kebab-case में हैं, जैसे
input-value,max-entries,remove-labelऔरadded-count-text।readonlyऔरautocompleteके नाम HTML वाले ही हैं। - एलिमेंट के डिफ़ाइन होने से पहले उसका कोई साइज़ नहीं होता और वह कुछ नहीं दिखाता। बॉक्स की ऊँचाई के लिए जगह रखें। जिस पेज को स्क्रिप्ट के बिना लिस्ट लेनी है, वह सादा
<input>या<textarea>इस्तेमाल करता है और टेक्स्ट को अपने सर्वर पर टुकड़ों में काटता है।
| आपको चाहिए | इस्तेमाल करें |
|---|---|
| ऐसे टेक्स्ट की लिस्ट जो व्यक्ति टाइप करता है और जिनमें हर एक अलग से जाँचा जाता है | चिप फ़ील्ड |
| उन विकल्पों में से चुनाव जो प्रॉडक्ट के पास हैं | कॉम्बोबॉक्स। चिप फ़ील्ड में सुझावों की कोई लिस्ट नहीं होती |
| टैग या चिप का ऐसा सेट जो अकेला रहता है, जिसमें न टाइप करना है न फ़ॉर्म का कोई मान है | टैग ग्रुप |
| थोड़ी-सी लंबी एंट्री, जिनमें हर एक को लेबल चाहिए | टेक्स्ट फ़ील्ड का एक फ़ील्ड ग्रुप |
| एक टेक्स्ट, वह चाहे जितना लंबा हो | टेक्स्ट फ़ील्ड |
supportingTextमें बताएँ कि एंट्री क्या है और कैसे बनती है: “पतों को कॉमा से अलग करें।”separatorsमें सिर्फ़ वही दें जो कभी किसी एंट्री का हिस्सा नहीं हो सकता। “Lovelace, Ada” जैसे नामों के लिए कोई सेपरेटर न दें।removeLabelमें{entry}वाली चिह्नित जगह रखें, ताकि हटाने की दो क्रियाओं का नाम कभी एक न हो।invalidTextऐसे शब्दों में दें जो बताएँ कि सही एंट्री कैसी दिखती है।- सीमा
supportingTextमें बताएँ, और सीमा पर क्या होता है, यहlimitTextमें।
- चिप फ़ील्ड को फ़ील्ड के भीतर न रखें। वह पहले से एक फ़ील्ड है।
- पते की जाँच के लिए
type="email"के भरोसे न रहें। वह कीबोर्ड चुनता है, और कुछ नहीं। checkका जवाब बाद में न दें। जिस एंट्री को सर्वर अस्वीकार करता है, वहerrorऔरerrorTextसे बताई जाती है।- टाइप किए गए टेक्स्ट को मान का हिस्सा न मानें। वह तब एंट्री बनता है जब फ़ोकस हटता है; जो प्रॉडक्ट फ़ील्ड पर फ़ोकस रहते स्क्रिप्ट से सबमिट करता है, वह
inputValueपढ़ता है।
- रोल
textbox (the typing part), after a list of the entries- लेबलिंग
- label names the typing part (a text box) and the list of entries; the supporting text with, in error, the error text after it describes the typing part, with optionalText while optional is true — all through the Field (FLD-10, FLD-11). Each entry is a button named by its whole text, cut or not, and its remove action a button named by removeLabel with the entry in it. A refusal is said by the Field's error announcement; an entry made or removed by addedText, addedCountText and removedText in a polite live region. Every word is the product's.
- न्यूनतम टार्गेट
- दिखने वाला आकार छोटा होने पर भी हिट एरिया न्यूनतम टार्गेट साइज़ को पूरा करता है। minimum 32px · pointer 44px · spacing 8px · touch 48px
कीबोर्ड
| कुंजियाँ | क्रिया |
|---|---|
| Tab / Shift+Tab | Moves focus to the typing part, the chip field's one stop, and on from it. From an entry, Tab moves to the typing part and Shift+Tab leaves the chip field backwards. |
| Enter | In the typing part with text: offers the text as an entry. With no text: the Text input's action key (on the web, asks for the form's submission). On an entry: takes it back into the typing part to be changed. |
| A separator the product lists | Offers the text before it as an entry; the separator itself is not kept. |
| Backspace | In the typing part with the caret at the start and nothing selected: moves focus to the last entry and removes nothing. On an entry: removes it; focus goes to the entry before it. A held key is answered once. |
| Delete | On an entry: removes it; focus goes to the entry after it, or to the typing part. |
| Left Arrow / Right Arrow | From the start of the typing part, the arrow that points to where the line starts moves focus to the last entry. Among entries, each arrow moves the way it points, in either layout direction; past the last entry focus returns to the typing part. |
| Home / End | On an entry: moves focus to the first or the last entry. In the typing part they are the caret's. |
| Space | On an entry: takes it back to be changed, as Enter does. In the typing part: a character, or a separator where the product lists it. |
| Escape | On an entry: moves focus to the typing part. |
| Any character | On an entry: moves focus to the typing part and types the character there. |
टिप्पणियाँ
- One stop, not one for every entry: a person who moves through a form with Tab lands in the typing part, where entries are made, and passes a list of thirty addresses in one press. The entries are reached from there with the arrow keys or Backspace, and by pointer, touch and a screen reader's own navigation as the separate elements they are. This replaces, inside the chip field only, the stops a Chip has when it stands alone (CHP-23), which that sentence leaves to whatever holds the chips.
- A refused entry stays text. It is not drawn as a chip in an error state: the Chip has no such state, a refused chip would have to carry its reason somewhere a person who cannot see its color finds it, and the text is exactly what must be corrected — it is already under the caret. The error is the Field's: words in the supporting row, the invalid state on the typing part, announced once (WCAG 3.3.1, 3.3.3, 1.4.1).
- An entry the product finds wrong after it was made (an address that turns out not to exist) is the product's to report with error and errorText, naming the entry in words; the person removes it or takes it back to change it.
- Backspace takes two presses to remove the last entry — one to reach it, one to remove it — and a held key never reaches an entry, so that erasing typed text cannot run on into the list (WCAG 3.3.4 in spirit: a removal is deliberate).
- Activating an entry takes it back into the typing part. Nothing in its name says so, because Tanrei has no words: a product whose people need it said writes it in supportingText ("Press Enter on an address to change it").
- Targets: an entry is a small Chip, 24 high, whose own hit area and whose remove action's reach the minimum target (CHP-5, CHP-21); between two lines of entries those areas overlap and meet at the middle (CHF-30). Every pointer action has a key: Backspace and Delete remove, Enter takes back.
- Enter never submits a form while there is text to make an entry of; with an empty typing part it is the Text input's action key. Text that is typed and not yet an entry is not part of the value: it becomes an entry when focus leaves, and a product that submits by script while the field has focus reads inputValue.
- The text of an input method's composition is never cut into entries: the key that commits a composition commits it, and only then is the text read (CHF-7). A Japanese or Chinese ideographic comma is a separator only where the product lists it.
- A long entry is cut by the Chip with an ellipsis and keeps its whole text as its name; there is no tooltip. Taking it back shows it whole in the typing part.
- Forced colors: the chip field draws nothing of its own, so there is nothing of its own to lose.
- How a state looks is a value decision of the active design system; components read the state's tokens and never compute the effect themselves.
इससे जनरेट किया गया: specs/chip-field.spec.json, tokens/sys/measure.tokens.json
- सहायक तकनीक को एक लिस्ट मिलती है, जिसका नाम लेबल से आता है और जिसमें हर एंट्री के लिए एक आइटम है: एक बटन, जिसका नाम एंट्री का पूरा टेक्स्ट है, और उसकी हटाने की क्रिया, यानी एक बटन, जिसका नाम एंट्री के साथ
removeLabelसे आता है। लिस्ट के बाद टाइप करने वाला भाग आता है: एक टेक्स्ट बॉक्स, जिसका नाम लेबल है और जिसका विवरण सहायता या त्रुटि है। - फ़ील्ड Tab कुंजी के लिए एक ही पड़ाव है, उसमें चाहे जितनी एंट्री हों। एंट्री तक ऐरो कुंजियों या Backspace से पहुँचा जाता है, और पॉइंटर, टच और स्क्रीन रीडर के अपने नेविगेशन से।
- अस्वीकार हुई एंट्री टाइप करने वाले भाग में, जहाँ कैरेट है, टेक्स्ट के रूप में ही रहती है, और कारण फ़ील्ड की त्रुटि में शब्दों में होता है, जो एक बार पढ़कर सुनाई जाती है। अस्वीकार हुई और स्वीकार हुई एंट्री का फ़र्क़ कभी सिर्फ़ रंग से नहीं बताया जाता।
- एक एंट्री का बनना, एक साथ कई एंट्री का बनना, और एक एंट्री का हटना, हर एक आपके वाक्यों के साथ, बिना टोके (polite) वाले लाइव रीजन में कहा जाता है।
- हटाना सोच-समझकर होता है: Backspace दो बार दबानी पड़ती है, और दबाकर रखी गई कुंजी का जवाब एक ही बार दिया जाता है।
- दिशा वही होती है जो उस जगह की है जहाँ फ़ील्ड इस्तेमाल होता है। दाएँ से बाएँ वाले लेआउट में पंक्तियाँ दाईं ओर से शुरू होती हैं, और ऐरो कुंजियाँ तब भी उसी ओर ले जाती हैं जिधर वे इशारा करती हैं। भीतर का पता अपनी दिशा बनाए रखता है।
- सँकरी जगह में 200% टेक्स्ट पर भी हर एंट्री दिखाई जाती है, और जहाँ आख़िरी पंक्ति में बहुत कम जगह बचती है, वहाँ टाइप करने वाला भाग अपनी अलग पंक्ति लेता है।
वेब पर ज्ञात कमियाँ: स्क्रीन रीडर क्या कहते हैं, यह ब्राउज़र के एक्सेसिबिलिटी ट्री से पढ़ा गया है, स्क्रीन रीडर से सुना नहीं गया।
labelहमेशा दें।removeLabel,addedTextऔरremovedTextदें, एलिमेंट पर या प्रॉडक्ट के शब्दों से एक बार। इनके बिना हटाने की क्रियाओं का कोई नाम नहीं होता और कुछ पढ़कर नहीं सुनाया जाता।supportingTextमें बताएँ कि एंट्री कैसे बनती है। जहाँ लोगों को यह जानना ज़रूरी है कि एंट्री पर Enter उसे बदलती है, वहाँ यह भी बताएँ।- एंट्री क्यों अस्वीकार हुई, यह ऐसे शब्दों में बताएँ जो बताएँ कि उसे कैसे ठीक किया जाए।