@reliability-design/web 1.4.6 → 1.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +246 -49
  2. package/dist/components/rel-accordion/README.md +133 -132
  3. package/dist/components/rel-alert/README.md +145 -141
  4. package/dist/components/rel-autocomplete/README.md +172 -61
  5. package/dist/components/rel-avatar/README.md +118 -130
  6. package/dist/components/rel-badge/README.md +97 -93
  7. package/dist/components/rel-breadcrumb/README.md +96 -102
  8. package/dist/components/rel-button/README.md +190 -130
  9. package/dist/components/rel-calendar/README.md +109 -109
  10. package/dist/components/rel-card/README.md +75 -94
  11. package/dist/components/rel-cardmedia/README.md +100 -127
  12. package/dist/components/rel-carousel/README.md +186 -166
  13. package/dist/components/rel-checkbox/README.md +96 -75
  14. package/dist/components/rel-chip/README.md +138 -121
  15. package/dist/components/rel-container/README.md +107 -99
  16. package/dist/components/rel-date-picker/README.md +200 -289
  17. package/dist/components/rel-divider/README.md +88 -100
  18. package/dist/components/rel-drawer/README.md +187 -200
  19. package/dist/components/rel-kbd/README.md +141 -151
  20. package/dist/components/rel-layout/README.md +34 -0
  21. package/dist/components/rel-menu/README.md +180 -151
  22. package/dist/components/rel-menubar/README.md +218 -329
  23. package/dist/components/rel-otp/README.md +171 -440
  24. package/dist/components/rel-pagination/README.md +100 -424
  25. package/dist/components/rel-popover/README.md +203 -568
  26. package/dist/components/rel-progress/README.md +88 -110
  27. package/dist/components/rel-radio/README.md +131 -138
  28. package/dist/components/rel-range-picker/README.md +165 -0
  29. package/dist/components/rel-resizable/README.md +199 -140
  30. package/dist/components/rel-segmented-button/README.md +156 -141
  31. package/dist/components/rel-select/README.md +156 -93
  32. package/dist/components/rel-sheet/README.md +168 -224
  33. package/dist/components/rel-skeleton/README.md +104 -0
  34. package/dist/components/rel-slider/README.md +131 -135
  35. package/dist/components/rel-snackbar/README.md +168 -134
  36. package/dist/components/rel-stepper/README.md +162 -160
  37. package/dist/components/rel-switch/README.md +117 -102
  38. package/dist/components/rel-tab/README.md +173 -163
  39. package/dist/components/rel-textfield/README.md +176 -69
  40. package/dist/components/rel-time-picker/README.md +122 -157
  41. package/dist/components/rel-toast/README.md +165 -148
  42. package/dist/components/rel-tooltip/README.md +119 -111
  43. package/dist/components/rel-upload/README.md +220 -0
  44. package/dist/index.d.mts +1726 -447
  45. package/dist/index.d.ts +1726 -447
  46. package/dist/index.js +13715 -10870
  47. package/dist/index.js.map +1 -1
  48. package/dist/index.mjs +14018 -11163
  49. package/dist/index.mjs.map +1 -1
  50. package/dist/styles/focus-ring.ts +84 -0
  51. package/dist/styles/vars.css +892 -866
  52. package/dist/{vars-XNMTSRVN.css → vars-DXX6QOAG.css} +892 -866
  53. package/package.json +3 -2
  54. package/dist/components/rel-accordion/rel-accordion.ts +0 -336
  55. package/dist/components/rel-alert/rel-alert.ts +0 -305
  56. package/dist/components/rel-autocomplete/rel-autocomplete.ts +0 -720
  57. package/dist/components/rel-avatar/rel-avatar.ts +0 -142
  58. package/dist/components/rel-badge/rel-badge.ts +0 -175
  59. package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +0 -106
  60. package/dist/components/rel-button/rel-button.ts +0 -560
  61. package/dist/components/rel-calendar/index.ts +0 -1
  62. package/dist/components/rel-calendar/rel-calendar.ts +0 -565
  63. package/dist/components/rel-card/rel-card.ts +0 -88
  64. package/dist/components/rel-cardmedia/rel-cardmedia.ts +0 -88
  65. package/dist/components/rel-carousel/index.ts +0 -1
  66. package/dist/components/rel-carousel/rel-carousel.ts +0 -723
  67. package/dist/components/rel-chart/README.md +0 -286
  68. package/dist/components/rel-chart/index.ts +0 -1
  69. package/dist/components/rel-chart/rel-chart.ts +0 -754
  70. package/dist/components/rel-checkbox/rel-checkbox.ts +0 -382
  71. package/dist/components/rel-chip/rel-chip.ts +0 -483
  72. package/dist/components/rel-container/rel-container.ts +0 -95
  73. package/dist/components/rel-date-picker/date-format.test.ts +0 -43
  74. package/dist/components/rel-date-picker/date-format.ts +0 -47
  75. package/dist/components/rel-date-picker/date-parse.test.ts +0 -116
  76. package/dist/components/rel-date-picker/date-parse.ts +0 -178
  77. package/dist/components/rel-date-picker/index.ts +0 -1
  78. package/dist/components/rel-date-picker/rel-date-picker.ts +0 -1676
  79. package/dist/components/rel-divider/rel-divider.ts +0 -54
  80. package/dist/components/rel-drawer/index.ts +0 -1
  81. package/dist/components/rel-drawer/rel-drawer-footer.ts +0 -27
  82. package/dist/components/rel-drawer/rel-drawer.ts +0 -607
  83. package/dist/components/rel-kbd/rel-kbd.ts +0 -188
  84. package/dist/components/rel-layout/rel-layout.ts +0 -49
  85. package/dist/components/rel-menu/rel-menu.ts +0 -541
  86. package/dist/components/rel-menubar/index.ts +0 -2
  87. package/dist/components/rel-menubar/rel-menubar-menu.css +0 -3
  88. package/dist/components/rel-menubar/rel-menubar-menu.ts +0 -17
  89. package/dist/components/rel-menubar/rel-menubar.ts +0 -777
  90. package/dist/components/rel-nav-menu/README.md +0 -289
  91. package/dist/components/rel-nav-menu/index.ts +0 -3
  92. package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +0 -243
  93. package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +0 -72
  94. package/dist/components/rel-nav-menu/rel-nav-menu.ts +0 -270
  95. package/dist/components/rel-navbar/README.md +0 -126
  96. package/dist/components/rel-navbar/rel-navbar.ts +0 -105
  97. package/dist/components/rel-otp/index.ts +0 -1
  98. package/dist/components/rel-otp/rel-otp.ts +0 -527
  99. package/dist/components/rel-pagination/index.ts +0 -1
  100. package/dist/components/rel-pagination/rel-pagination.ts +0 -522
  101. package/dist/components/rel-popover/index.ts +0 -2
  102. package/dist/components/rel-popover/rel-popover-content.ts +0 -81
  103. package/dist/components/rel-popover/rel-popover.ts +0 -475
  104. package/dist/components/rel-progress/rel-progress.ts +0 -234
  105. package/dist/components/rel-radio/rel-radio.ts +0 -481
  106. package/dist/components/rel-range-picker/rel-range-picker.ts +0 -1688
  107. package/dist/components/rel-resizable/index.ts +0 -3
  108. package/dist/components/rel-resizable/rel-resizable-group.ts +0 -405
  109. package/dist/components/rel-resizable/rel-resizable-handle.ts +0 -150
  110. package/dist/components/rel-resizable/rel-resizable-panel.ts +0 -58
  111. package/dist/components/rel-segmented-button/rel-segmented-button.ts +0 -217
  112. package/dist/components/rel-select/rel-select.ts +0 -1416
  113. package/dist/components/rel-sheet/rel-sheet.ts +0 -610
  114. package/dist/components/rel-sidebar/README.md +0 -209
  115. package/dist/components/rel-sidebar/rel-sidebar.ts +0 -1191
  116. package/dist/components/rel-skeleton/rel-skeleton.ts +0 -143
  117. package/dist/components/rel-slider/rel-slider.ts +0 -673
  118. package/dist/components/rel-snackbar/rel-snackbar.ts +0 -329
  119. package/dist/components/rel-stepper/rel-stepper.ts +0 -567
  120. package/dist/components/rel-switch/rel-switch.ts +0 -199
  121. package/dist/components/rel-tab/rel-tab.ts +0 -264
  122. package/dist/components/rel-table/README.md +0 -178
  123. package/dist/components/rel-table/rel-table-body.ts +0 -22
  124. package/dist/components/rel-table/rel-table-caption.ts +0 -30
  125. package/dist/components/rel-table/rel-table-cell.ts +0 -43
  126. package/dist/components/rel-table/rel-table-footer.ts +0 -24
  127. package/dist/components/rel-table/rel-table-head.ts +0 -47
  128. package/dist/components/rel-table/rel-table-header.ts +0 -22
  129. package/dist/components/rel-table/rel-table-row.ts +0 -37
  130. package/dist/components/rel-table/rel-table.ts +0 -62
  131. package/dist/components/rel-textfield/rel-textfield.ts +0 -1054
  132. package/dist/components/rel-time-picker/rel-time-picker.ts +0 -1482
  133. package/dist/components/rel-time-picker/time-parse.test.ts +0 -67
  134. package/dist/components/rel-time-picker/time-parse.ts +0 -85
  135. package/dist/components/rel-toast/rel-toast.ts +0 -206
  136. package/dist/components/rel-tooltip/rel-tooltip.ts +0 -193
  137. package/dist/components/rel-topbar/rel-topbar-actions.ts +0 -27
  138. package/dist/components/rel-topbar/rel-topbar-brand.ts +0 -54
  139. package/dist/components/rel-topbar/rel-topbar-dropdown-item.ts +0 -69
  140. package/dist/components/rel-topbar/rel-topbar-dropdown.ts +0 -31
  141. package/dist/components/rel-topbar/rel-topbar-item.ts +0 -324
  142. package/dist/components/rel-topbar/rel-topbar-mobile-panel.ts +0 -27
  143. package/dist/components/rel-topbar/rel-topbar-profile.ts +0 -243
  144. package/dist/components/rel-topbar/rel-topbar-utilities.ts +0 -27
  145. package/dist/components/rel-topbar/rel-topbar.ts +0 -446
  146. package/dist/components/rel-upload/UPLOAD-DESIGN-CHANGES.md +0 -134
  147. package/dist/components/rel-upload/rel-upload-actions.ts +0 -163
  148. package/dist/components/rel-upload/rel-upload.ts +0 -968
@@ -1,106 +1,213 @@
1
1
  # rel-textfield
2
2
 
3
- ## Overview
4
-
5
- A text input field component with support for labels, icons, validation states, and supporting text. Used for single-line text entry in forms and user interfaces.
3
+ `<rel-textfield>` is the single-line and multi-line text input from the Figma "Text Field" component: a labelled control with three chromes (`default` outlined, `underline`, `legend` notched outline), three heights (32 / 40 / 48px), prefix and suffix blocks (icon, short text or slotted content), error / helper text and full-width or inline layout. Use it for free-text entry — names, emails, passwords, numbers, notes (`multiline`). For picking from a fixed list use `rel-select`; for type-ahead against a list use `rel-autocomplete`; for dates and times use the picker components, which reuse this field's chrome.
6
4
 
7
5
  ## Usage
8
6
 
9
7
  ```html
10
- <!-- Basic usage -->
11
- <rel-textfield label="Email" placeholder="Enter your email"></rel-textfield>
8
+ <!-- Basic field -->
9
+ <rel-textfield label="Email" placeholder="you@example.com" type="email"></rel-textfield>
10
+
11
+ <!-- Sizes and chromes -->
12
+ <rel-textfield label="Small" size="small"></rel-textfield>
13
+ <rel-textfield label="Large" size="large"></rel-textfield>
14
+ <rel-textfield label="Underline" variant="underline"></rel-textfield>
15
+ <rel-textfield label="Legend" variant="legend"></rel-textfield>
16
+
17
+ <!-- Label styles -->
18
+ <rel-textfield label="Floating label" label-style="floating"></rel-textfield>
19
+ <rel-textfield label-style="none" placeholder="Search orders" field-aria-label="Search orders"></rel-textfield>
20
+
21
+ <!-- Leading icon, helper text, required -->
22
+ <rel-textfield label="Search" prefixicon="search" helpertext="Type at least 3 characters" required></rel-textfield>
23
+
24
+ <!-- Prefix / suffix text (Figma .Preffix / .Suffix) -->
25
+ <rel-textfield label="Website" prefix-text="https://" prefix-style="fill"></rel-textfield>
26
+ <rel-textfield label="Weight" suffix-text="kg" suffix-divider></rel-textfield>
27
+
28
+ <!-- Slotted prefix / suffix content -->
29
+ <rel-textfield label="Amount">
30
+ <span slot="prefix">$</span>
31
+ <rel-button slot="suffix" variant="ghost" size="small">Max</rel-button>
32
+ </rel-textfield>
12
33
 
13
- <!-- With icons and supporting text -->
34
+ <!-- Clickable trailing icon (e.g. password toggle) -->
14
35
  <rel-textfield
36
+ id="pw"
15
37
  label="Password"
16
38
  type="password"
17
- leftIcon="🔒"
18
- supportingText="Must be at least 8 characters">
39
+ righticon="eye"
40
+ clickable-right-icon
41
+ right-icon-aria-label="Show password">
19
42
  </rel-textfield>
43
+ <script>
44
+ const pw = document.getElementById("pw");
45
+ pw.addEventListener("rel-right-icon-click", () => {
46
+ pw.type = pw.type === "password" ? "text" : "password";
47
+ });
48
+ pw.addEventListener("rel-change", (e) => console.log("typed:", e.detail));
49
+ </script>
20
50
 
21
- <!-- No label — an accessible name is required in its place -->
22
- <rel-textfield
23
- label-style="none"
24
- placeholder="Search orders"
25
- field-aria-label="Search orders">
26
- </rel-textfield>
51
+ <!-- Error state -->
52
+ <rel-textfield label="Username" value="a" error errormessage="Must be at least 3 characters"></rel-textfield>
53
+
54
+ <!-- Multiline (textarea) -->
55
+ <rel-textfield label="Notes" multiline rows="5" maxlength="500"></rel-textfield>
27
56
 
28
- <!-- Setting value via JavaScript -->
29
- <rel-textfield id="myField" label="Username"></rel-textfield>
57
+ <!-- Read-only, disabled, inline width -->
58
+ <rel-textfield label="Order ID" value="SO-4821" readonly></rel-textfield>
59
+ <rel-textfield label="Disabled" disabled></rel-textfield>
60
+ <rel-textfield id="qty" label="Quantity" type="number"></rel-textfield>
30
61
  <script>
31
- const field = document.getElementById('myField');
32
- field.value = 'john.doe';
62
+ // fullWidth defaults to true; a boolean attribute cannot express false, so unset it via the property
63
+ document.getElementById("qty").fullWidth = false;
33
64
  </script>
34
65
  ```
35
66
 
67
+ ### Deprecated aliases
68
+
69
+ ```html
70
+ <!-- floatingLabel → label-style="floating" (kept permanently as an alias; no console notice) -->
71
+ <rel-textfield label="Old spelling" floatinglabel></rel-textfield>
72
+ <rel-textfield label="Canonical" label-style="floating"></rel-textfield>
73
+ ```
74
+
75
+ <!-- readme-gen:start -->
76
+
77
+ <!-- Generated from rel-textfield.ts — do not edit; run readme-generate.mjs -->
78
+
36
79
  ## API
37
80
 
38
- ### Attributes/Properties
39
-
40
- | Name | Type | Default | Description |
41
- |------|------|---------|-------------|
42
- | `label` | `string` | - | Label text displayed above the input |
43
- | `label-style` | `"default" \| "floating" \| "none"` | - | Label presentation. `"none"` renders no label at all. Unset, the deprecated `floatingLabel` boolean decides |
44
- | `floatingLabel` | `boolean` | `false` | **Deprecated** — use `label-style="floating"`. Kept permanently as an alias |
45
- | `field-aria-label` | `string` | - | Accessible name for the input. Required with `label-style="none"` |
46
- | `field-aria-labelledby` | `string` | - | IDREF list of external element(s) naming the input. Wins over `field-aria-label` |
47
- | `placeholder` | `string` | `""` | Placeholder text |
48
- | `type` | `string` | `"text"` | Input type (text, email, password, etc.) |
49
- | `value` | `string` | `""` | Current input value |
50
- | `leftIcon` | `string` | - | Icon content on the left side |
51
- | `rightIcon` | `string` | - | Icon content on the right side |
52
- | `supportingText` | `string` | - | Helper or error text below input |
53
- | `state` | `"default" \| "focused" \| "error" \| "disabled"` | `"default"` | Visual state |
54
- | `size` | `"small" \| "medium" \| "large"` | `"medium"` | Size variant |
81
+ ### Attributes / Properties
82
+
83
+ | Property | Attribute | Type | Default | Description |
84
+ | --- | --- | --- | --- | --- |
85
+ | `label` | `label` | `string` | `undefined` | Visible label text. Rendered above the control (default), inside it as a floating label (`labelStyle="floating"`) or as the notch of the `legend` variant; omitted entirely under `labelStyle="none"`. |
86
+ | `placeholder` | `placeholder` | `string` | `""` | Placeholder shown while the field is empty. Under the floating label style it stays hidden until the field is focused. |
87
+ | `type` | `type` | `string` | `"text"` | Native input `type` (`text`, `email`, `password`, `number`, …). Ignored when `multiline` is set. |
88
+ | `value` | `value` | `string` | `""` | Current text. Updated on every keystroke; set it to control the field programmatically. |
89
+ | `leftIcon` | `lefticon` | `string` | `undefined` | Legacy name for the leading icon (a `rel-icon` name). `prefixIcon` wins when both are set. |
90
+ | `rightIcon` | `righticon` | `string` | `undefined` | Trailing `rel-icon` name rendered in the suffix block. Decorative unless `clickableRightIcon` is set. |
91
+ | `clickableRightIcon` | `clickable-right-icon` | `boolean` | `false` | Makes the trailing icon interactive (pointer + focusable) and emits `rel-right-icon-click` — e.g. a password show/hide toggle or clear button. |
92
+ | `rightIconAriaLabel` | `right-icon-aria-label` | `string` | `undefined` | Accessible label for the trailing icon when it is clickable. |
93
+ | `prefixText` | `prefix-text` | `string` | `undefined` | Short text rendered before the input, e.g. `"http://"` or `"$"`. Sits in the same prefix block as `prefixIcon` and is styled by `prefixStyle`. |
94
+ | `prefixStyle` | `prefix-style` | `"clear" \| "divider" \| "fill"` | `"clear"` | Visual treatment of the prefix block — applies to the prefix icon, text and slotted `prefix` content alike. See `TextFieldPrefixStyle`. |
95
+ | `suffixText` | `suffix-text` | `string` | `undefined` | Short text rendered after the input, e.g. `"kg"` or `".00"`. Shares the suffix block with `rightIcon` and slotted `suffix` content. |
96
+ | `suffixDivider` | `suffix-divider` | `boolean` | `false` | Draws a hairline between the input and the suffix block. |
97
+ | `supportingText` | `supportingtext` | `string` | `undefined` | Legacy name for the helper line below the control. `helperText` wins when both are set. |
98
+ | `state` | `state` | `"default" \| "error" \| "disabled"` | `"default"` | Legacy visual state. `"error"` / `"disabled"` behave like the `error` / `disabled` booleans, which are preferred and take precedence. Typing into a `state="error"` field resets it to `"default"` until the value is emptied again. |
99
+ | `size` | `size` | `"small" \| "medium" \| "large"` | `"medium"` | Control height — `small` 32px, `medium` 40px, `large` 48px — which also scales the text and the affix icons. |
100
+ | `labelStyle` | `label-style` | `"default" \| "floating" \| "none"` | `undefined` | Label presentation. Left `undefined` the deprecated `floatingLabel` boolean decides, so existing markup keeps working; set explicitly and it wins. Declares `attribute` because Lit would otherwise only listen for the all-lowercase `labelstyle`. Reflected. |
101
+ | `fieldAriaLabel` | `field-aria-label` | `string` | `undefined` | Accessible name for the input. Required when `labelStyle="none"`, since no `<label>` renders and a placeholder is not a valid naming mechanism. |
102
+ | `fieldAriaLabelledby` | `field-aria-labelledby` | `string` | `undefined` | IDREF list of external element(s) naming the input. Wins over `fieldAriaLabel`. |
103
+ | `variant` | `variant` | `"default" \| "underline" \| "legend"` | `"default"` | Field chrome: `default` outlined box, `underline` bottom border only, `legend` notched outline with the label sitting in the top border (native fieldset/legend). Reflected. |
104
+ | `disabled` | `disabled` | `boolean` | `false` | Disables the input (not focusable, not editable) and dims the control. |
105
+ | `required` | `required` | `boolean` | `false` | Marks the input required: sets native `required` / `aria-required` and appends an asterisk to the label. |
106
+ | `multiline` | `multiline` | `boolean` | `false` | Renders a textarea instead of a single-line input (see `rows`). Prefix/suffix blocks and `type` are ignored in this mode. Reflected. |
107
+ | `rows` | `rows` | `number` | `3` | Visible text rows of the textarea when `multiline` is set. |
108
+ | `prefixIcon` | `prefixicon` | `string` | `undefined` | Leading `rel-icon` name rendered in the prefix block (preferred over the legacy `leftIcon`). |
109
+ | `prefixIconAriaLabel` | `prefixiconarialabel` | `string` | `undefined` | Accessible label for the leading icon. Without it the icon is `aria-hidden` (decorative). |
110
+ | `error` | `error` | `boolean` | `false` | Puts the field in the error state: danger border, `aria-invalid`, and `errorMessage` replacing the helper text. |
111
+ | `errorMessage` | `errormessage` | `string` | `undefined` | Text shown below the control instead of `helperText` while the field is in the error state. |
112
+ | `helperText` | `helpertext` | `string` | `undefined` | Helper line below the control (preferred over the legacy `supportingText`); linked to the input via `aria-describedby`. |
113
+ | `helperIcon` | `helper-icon` | `string` | `undefined` | Icon name from the generated icon dictionary, rendered before the helper line (Figma "Supporting Icon"). Sized 16px, or 14px at `size="small"`, and it takes the helper's colour — so it turns `--rel-text-danger` in the error state. Decorative: it is hidden from screen readers, since the helper text it sits beside is already announced. |
114
+ | `readonly` | `readonly` | `boolean` | `false` | Makes the input read-only: focusable and selectable but not editable. |
115
+ | `maxLength` | `maxlength` | `number` | `undefined` | Maximum number of characters (native `maxlength`). |
116
+ | `name` | `name` | `string` | `undefined` | Form field name forwarded to the native input, for form submission and autofill. |
117
+ | `fullWidth` | `fullwidth` | `boolean` | `true` | Fills the parent width as a block element (default). Unset it to render inline at the content's natural width. Reflected. |
118
+
119
+ #### Deprecated (still supported — removal targeted for 3.0)
120
+
121
+ | Property | Attribute | Type | Use instead |
122
+ | --- | --- | --- | --- |
123
+ | `floatingLabel` | `floatinglabel` | `boolean` | Use `labelStyle="floating"`. Kept permanently as an alias. |
124
+
125
+ ### Methods
126
+
127
+ | Method | Signature | Description |
128
+ | --- | --- | --- |
129
+ | `focus` | `focus(options?: FocusOptions)` | Focuses the inner input/textarea (the host itself is not focusable). |
55
130
 
56
131
  ## Events
57
132
 
58
- | Event | Detail | Description |
59
- |-------|--------|-------------|
60
- | `input-change` | `string` (the current value) | Fires when the input value changes through user interaction |
133
+ | Event | Detail | Bubbles / composed | Description |
134
+ | --- | --- | --- | --- |
135
+ | `rel-change` | `value` | bubbles / composed | Fired on every keystroke. Detail: the current text (`value`). |
136
+ | `rel-right-icon-click` | — | bubbles / composed | Fired when the trailing icon is clicked or activated with Enter / Space while `clickableRightIcon` is set. No detail. |
61
137
 
62
138
  ## Slots
63
139
 
64
- Default slot not used. All content controlled via properties.
140
+ | Slot | Description |
141
+ | --- | --- |
142
+ | `prefix` | Custom content at the far left of the control (e.g. a unit dropdown); shares the prefix block with `prefixIcon` / `prefixText`. Hidden when `multiline` is set. |
143
+ | `suffix` | Custom content at the far right of the control (e.g. an action button); shares the suffix block with `rightIcon` / `suffixText`. Hidden when `multiline` is set. |
65
144
 
66
145
  ## CSS Parts
67
146
 
68
- None exposed.
147
+ | Part | Description |
148
+ | --- | --- |
149
+ | `label` | The visible label element (default and floating label styles) |
150
+ | `input` | The native input / textarea |
151
+ | `right-icon` | The trailing `rel-icon` |
152
+ | `prefix` | The prefix block (leading icon, prefix text and the `prefix` slot) |
153
+ | `suffix` | The suffix block (suffix text, trailing icon and the `suffix` slot) |
154
+ | `helper` | The helper / error text line below the control |
155
+ | `helper-icon` | The leading `rel-icon` in the helper line; rendered only when `helper-icon` is set and there is helper text |
156
+ | `control` | The bordered control box (the fieldset in the legend variant) |
69
157
 
70
158
  ## Tokens / CSS Variables
71
159
 
72
- - `--rel-fonts-font-family`: Font family
73
- - `--rel-body-sm-regular-font-size`, `--rel-body-md-regular-font-size`: Font sizes
74
- - `--rel-fonts-weight-body-medium`: Font weight for label
75
- - `--rel-text-label`: Label color
76
- - `--rel-text-default`: Input text color
77
- - `--rel-text-placeholder`: Placeholder and icon color
78
- - `--rel-text-disabled`: Disabled text color
79
- - `--rel-border-default`: Default border color
80
- - `--rel-bg-info`: Focus border color
81
- - `--rel-border-danger`: Error state border color
82
- - `--rel-bg-surface`: Input background (light mode)
83
- - `--rel-bg-neutral-elevated-1`: Disabled background
84
- - `--rel-spacing-*`: Spacing tokens
85
- - `--rel-border-radius-sm`: Border radius
86
- - `--rel-field-label-reserve`: Height held for the absent label row under `label-style="none"`, so the input bottom-aligns with labelled siblings. Defaults to the label line-height plus the wrapper gap; set to `0` to collapse the row entirely in compact contexts (toolbars, table cells)
160
+ ### Component hooks
161
+
162
+ Set these on the host (or an ancestor) to customise the element without touching design tokens.
163
+
164
+ | Custom property | Default | Description |
165
+ | --- | --- | --- |
166
+ | `--rel-field-label-reserve` | `calc(var(--rel-body-md-regular-line-height) + var(--rel-spacing-2xs))` | Height held for the label row whenever no label renders above the control — `labelStyle="none"`, and `labelStyle="floating"` where the label sits inside the control — so the control still lines up with labelled siblings in a form row. Defaults to that size's label line-height plus the wrapper gap (24px at `small`, 26px at `medium` and `large`). Set to `0` to collapse the row entirely (toolbars, table cells). |
167
+ | `--rel-textfield-surface` | `var(--rel-bg-neutral)` | Colour the floating label's strip paints to mask the border behind it; defaults to the control's own fill (`--rel-bg-neutral`). Set it when the field sits on a tinted or elevated surface, otherwise the strip shows as a light dash across the border. |
168
+
169
+ <!-- readme-gen:end -->
87
170
 
88
171
  ## Accessibility
89
172
 
90
- - Associates `<label>` with input via `for`/`id`
91
- - With `label-style="none"` no `<label>` renders, so `field-aria-label` (or
92
- `field-aria-labelledby`) must supply the accessible name — a placeholder is
93
- not a valid naming mechanism. The component logs a console warning when both
94
- are missing.
95
- - Supports native HTML5 input attributes (`required`, `disabled`, `readonly`, `maxlength`)
96
- - Focus ring visible on keyboard navigation (`:focus-visible`)
97
- - Error state communicated visually via border color
98
- - Supporting text can provide `aria-describedby` context
173
+ - The visible `<label>` is linked to the native input via `for`/`id` (the host `id`, or a generated one). In the `legend` variant the input is instead named through `aria-labelledby` pointing at the `<legend>`.
174
+ - With `label-style="none"` no label renders: `field-aria-labelledby` (wins) or `field-aria-label` must supply the accessible name. The component logs a console warning once when neither is set, because a placeholder is not a valid naming mechanism.
175
+ - The input carries `aria-required`, `aria-invalid` (true in the error state) and `aria-describedby` pointing at the helper line. That line is always rendered with `aria-live="polite"`, so a change from helper text to `errorMessage` is announced.
176
+ - The leading icon is `aria-hidden` unless `prefixIconAriaLabel` is set, in which case it becomes `role="img"` with that label. The trailing icon is `aria-hidden` unless `clickable-right-icon` is set, in which case it is `role="button"`, `tabindex="0"` and named by `right-icon-aria-label`.
177
+ - No screen-reader announcements are made via `announce()`; the live helper region is the only announcement path.
178
+
179
+ | Key | Action |
180
+ |-----|--------|
181
+ | `Tab` | Focus the input; with `clickable-right-icon` the trailing icon is the next Tab stop |
182
+ | `Enter` / `Space` (on the trailing icon) | Fires `rel-right-icon-click` (default prevented) |
183
+
184
+ Focus behaviour: `focus()` on the host focuses the inner input / textarea (the host itself is not focusable). A mousedown anywhere on the control — border, legend notch, prefix / suffix padding — focuses the input like clicking a label would; presses on the input, a clickable icon or slotted content keep their native behaviour. The focused control shows a `--rel-border-strong` border plus a 1px ring; the `legend` variant recolours the border and legend only (a ring would strike through the notch).
99
185
 
100
186
  ## Notes / Edge Cases
101
187
 
102
- - The `state` prop overrides internal focus state if set explicitly
103
- - Icons are decorative (text content, not `<img>` elements)
104
- - Input type `password` does not auto-toggle visibility (use `rightIcon` for toggle button)
105
- - Error state must be set programmatically; no built-in validation
106
- - Disabled inputs cannot be focused or edited
188
+ - Attribute spellings: props declared with an explicit `attribute` use kebab-case (`label-style`, `prefix-text`, `clickable-right-icon`, `field-aria-label`, …). The others have Lit's default all-lowercase attribute — `prefixicon`, `righticon`, `helpertext`, `errormessage`, `maxlength`, `fullwidth`, `supportingtext`, `floatinglabel` — see the Attribute column above. HTML attribute names are case-insensitive, so `helperText="…"` in markup also works.
189
+ - **The same logical prop can take a _different_ spelling on `rel-autocomplete` / `rel-select`.** Those components declare an explicit kebab `attribute` where this one falls back to Lit's all-lowercase default, so `prefix-icon` works on `<rel-autocomplete>` and is silently ignored on `<rel-textfield>`. There is no error when this happens — an attribute a component does not observe is inert, so the icon simply never appears. The pairs that differ today:
190
+
191
+ | Prop | `rel-textfield` | `rel-autocomplete` / `rel-select` |
192
+ | --- | --- | --- |
193
+ | `prefixIcon` | `prefixicon` | `prefix-icon` (autocomplete) |
194
+ | `helperText` | `helpertext` | `helper-text` (autocomplete) |
195
+ | `errorMessage` | `errormessage` | `error-message` (autocomplete) |
196
+ | `floatingLabel` | `floatinglabel` | `floating-label` (autocomplete) |
197
+ | `fullWidth` | `fullwidth` | `full-width` (autocomplete) |
198
+ | `leftIcon` | `lefticon` | `left-icon` (select) |
199
+ | `rightIcon` | `righticon` | `right-icon` (select) |
200
+ | `supportingText` | `supportingtext` | `supporting-text` (select) |
201
+
202
+ All three agree on `label-style`, `field-aria-label` and `field-aria-labelledby`. This is an inconsistency, not a design decision: the kebab spellings are the intended direction, and unifying on them means retiring the lowercase ones, which only a major version can do — so it is targeted for 3.0. Until then the Attribute column above is the authority for **this** component. In a Lit template you can sidestep the whole question with a property binding (`.prefixIcon=${…}`), which is spelling-independent; that is also how `rel-autocomplete` drives the field it wraps, so its own forwarding is unaffected by the mismatch.
203
+ - Legacy names still work but the canonical ones win when both are set: `leftIcon` → `prefixIcon`, `supportingText` → `helperText`, `state="error"` → `error`, `state="disabled"` → `disabled`. `lefticon` / `righticon` attributes are also read once at connect time.
204
+ - `errorMessage` replaces the helper line only while the field is in the error state **and** the message is set; otherwise the helper text stays visible. There is no built-in validation — set `error` from your form layer.
205
+ - `state="error"` (legacy) auto-clears to `"default"` as soon as the user types a non-empty value and comes back once the value is emptied again; the `error` boolean never auto-clears.
206
+ - `multiline` renders a `<textarea>` (`rows`, vertical resize, 80px minimum height). `type`, the prefix / suffix blocks and their slots are ignored in this mode (the slots stay mounted but hidden).
207
+ - `fullWidth` defaults to `true` and reflects as `fullwidth`; without it the host becomes `inline-block` at its content width. To turn it off from HTML you must bind the property (`.fullWidth=${false}`), since a boolean attribute cannot express `false`.
208
+ - `label-style="floating"`: the placeholder is hidden until the field is focused; the label floats onto the border when focused or filled. Internally the deprecated `floatingLabel` boolean is kept in sync with `labelStyle` and its reflected `floatinglabel` attribute is the styling hook, so both spellings render identically. With a `prefix-style="clear"` prefix the floated label slides back over the control's left edge (Figma "Floating Label"); `divider` / `fill` prefixes keep it after the block.
209
+ - `variant="legend"` + `label-style="none"` drops the `<legend>` entirely so the top border runs continuous; a `fill` prefix is squared off in this variant because it cannot reach the notched top border.
210
+ - `--rel-field-label-reserve` (see Component hooks) keeps a `label-style="none"` field bottom-aligned with labelled siblings; set it to `0` in toolbars or table cells.
211
+ - Inside the prefix block the order is slotted content → icon → text (nearest the input); in the suffix block it is text → icon → slotted content. Clicking a non-interactive part of either block focuses the input.
212
+ - The control height (32 / 40 / 48px) is explicit so the field lines up with `rel-select` and the date / time / range picker triggers; the textarea keeps the padding model and grows with `rows`.
213
+ - In Figma, the `error` state's border has no focus ring; that matches the code (`box-shadow: none` in error).