srcdev-nuxt-components 9.6.8 → 9.6.10

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 (109) hide show
  1. package/.claude/skills/component-compliance-checklist.md +28 -1
  2. package/.claude/skills/component-inline-action-button.md +1 -1
  3. package/.claude/skills/component-local-style-override.md +1 -1
  4. package/.claude/skills/component-naming.md +17 -12
  5. package/.claude/skills/components/container-glow.md +2 -2
  6. package/.claude/skills/components/form-field.md +2 -2
  7. package/.claude/skills/components/form-wrapper.md +1 -1
  8. package/.claude/skills/components/glowing-border.md +1 -1
  9. package/.claude/skills/components/input-description.md +7 -7
  10. package/.claude/skills/components/input-error.md +3 -3
  11. package/.claude/skills/components/input-label.md +7 -8
  12. package/.claude/skills/components/input-number.md +17 -17
  13. package/.claude/skills/components/input-select.md +153 -0
  14. package/.claude/skills/components/input-text.md +220 -0
  15. package/.claude/skills/components/input-textarea.md +147 -0
  16. package/.claude/skills/components/select-menu.md +4 -4
  17. package/.claude/skills/components/toggle-switch.md +143 -0
  18. package/.claude/skills/composable-zod-validation.md +1 -1
  19. package/.claude/skills/css-nesting-conventions.md +22 -1
  20. package/.claude/skills/icon-sets.md +1 -1
  21. package/.claude/skills/icon-sizing.md +1 -1
  22. package/.claude/skills/index.md +5 -5
  23. package/.claude/skills/storybook-add-story.md +1 -1
  24. package/.claude/skills/theming-component-token-pattern.md +8 -8
  25. package/.claude/skills/theming-form-geometry-tokens.md +1 -1
  26. package/.vscode/srcdev-component-input-select.code-snippets +20 -14
  27. package/.vscode/srcdev-component-input-text.code-snippets +46 -40
  28. package/.vscode/srcdev-component-input-textarea.code-snippets +19 -14
  29. package/.vscode/srcdev-component-toggle-switch.code-snippets +19 -29
  30. package/app/assets/styles/setup/04.elements/forms/00.element-defaults.css +2 -2
  31. package/app/assets/styles/setup/04.elements/forms/06.button-geometry.css +1 -1
  32. package/app/components/01.atoms/animations/glowing-border/CONSUMER-STYLING.md +2 -2
  33. package/app/components/01.atoms/animations/glowing-border/stories/GlowingBorder.stories.ts +4 -4
  34. package/app/components/02.molecules/progress-tracker/stories/ProgressTracker.stories.ts +4 -4
  35. package/app/components/05.forms/form-errors/CONSUMER-STYLING.md +1 -1
  36. package/app/components/05.forms/form-field/CONSUMER-STYLING.md +2 -2
  37. package/app/components/05.forms/input-button/stories/InputButton.stories.ts +3 -3
  38. package/app/components/05.forms/input-description/CONSUMER-STYLING.md +6 -6
  39. package/app/components/05.forms/input-label/CONSUMER-STYLING.md +7 -7
  40. package/app/components/05.forms/input-number/CONSUMER-STYLING.md +9 -5
  41. package/app/components/05.forms/input-number/InputNumber.vue +2 -2
  42. package/app/components/05.forms/input-select/CONSUMER-STYLING.md +80 -10
  43. package/app/components/05.forms/input-select/InputSelect.vue +198 -0
  44. package/app/components/05.forms/input-select/InputSelectField.vue +130 -0
  45. package/app/components/05.forms/input-select/stories/InputSelect.stories.ts +184 -0
  46. package/app/components/05.forms/input-select/stories/InputSelectField.stories.ts +187 -0
  47. package/app/components/05.forms/input-select/tests/{InputSelectCore.spec.ts → InputSelect.spec.ts} +75 -12
  48. package/app/components/05.forms/input-select/tests/InputSelectField.spec.ts +121 -0
  49. package/app/components/05.forms/input-text/CONSUMER-STYLING.md +85 -15
  50. package/app/components/05.forms/input-text/{InputPasswordWithLabel.vue → InputPasswordField.vue} +16 -19
  51. package/app/components/05.forms/input-text/{InputTextCore.vue → InputText.vue} +42 -78
  52. package/app/components/05.forms/input-text/{InputTextAsNumberWithLabel.vue → InputTextAsNumberField.vue} +66 -62
  53. package/app/components/05.forms/input-text/InputTextField.vue +168 -0
  54. package/app/components/05.forms/input-text/stories/InputPasswordField.stories.ts +163 -0
  55. package/app/components/05.forms/input-text/stories/InputText.stories.ts +194 -0
  56. package/app/components/05.forms/input-text/stories/InputTextAsNumberField.stories.ts +182 -0
  57. package/app/components/05.forms/input-text/stories/InputTextField.stories.ts +206 -0
  58. package/app/components/05.forms/input-text/tests/{InputPasswordWithLabel.spec.ts → InputPasswordField.spec.ts} +42 -3
  59. package/app/components/05.forms/input-text/tests/InputText.spec.ts +166 -0
  60. package/app/components/05.forms/input-text/tests/InputTextAsNumberField.spec.ts +135 -0
  61. package/app/components/05.forms/input-text/tests/InputTextField.spec.ts +130 -0
  62. package/app/components/05.forms/input-textarea/CONSUMER-STYLING.md +94 -12
  63. package/app/components/05.forms/input-textarea/InputTextarea.vue +165 -0
  64. package/app/components/05.forms/input-textarea/InputTextareaField.vue +159 -0
  65. package/app/components/05.forms/input-textarea/stories/InputTextarea.stories.ts +198 -0
  66. package/app/components/05.forms/input-textarea/stories/InputTextareaField.stories.ts +161 -0
  67. package/app/components/05.forms/input-textarea/tests/InputTextarea.spec.ts +149 -0
  68. package/app/components/05.forms/input-textarea/tests/InputTextareaField.spec.ts +122 -0
  69. package/app/components/05.forms/patterns/stories/ContactForm.stories.ts +13 -13
  70. package/app/components/05.forms/patterns/stories/LoginForm.stories.ts +6 -6
  71. package/app/components/05.forms/patterns/stories/MigratedFieldsForm.stories.ts +30 -32
  72. package/app/components/05.forms/toggle-switch/CONSUMER-STYLING.md +71 -50
  73. package/app/components/05.forms/toggle-switch/{ToggleSwitchCore.vue → ToggleSwitch.vue} +58 -73
  74. package/app/components/05.forms/toggle-switch/{ToggleSwitchWithLabel.vue → ToggleSwitchField.vue} +65 -19
  75. package/app/components/05.forms/toggle-switch/stories/ToggleSwitch.stories.ts +148 -0
  76. package/app/components/05.forms/toggle-switch/stories/ToggleSwitchField.stories.ts +176 -0
  77. package/app/components/05.forms/toggle-switch/tests/ToggleSwitch.spec.ts +145 -0
  78. package/app/components/05.forms/toggle-switch/tests/ToggleSwitchField.spec.ts +155 -0
  79. package/package.json +1 -1
  80. package/.claude/skills/components/input-select-core.md +0 -151
  81. package/.claude/skills/components/input-text-core.md +0 -204
  82. package/.claude/skills/components/input-textarea-core.md +0 -154
  83. package/.claude/skills/components/toggle-switch-core.md +0 -169
  84. package/app/components/05.forms/input-select/InputSelectCore.vue +0 -188
  85. package/app/components/05.forms/input-select/InputSelectWithLabel.vue +0 -118
  86. package/app/components/05.forms/input-select/stories/InputSelectCore.stories.ts +0 -69
  87. package/app/components/05.forms/input-select/stories/InputSelectWithLabel.stories.ts +0 -115
  88. package/app/components/05.forms/input-select/tests/InputSelectWithLabel.spec.ts +0 -87
  89. package/app/components/05.forms/input-text/InputTextWithLabel.vue +0 -154
  90. package/app/components/05.forms/input-text/stories/InputPasswordWithLabel.stories.ts +0 -368
  91. package/app/components/05.forms/input-text/stories/InputTextAsNumberWithLabel.stories.ts +0 -480
  92. package/app/components/05.forms/input-text/stories/InputTextCore.stories.ts +0 -267
  93. package/app/components/05.forms/input-text/stories/InputTextWithLabel.stories.ts +0 -319
  94. package/app/components/05.forms/input-text/tests/InputTextAsNumberWithLabel.spec.ts +0 -75
  95. package/app/components/05.forms/input-text/tests/InputTextCore.spec.ts +0 -60
  96. package/app/components/05.forms/input-text/tests/InputTextWithLabel.spec.ts +0 -71
  97. package/app/components/05.forms/input-textarea/InputTextareaCore.vue +0 -159
  98. package/app/components/05.forms/input-textarea/InputTextareaWithLabel.vue +0 -136
  99. package/app/components/05.forms/input-textarea/stories/InputTextareaCore.stories.ts +0 -247
  100. package/app/components/05.forms/input-textarea/stories/InputTextareaWithLabel.stories.ts +0 -458
  101. package/app/components/05.forms/input-textarea/tests/InputTextareaCore.spec.ts +0 -119
  102. package/app/components/05.forms/input-textarea/tests/InputTextareaWithLabel.spec.ts +0 -93
  103. package/app/components/05.forms/toggle-switch/ToggleSwitchWithLabelInline.vue +0 -81
  104. package/app/components/05.forms/toggle-switch/stories/ToggleSwitchCore.stories.ts +0 -251
  105. package/app/components/05.forms/toggle-switch/stories/ToggleSwitchWithLabel.stories.ts +0 -251
  106. package/app/components/05.forms/toggle-switch/stories/ToggleSwitchWithLabelInline.stories.ts +0 -283
  107. package/app/components/05.forms/toggle-switch/tests/ToggleSwitchCore.spec.ts +0 -101
  108. package/app/components/05.forms/toggle-switch/tests/ToggleSwitchWithLabel.spec.ts +0 -133
  109. package/app/components/05.forms/toggle-switch/tests/ToggleSwitchWithLabelInline.spec.ts +0 -66
@@ -181,7 +181,7 @@ Playwright `STORY_BASE` slug. The slug is derived by lowercasing and replacing s
181
181
  | Title | STORY_BASE slug |
182
182
  | --------------------------------------------- | ------------------------------------------- |
183
183
  | `"Atoms/Text Blocks/HeroText"` | `atoms-text-blocks-herotext` |
184
- | `"Components/Forms/Input Text/InputTextCore"` | `components-forms-input-text-inputtextcore` |
184
+ | `"Components/Forms/Input Text/InputText"` | `components-forms-input-text-inputtext` |
185
185
 
186
186
  ## argTypes control types
187
187
 
@@ -25,7 +25,7 @@ overrides (2026-08-25):
25
25
  signalled that to the consumer — the app's declaration became permanently dead, silently. A
26
26
  `var()` with an undefined custom property and no fallback just resolves to the property's
27
27
  initial value; there is no error, no warning, ever.
28
- 2. **Tokens that were "shared" only by accident.** `InputTextCore`, `InputSelectCore`,
28
+ 2. **Tokens that were "shared" only by accident.** `InputText`, `InputSelect`,
29
29
  `InputNumber` and the checkbox button all read the exact same `--theme-input-surface`, so a
30
30
  consumer wanting to restyle just text inputs had no way to do that without also restyling every
31
31
  other input type. The private `--_input-text-surface: var(--theme-input-surface);` indirection
@@ -208,27 +208,27 @@ consuming app having declared anything.
208
208
  Pure token-rename pass, no visual/default changes (unlike `InputButton`'s redesign above).
209
209
  Added Storybook stories for both (`InputCheckboxRadio`, `InputCheckboxRadioButton`) —
210
210
  neither had one before.
211
- - ✅ `InputTextCore`, `InputSelectCore`, `InputNumber` — migrated 2026-08-25, see their
212
- `CONSUMER-STYLING.md`. `InputTextCore`/`InputSelectCore` also had this exact problem's original
211
+ - ✅ `InputText`, `InputSelect`, `InputNumber` — migrated 2026-08-25, see their
212
+ `CONSUMER-STYLING.md`. `InputText`/`InputSelect` also had this exact problem's original
213
213
  form: a private `--_input-text-*`/`--_input-select-*` naming scheme documented as a second
214
214
  "local override path" alongside the global tokens, added 2026-08-22 (three days before this
215
215
  pattern was formalised) as a workaround for a global-override-not-landing report that was never
216
216
  root-caused. That private-var-as-override-point shape is exactly what this pattern replaces —
217
217
  renamed public with real fallbacks, old two-path docs removed. `InputNumber` had no
218
218
  component-scoped tokens at all before this (bare `--theme-input-*` throughout). Added a
219
- Storybook story for `InputSelectCore` (didn't have one); `InputNumber` still doesn't.
220
- `InputTextCore`/`InputSelectCore`'s `.normal` variant also had hover and `:focus-visible` share
219
+ Storybook story for `InputSelect` (didn't have one); `InputNumber` still doesn't.
220
+ `InputText`/`InputSelect`'s `.normal` variant also had hover and `:focus-visible` share
221
221
  one token (literally the same rule content duplicated under two selectors) — split into
222
222
  `--input-text-border-hover`/`--input-select-border-hover` alongside the existing `-border-focus`
223
223
  pair, both still defaulting to `--theme-border-focus` so default rendering is unchanged, but
224
224
  mouse and assistive-tech interaction can now be themed independently. `InputNumber` has no
225
225
  hover state on its border at all (only a `:focus-visible` box-shadow toggle), so there was
226
226
  nothing to split there.
227
- - ✅ `ToggleSwitchCore`, `TripleToggleSwitch`, `DisplayThemeSwitch` — migrated 2026-08-25, see
227
+ - ✅ `ToggleSwitch`, `TripleToggleSwitch`, `DisplayThemeSwitch` — migrated 2026-08-25, see
228
228
  the first two's `CONSUMER-STYLING.md`. Correction to the two lines this replaces: they claimed
229
- `ToggleSwitchCore` read a bare `--theme-toggle-symbol-color-*` — that token doesn't exist
229
+ `ToggleSwitch` read a bare `--theme-toggle-symbol-color-*` — that token doesn't exist
230
230
  anywhere in this codebase and never did; false memory from conflating it with the checkbox
231
- fix. `ToggleSwitchCore` itself turned out to be a plain Tier 2 case (real, live tokens, just no
231
+ fix. `ToggleSwitch` itself turned out to be a plain Tier 2 case (real, live tokens, just no
232
232
  component-scoped override point) plus five confirmed-dead private locals (declared, never read
233
233
  anywhere in the file) removed outright. The real dead-token bug was in `TripleToggleSwitch`
234
234
  (and duplicated in `DisplayThemeSwitch`'s own override): `--theme-form-radio-border`,
@@ -51,7 +51,7 @@ From `00.element-defaults.css` through `09.animation-motion.css`:
51
51
 
52
52
  `00.element-defaults.css` is the one exception — it's not tokens, it's a real selector-based rule
53
53
  (browser autofill background/text-colour reset via `input:autofill` etc.). It reads
54
- `var(--theme-surface)` and the component-private `--_input-text-core-color`, so changing
54
+ `var(--theme-surface)` and the component-private `--_input-text-color`, so changing
55
55
  `--theme-surface` (per `theming-partial-override.md`) changes autofill colours too — no separate
56
56
  override needed there. If you need to change that rule's *behaviour* itself (not just its colour
57
57
  inputs), you'd need a competing unlayered selector of your own targeting the same pseudo-classes,
@@ -1,22 +1,22 @@
1
1
  {
2
- "SRCDEV InputSelectCore Basic": {
3
- "description": "Basic InputSelectCore native select (no label/error wrapper)",
2
+ "SRCDEV InputSelect Basic": {
3
+ "description": "Basic InputSelect native select (no label/error wrapper)",
4
4
  "scope": "vue,html",
5
5
  "body": [
6
- "<InputSelectCore",
6
+ "<InputSelect",
7
7
  " id=\"$1fieldId\"",
8
- " name=\"$2fieldName\"",
9
- " v-model=\"$3fieldValue\"",
10
- " v-model:field-data=\"$4fieldOptions\"",
8
+ " v-model=\"$2fieldValue\"",
9
+ " v-model:field-data=\"$3fieldOptions\"",
10
+ " name=\"$4fieldName\"",
11
11
  " placeholder=\"$5Choose an option\"",
12
12
  "/>"
13
13
  ]
14
14
  },
15
- "SRCDEV InputSelectWithLabel Basic": {
16
- "description": "InputSelectWithLabel: labelled select with error/description support",
15
+ "SRCDEV InputSelectField Basic": {
16
+ "description": "InputSelectField: labelled select with description and error support",
17
17
  "scope": "vue,html",
18
18
  "body": [
19
- "<InputSelectWithLabel",
19
+ "<InputSelectField",
20
20
  " v-model=\"$1fieldValue\"",
21
21
  " v-model:field-data=\"$2fieldOptions\"",
22
22
  " name=\"$3fieldName\"",
@@ -24,17 +24,23 @@
24
24
  " placeholder=\"$5Choose an option\"",
25
25
  " :error-message=\"$6errors.fieldName\"",
26
26
  " :field-has-error=\"!!$6errors.fieldName\"",
27
- "/>"
27
+ ">",
28
+ " <template #descriptionText>$7</template>",
29
+ "</InputSelectField>"
28
30
  ]
29
31
  },
30
32
  "SRCDEV InputSelect CSS Override": {
31
- "description": "CSS override scaffold for InputSelectCore tokens",
33
+ "description": "CSS override scaffold for InputSelect tokens",
32
34
  "scope": "css",
33
35
  "body": [
34
36
  ".$1my-page {",
35
- " .input-select-wrapper {",
36
- " --input-select-surface: $2;",
37
- " --input-select-border: $3;",
37
+ " --input-select-surface: $2;",
38
+ " --input-select-text-color: $3;",
39
+ " --input-select-border: $4;",
40
+ " --input-select-border-focus: $5;",
41
+ "",
42
+ " .input-select-field[data-invalid] {",
43
+ " $0",
38
44
  " }",
39
45
  "}"
40
46
  ]
@@ -1,53 +1,54 @@
1
1
  {
2
- "SRCDEV InputTextCore Basic": {
3
- "description": "Basic InputTextCore native input (no label/error wrapper)",
2
+ "SRCDEV InputText Basic": {
3
+ "description": "Basic InputText native input (no label/error wrapper)",
4
4
  "scope": "vue,html",
5
5
  "body": [
6
- "<InputTextCore",
6
+ "<InputText",
7
7
  " id=\"$1fieldId\"",
8
- " name=\"$2fieldName\"",
9
- " v-model=\"$3fieldValue\"",
8
+ " v-model=\"$2fieldValue\"",
9
+ " name=\"$3fieldName\"",
10
10
  " type=\"$4text\"",
11
- " placeholder=\"$5Enter value...\"",
11
+ " placeholder=\"$5Enter value\"",
12
12
  "/>"
13
13
  ]
14
14
  },
15
- "SRCDEV InputTextCore Date with min/max": {
16
- "description": "InputTextCore date input constrained to a min/max range (e.g. no dates in the past)",
15
+ "SRCDEV InputText Date with min/max": {
16
+ "description": "InputText date input constrained to a min/max range (e.g. no dates in the past)",
17
17
  "scope": "vue,html",
18
18
  "body": [
19
- "<InputTextCore",
19
+ "<InputText",
20
20
  " id=\"$1appointment-date\"",
21
- " name=\"$2appointmentDate\"",
22
- " v-model=\"$3appointmentDate\"",
21
+ " v-model=\"$2appointmentDate\"",
22
+ " name=\"$3appointmentDate\"",
23
23
  " type=\"date\"",
24
24
  " :min=\"new Date().toISOString().split('T')[0]\"",
25
25
  " max=\"$42027-12-31\"",
26
26
  "/>"
27
27
  ]
28
28
  },
29
- "SRCDEV InputTextWithLabel Basic": {
30
- "description": "InputTextWithLabel: labelled text field with error/description support",
29
+ "SRCDEV InputTextField Basic": {
30
+ "description": "InputTextField: labelled text field with description and error support",
31
31
  "scope": "vue,html",
32
32
  "body": [
33
- "<InputTextWithLabel",
33
+ "<InputTextField",
34
34
  " v-model=\"$1fieldValue\"",
35
- " id=\"$2fieldId\"",
36
- " name=\"$3fieldName\"",
37
- " type=\"$4text\"",
38
- " label=\"$5Field label\"",
35
+ " name=\"$2fieldName\"",
36
+ " type=\"${3|text,email,tel,url,date,number|}\"",
37
+ " label=\"$4Field label\"",
38
+ " autocomplete=\"$5\"",
39
39
  " :error-message=\"$6errors.fieldName\"",
40
40
  " :field-has-error=\"!!$6errors.fieldName\"",
41
- "/>"
41
+ ">",
42
+ " <template #descriptionText>$7</template>",
43
+ "</InputTextField>"
42
44
  ]
43
45
  },
44
- "SRCDEV InputTextWithLabel Date with min/max": {
45
- "description": "InputTextWithLabel date field constrained to a min/max range",
46
+ "SRCDEV InputTextField Date with min/max": {
47
+ "description": "InputTextField date field constrained to a min/max range",
46
48
  "scope": "vue,html",
47
49
  "body": [
48
- "<InputTextWithLabel",
50
+ "<InputTextField",
49
51
  " v-model=\"$1appointmentDate\"",
50
- " id=\"$2appointment-date\"",
51
52
  " name=\"$2appointmentDate\"",
52
53
  " type=\"date\"",
53
54
  " label=\"$3Appointment date\"",
@@ -58,24 +59,27 @@
58
59
  "/>"
59
60
  ]
60
61
  },
61
- "SRCDEV InputPasswordWithLabel": {
62
- "description": "InputPasswordWithLabel with show/hide toggle",
62
+ "SRCDEV InputPasswordField": {
63
+ "description": "InputPasswordField with show/hide toggle",
63
64
  "scope": "vue,html",
64
65
  "body": [
65
- "<InputPasswordWithLabel",
66
+ "<InputPasswordField",
66
67
  " v-model=\"$1password\"",
67
68
  " name=\"$2password\"",
68
69
  " label=\"$3Password\"",
69
- " :error-message=\"$4errors.password\"",
70
- " :field-has-error=\"!!$4errors.password\"",
70
+ " autocomplete=\"${4|current-password,new-password|}\"",
71
+ " :error-message=\"$5errors.password\"",
72
+ " :field-has-error=\"!!$5errors.password\"",
73
+ " show-password-text=\"$6Show password\"",
74
+ " hide-password-text=\"$7Hide password\"",
71
75
  "/>"
72
76
  ]
73
77
  },
74
- "SRCDEV InputTextAsNumberWithLabel": {
75
- "description": "InputTextAsNumberWithLabel numeric stepper with min/max/step",
78
+ "SRCDEV InputTextAsNumberField": {
79
+ "description": "InputTextAsNumberField numeric stepper with min/max/step",
76
80
  "scope": "vue,html",
77
81
  "body": [
78
- "<InputTextAsNumberWithLabel",
82
+ "<InputTextAsNumberField",
79
83
  " v-model=\"$1quantity\"",
80
84
  " name=\"$2quantity\"",
81
85
  " label=\"$3Quantity\"",
@@ -85,21 +89,23 @@
85
89
  " :error-message=\"$7errors.quantity\"",
86
90
  " :field-has-error=\"!!$7errors.quantity\"",
87
91
  ">",
88
- " <template #left>−</template>",
89
- " <template #right>+</template>",
90
- "</InputTextAsNumberWithLabel>"
92
+ " <template #left><Icon name=\"mdi:minus\" /></template>",
93
+ " <template #right><Icon name=\"mdi:plus\" /></template>",
94
+ "</InputTextAsNumberField>"
91
95
  ]
92
96
  },
93
97
  "SRCDEV InputText CSS Override": {
94
- "description": "CSS override scaffold for InputTextCore tokens",
98
+ "description": "CSS override scaffold for InputText tokens",
95
99
  "scope": "css",
96
100
  "body": [
97
101
  ".$1my-page {",
98
- " .input-text-wrapper {",
99
- " --input-text-surface: $2;",
100
- " --input-text-border: $3;",
101
- " --input-text-border-focus: $4;",
102
- " --input-text-color: $5;",
102
+ " --input-text-surface: $2;",
103
+ " --input-text-border: $3;",
104
+ " --input-text-border-focus: $4;",
105
+ " --input-text-color: $5;",
106
+ "",
107
+ " .input-text-field[data-invalid] {",
108
+ " $0",
103
109
  " }",
104
110
  "}"
105
111
  ]
@@ -1,38 +1,43 @@
1
1
  {
2
- "SRCDEV InputTextareaCore Basic": {
3
- "description": "Basic InputTextareaCore native textarea (no label/error wrapper)",
2
+ "SRCDEV InputTextarea Basic": {
3
+ "description": "Basic InputTextarea native textarea (no label/error wrapper)",
4
4
  "scope": "vue,html",
5
5
  "body": [
6
- "<InputTextareaCore",
6
+ "<InputTextarea",
7
7
  " id=\"$1fieldId\"",
8
- " name=\"$2fieldName\"",
9
- " v-model=\"$3fieldValue\"",
8
+ " v-model=\"$2fieldValue\"",
9
+ " name=\"$3fieldName\"",
10
10
  " placeholder=\"$4Placeholder text\"",
11
11
  "/>"
12
12
  ]
13
13
  },
14
- "SRCDEV InputTextareaWithLabel Basic": {
15
- "description": "InputTextareaWithLabel: labelled textarea with error/description support",
14
+ "SRCDEV InputTextareaField Basic": {
15
+ "description": "InputTextareaField: labelled textarea with description and error support",
16
16
  "scope": "vue,html",
17
17
  "body": [
18
- "<InputTextareaWithLabel",
18
+ "<InputTextareaField",
19
19
  " v-model=\"$1fieldValue\"",
20
20
  " name=\"$2fieldName\"",
21
21
  " label=\"$3Field label\"",
22
- " placeholder=\"$4Placeholder text\"",
22
+ " :maxlength=\"${4:1000}\"",
23
23
  " :error-message=\"$5errors.fieldName\"",
24
24
  " :field-has-error=\"!!$5errors.fieldName\"",
25
- "/>"
25
+ ">",
26
+ " <template #descriptionText>$6</template>",
27
+ "</InputTextareaField>"
26
28
  ]
27
29
  },
28
30
  "SRCDEV InputTextarea CSS Override": {
29
- "description": "CSS override scaffold for InputTextareaCore tokens",
31
+ "description": "CSS override scaffold for InputTextarea tokens",
30
32
  "scope": "css",
31
33
  "body": [
32
34
  ".$1my-page {",
33
- " .input-textarea-wrapper {",
34
- " --input-textarea-surface: $2;",
35
- " --input-textarea-border: $3;",
35
+ " --input-textarea-surface: $2;",
36
+ " --input-textarea-border: $3;",
37
+ " --input-textarea-max-height: ${4:20lh};",
38
+ "",
39
+ " .input-textarea-field[data-invalid] {",
40
+ " $0",
36
41
  " }",
37
42
  "}"
38
43
  ]
@@ -1,50 +1,40 @@
1
1
  {
2
- "SRCDEV ToggleSwitchCore": {
3
- "description": "ToggleSwitchCore — bare toggle switch (no label, use ToggleSwitchWithLabel for that)",
2
+ "SRCDEV ToggleSwitch": {
3
+ "description": "ToggleSwitch: bare switch (pair with a label for=\"toggle-switch-{id}\", or use ToggleSwitchField)",
4
4
  "scope": "vue,html",
5
5
  "body": [
6
- "<ToggleSwitchCore",
7
- " v-model=\"$1modelValue\"",
8
- " id=\"$2toggle-id\"",
9
- " name=\"$3toggleName\"",
6
+ "<label for=\"toggle-switch-$1toggle-id\">$2Label</label>",
7
+ "<ToggleSwitch",
8
+ " id=\"$1toggle-id\"",
9
+ " v-model=\"$3modelValue\"",
10
+ " name=\"$4toggleName\"",
10
11
  "/>"
11
12
  ]
12
13
  },
13
- "SRCDEV ToggleSwitchWithLabel": {
14
- "description": "ToggleSwitchWithLabel: labelled toggle switch with description/error support",
14
+ "SRCDEV ToggleSwitchField": {
15
+ "description": "ToggleSwitchField: labelled switch with description and error support",
15
16
  "scope": "vue,html",
16
17
  "body": [
17
- "<ToggleSwitchWithLabel",
18
+ "<ToggleSwitchField",
18
19
  " v-model=\"$1fieldValue\"",
19
20
  " name=\"$2fieldName\"",
20
21
  " label=\"$3Field label\"",
21
- " :error-message=\"$4errors.fieldName\"",
22
- " :field-has-error=\"!!$4errors.fieldName\"",
22
+ " layout=\"${4|stacked,inline|}\"",
23
+ " :error-message=\"$5errors.fieldName\"",
24
+ " :field-has-error=\"!!$5errors.fieldName\"",
23
25
  ">",
24
- " <template #descriptionText>$5Help text</template>",
25
- "</ToggleSwitchWithLabel>"
26
- ]
27
- },
28
- "SRCDEV ToggleSwitchWithLabelInline": {
29
- "description": "ToggleSwitchWithLabelInline: compact label + toggle switch side by side, no error support",
30
- "scope": "vue,html",
31
- "body": [
32
- "<ToggleSwitchWithLabelInline",
33
- " v-model=\"$1fieldValue\"",
34
- " name=\"$2fieldName\"",
35
- " label=\"$3Field label\"",
36
- "/>"
26
+ " <template #descriptionText>$6Help text</template>",
27
+ "</ToggleSwitchField>"
37
28
  ]
38
29
  },
39
30
  "SRCDEV ToggleSwitch CSS Override": {
40
- "description": "CSS override scaffold for ToggleSwitchCore tokens",
31
+ "description": "CSS override scaffold for ToggleSwitch tokens",
41
32
  "scope": "css",
42
33
  "body": [
43
34
  ".$1my-page {",
44
- " .toggle-switch-wrapper {",
45
- " --toggle-switch-surface: $2;",
46
- " --toggle-switch-symbol-surface-on: $3;",
47
- " }",
35
+ " --toggle-switch-surface: $2;",
36
+ " --toggle-switch-symbol-surface-on: $3;",
37
+ " --input-toggle-symbol-size: ${4:2.4rem};",
48
38
  "}"
49
39
  ]
50
40
  }
@@ -11,9 +11,9 @@
11
11
  input:-webkit-autofill-and-obscured {
12
12
  background-color: var(--theme-surface) !important;
13
13
  background-image: none !important;
14
- color: var(--_input-text-core-color) !important;
14
+ color: var(--input-text-color, var(--theme-input-text-color-normal)) !important;
15
15
  -webkit-box-shadow: 0 0 0rem 1000px var(--theme-surface) inset;
16
- -webkit-text-fill-color: var(--_input-text-core-color);
16
+ -webkit-text-fill-color: var(--input-text-color, var(--theme-input-text-color-normal));
17
17
  transition: background-color 5000s ease-in-out 0s;
18
18
  }
19
19
  }
@@ -17,7 +17,7 @@
17
17
  box alone — .input-button keeps box-sizing: content-box (changing that risks shifting
18
18
  icon-only's aspect-ratio: 1 sizing), so its own padding-block and border have to be
19
19
  subtracted back out here, unlike --input-min-height itself which happens to need no such
20
- adjustment (InputTextCore has zero padding-block and no full border in its resting state).
20
+ adjustment (InputText has zero padding-block and no full border in its resting state).
21
21
  This is a floor, not a fixed height — icon-only/pill buttons or longer button-text can
22
22
  still grow past it. Textareas are the deliberate exception to this alignment entirely. */
23
23
  --button-min-height: calc(
@@ -86,7 +86,7 @@ For a single "special" button or input, wrap just the control so the glow become
86
86
  No changes to the control are needed:
87
87
 
88
88
  - `InputButton`'s border already defaults to its own surface colour, so it shows no edge of its own.
89
- - `InputTextCore` needs `--input-text-border: transparent`.
89
+ - `InputText` needs `--input-text-border: transparent`.
90
90
  - On the `GlowingBorder`: radius is the control's radius plus the glow width, surface
91
91
  `transparent`, overflow `visible` (so the control's hover and focus outlines aren't clipped),
92
92
  and an inline or shrink-to-fit display so it hugs the control.
@@ -97,7 +97,7 @@ No changes to the control are needed:
97
97
  </GlowingBorder>
98
98
 
99
99
  <GlowingBorder variant="vivid" style-class-passthrough="special-input">
100
- <InputTextCore id="email" v-model="email" type="email" name="email"></InputTextCore>
100
+ <InputText id="email" v-model="email" type="email" name="email"></InputText>
101
101
  </GlowingBorder>
102
102
  ```
103
103
 
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryFn } from "@nuxtjs/storybook";
2
2
  import { computed, ref } from "vue";
3
3
  import StorybookComponent from "../GlowingBorder.vue";
4
- import InputTextCore from "../../../../05.forms/input-text/InputTextCore.vue";
4
+ import InputText from "../../../../05.forms/input-text/InputText.vue";
5
5
  import InputButton from "../../../../05.forms/input-button/InputButton.vue";
6
6
  import CanvasSwitcher from "../../../canvas-switcher/CanvasSwitcher.vue";
7
7
  import type { MediaCanvas } from "~/types/components";
@@ -194,7 +194,7 @@ CustomTokens.args = {
194
194
  };
195
195
 
196
196
  export const HighlightedControls: StoryFn<StoryArgs> = (args) => ({
197
- components: { StorybookComponent, InputTextCore, InputButton },
197
+ components: { StorybookComponent, InputText, InputButton },
198
198
  setup() {
199
199
  const { args: storyArgs, stageStyle } = useStorySetup(args);
200
200
  const glowStyle = (controlRadius: string) =>
@@ -224,13 +224,13 @@ export const HighlightedControls: StoryFn<StoryArgs> = (args) => ({
224
224
  <div style="display: grid; gap: 8px; inline-size: min(100%, 40rem);">
225
225
  <label for="highlighted-email">Early-access email</label>
226
226
  <StorybookComponent :variant="args.variant" :style="inputGlowStyle">
227
- <InputTextCore
227
+ <InputText
228
228
  id="highlighted-email"
229
229
  v-model="email"
230
230
  type="email"
231
231
  name="highlighted-email"
232
232
  placeholder="eg. jane@example.com"
233
- ></InputTextCore>
233
+ ></InputText>
234
234
  </StorybookComponent>
235
235
  </div>
236
236
  </div>
@@ -2,7 +2,7 @@ import { computed, reactive, ref } from "vue";
2
2
  import ProgressTracker from "../ProgressTracker.vue";
3
3
  import CanvasSwitcher from "../../../01.atoms/canvas-switcher/CanvasSwitcher.vue";
4
4
  import InputButton from "../../../05.forms/input-button/InputButton.vue";
5
- import InputTextWithLabel from "../../../05.forms/input-text/InputTextWithLabel.vue";
5
+ import InputTextField from "../../../05.forms/input-text/InputTextField.vue";
6
6
  import type { Meta, StoryObj } from "@nuxtjs/storybook";
7
7
  import type { MediaCanvas, ProgressTrackerStep } from "~/types/components";
8
8
 
@@ -217,7 +217,7 @@ export const Wizard: Story = {
217
217
  name: "Wizard (parent-owned forms)",
218
218
  args: { modelValue: 0, steps: wizardSteps },
219
219
  render: (args) => ({
220
- components: { ProgressTracker, InputButton, InputTextWithLabel },
220
+ components: { ProgressTracker, InputButton, InputTextField },
221
221
  setup() {
222
222
  const story = useStorySetup(args);
223
223
  const form = reactive({ name: "", email: "" });
@@ -254,7 +254,7 @@ export const Wizard: Story = {
254
254
  <ProgressTracker v-bind="componentArgs" v-model="args.modelValue" :steps="steps">
255
255
  <template #step-0="{ headingId }">
256
256
  <form :aria-labelledby="headingId" style="display: grid; gap: 1.6rem;" @submit.prevent="next('name')">
257
- <InputTextWithLabel
257
+ <InputTextField
258
258
  v-model="form.name"
259
259
  type="text"
260
260
  name="wizard-name"
@@ -270,7 +270,7 @@ export const Wizard: Story = {
270
270
  </template>
271
271
  <template #step-1="{ headingId }">
272
272
  <form :aria-labelledby="headingId" style="display: grid; gap: 1.6rem;" @submit.prevent="next('email')">
273
- <InputTextWithLabel
273
+ <InputTextField
274
274
  v-model="form.email"
275
275
  type="email"
276
276
  name="wizard-email"
@@ -1,7 +1,7 @@
1
1
  # InputError — Consumer Styling Guide
2
2
 
3
3
  `InputError` is the red error message strip rendered under a form control by every `*Field`
4
- wrapper (`InputTextWithLabel`, `InputNumberField`, `InputSelectWithLabel`, `SingleCheckbox`, ...).
4
+ wrapper (`InputTextField`, `InputNumberField`, `InputSelectField`, `SingleCheckbox`, ...).
5
5
  It animates open (`grid-template-rows: 0fr → 1fr` plus opacity) when the field is in error.
6
6
 
7
7
  ## Public token API
@@ -1,7 +1,7 @@
1
1
  # FormField — Consumer Styling Guide
2
2
 
3
3
  `FormField` is a layout wrapper for one form control (typically an `*Field` component such as
4
- `InputTextWithLabel` or `InputNumberField`). It caps the field's width, centres it, optionally
4
+ `InputTextField` or `InputNumberField`). It caps the field's width, centres it, optionally
5
5
  insets it from its container's edges with a gutter, and applies vertical spacing between fields.
6
6
 
7
7
  ## Public token API
@@ -65,7 +65,7 @@ Set the tokens above on an element you own (a page or section class, or a class
65
65
 
66
66
  ```vue
67
67
  <FormField width="wide" style="--form-field-background-color: var(--slate-01);">
68
- <InputTextWithLabel ... />
68
+ <InputTextField ... />
69
69
  </FormField>
70
70
  ```
71
71
 
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryFn } from "@nuxtjs/storybook";
2
2
  import { ref } from "vue";
3
3
  import StorybookComponent from "../InputButton.vue";
4
- import InputTextCore from "../../input-text/InputTextCore.vue";
4
+ import InputText from "../../input-text/InputText.vue";
5
5
 
6
6
  interface InputButtonStoryArgs {
7
7
  type: "submit" | "button" | "reset";
@@ -314,11 +314,11 @@ NuxtIconOnlyComponent.args = {
314
314
  // most common "usual suspect" pairing (e.g. newsletter signup, search bar). Textareas are the
315
315
  // deliberate exception to this alignment and aren't part of this story.
316
316
  const InlineTemplate: StoryFn = () => ({
317
- components: { StorybookComponent, InputTextCore },
317
+ components: { StorybookComponent, InputText },
318
318
  template: `
319
319
  <div style="margin: 36px; max-width: 480px;">
320
320
  <div style="display: flex; align-items: flex-start; gap: 0.8rem;">
321
- <InputTextCore
321
+ <InputText
322
322
  id="inline-email"
323
323
  name="email"
324
324
  type="email"
@@ -1,8 +1,8 @@
1
1
  # InputDescription — Consumer Styling Guide
2
2
 
3
3
  `InputDescription` is the help text rendered between the label and the control by every `*Field`
4
- wrapper (`InputTextWithLabel`, `InputNumberField`, `InputSelectWithLabel`,
5
- `InputTextareaWithLabel`, `InputRangeField`, `InputTextAsNumberWithLabel`, `SingleCheckbox`,
4
+ wrapper (`InputTextField`, `InputNumberField`, `InputSelectField`,
5
+ `InputTextareaField`, `InputRangeField`, `InputTextAsNumberField`, `SingleCheckbox`,
6
6
  `MultipleCheckboxes`, `MultipleRadiobuttons`) when you pass it a `descriptionText` or
7
7
  `descriptionHtml` slot. With neither slot it renders nothing.
8
8
 
@@ -84,9 +84,9 @@ description. Keep these blocks **unlayered** (no `@layer ...` wrapper) so they b
84
84
  ```vue
85
85
  <template>
86
86
  <div class="contact-page-content">
87
- <InputTextWithLabel v-model="email" name="email" label="Email">
87
+ <InputTextField v-model="email" name="email" label="Email">
88
88
  <template #descriptionText>We'll only use this for your booking confirmation</template>
89
- </InputTextWithLabel>
89
+ </InputTextField>
90
90
  </div>
91
91
  </template>
92
92
 
@@ -108,9 +108,9 @@ The wrappers don't forward `style-class-passthrough` to the description, but a p
108
108
  the wrapper itself lands on its root element, which is an ancestor of the description:
109
109
 
110
110
  ```vue
111
- <InputTextWithLabel class="email-field" v-model="email" name="email" label="Email">
111
+ <InputTextField class="email-field" v-model="email" name="email" label="Email">
112
112
  <template #descriptionText>We'll only use this for your booking confirmation</template>
113
- </InputTextWithLabel>
113
+ </InputTextField>
114
114
 
115
115
  <style>
116
116
  .email-field {