srcdev-nuxt-components 9.3.1 → 9.3.2

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.
@@ -0,0 +1,42 @@
1
+ # InputSelectCore — Consumer Styling Guide
2
+
3
+ ## Two override paths
4
+
5
+ Same public/private split as `InputTextCore` (see that component's `CONSUMER-STYLING.md` for the
6
+ full rationale) — `.input-select-wrapper` now exposes local tokens, one indirection step below the
7
+ global `--theme-*` ones they default from:
8
+
9
+ ```css
10
+ --_input-select-surface: var(--theme-input-surface);
11
+ --_input-select-surface-hover: var(--theme-input-surface-hover);
12
+ --_input-select-border: var(--theme-border);
13
+ --_input-select-border-focus: var(--theme-border-focus);
14
+ --_input-select-outline-color: var(--_input-select-border-focus);
15
+ ```
16
+
17
+ - **Global override**: redeclare `--theme-input-surface` / `--theme-border` / `--theme-border-focus`
18
+ / `--theme-input-surface-hover` wherever you'd normally set theme tokens.
19
+ - **Local override** (this component only, guaranteed to win):
20
+
21
+ ```css
22
+ .input-select-wrapper {
23
+ --_input-select-border: var(--slate-06);
24
+ --_input-select-border-focus: var(--slate-04);
25
+ --_input-select-surface: var(--slate-01);
26
+ }
27
+ ```
28
+
29
+ ## Note on `--_input-select-outline-color`
30
+
31
+ Before 2026-08-22 this was referenced (on the open-picker outline) but never declared anywhere —
32
+ a dangling private token that silently resolved to the property's initial value (same failure mode
33
+ as the `--theme-button-surface` typo documented in the layer's `CLAUDE.md`, pitfall list). It's now
34
+ properly defined, defaulting to `--_input-select-border-focus`.
35
+
36
+ ---
37
+
38
+ ## Other tokens
39
+
40
+ Generic form-geometry tokens (`--input-padding-inline`, `--input-min-height`, `--input-font-size`,
41
+ `--form-element-border-width`, `--form-input-border-radius`, etc.) are shared across every
42
+ `05.forms` component and declared in `setup/04.elements/forms/*.css` — not component-local.
@@ -73,7 +73,17 @@ const fieldData = defineModel("fieldData") as Ref<IFormMultipleOptions>;
73
73
  <style lang="css">
74
74
  @layer components {
75
75
  .input-select-wrapper {
76
- background-color: var(--theme-input-surface);
76
+ /* Local overrides, one indirection step below the global --theme-* tokens they default from —
77
+ a consumer can target `.input-select-wrapper { --_input-select-border: ...; }` directly for
78
+ a guaranteed-specific override, instead of relying solely on redefining the global token.
79
+ See CONSUMER-STYLING.md. */
80
+ --_input-select-surface: var(--theme-input-surface);
81
+ --_input-select-surface-hover: var(--theme-input-surface-hover);
82
+ --_input-select-border: var(--theme-border);
83
+ --_input-select-border-focus: var(--theme-border-focus);
84
+ --_input-select-outline-color: var(--_input-select-border-focus);
85
+
86
+ background-color: var(--_input-select-surface);
77
87
  overflow: hidden;
78
88
 
79
89
  z-index: 2;
@@ -81,31 +91,33 @@ const fieldData = defineModel("fieldData") as Ref<IFormMultipleOptions>;
81
91
  transition: all var(--theme-form-transition-duration) ease-in-out;
82
92
 
83
93
  &.normal {
84
- border: var(--form-element-border-width) solid var(--theme-border);
94
+ border: var(--form-element-border-width) solid var(--_input-select-border);
85
95
  border-radius: var(--form-input-border-radius);
86
96
  outline: var(--form-element-outline-width) solid transparent;
87
97
  }
88
98
 
89
99
  &.underlined {
90
- border-bottom: var(--form-element-border-bottom-width-underlined) solid var(--theme-border);
91
- background-color: var(--theme-input-surface);
100
+ border-bottom: var(--form-element-border-bottom-width-underlined) solid var(--_input-select-border);
101
+ background-color: var(--_input-select-surface);
92
102
  }
93
103
 
94
104
  &:has(select:focus-visible, :hover) {
95
- outline: var(--form-element-outline-width-focus) solid var(--theme-border-focus);
105
+ outline: var(--form-element-outline-width-focus) solid var(--_input-select-border-focus);
96
106
  outline-offset: var(--form-element-outline-offset-focus);
97
107
  }
98
108
 
99
109
  .input-select-core {
100
110
  appearance: none;
101
111
  background-color: transparent;
112
+ display: flex;
113
+ align-items: center;
102
114
 
103
115
  /* For legacy support - eg, Safari */
104
116
  /* &::after {
105
117
  content: '';
106
118
  width: 0.8em;
107
119
  height: 0.5em;
108
- background-color: var(--theme-border);
120
+ background-color: var(--_input-select-border);
109
121
  clip-path: polygon(100% 0%, 0 0%, 50% 100%);
110
122
  } */
111
123
 
@@ -128,7 +140,7 @@ const fieldData = defineModel("fieldData") as Ref<IFormMultipleOptions>;
128
140
 
129
141
  &:open::picker(select) {
130
142
  opacity: 1;
131
- border: var(--form-element-border-width) solid var(--theme-border);
143
+ border: var(--form-element-border-width) solid var(--_input-select-border);
132
144
  outline: var(--form-element-outline-width) solid var(--_input-select-outline-color);
133
145
 
134
146
  @starting-style {
@@ -145,7 +157,7 @@ const fieldData = defineModel("fieldData") as Ref<IFormMultipleOptions>;
145
157
 
146
158
  font-family: var(--font-family);
147
159
  font-size: var(--input-font-size);
148
- line-height: var(--input-element-line-height);
160
+ /* line-height: var(--input-element-line-height); */
149
161
  padding-block: var(--input-padding-block);
150
162
  padding-inline: var(--input-padding-inline);
151
163
  min-height: var(--input-min-height);
@@ -156,7 +168,7 @@ const fieldData = defineModel("fieldData") as Ref<IFormMultipleOptions>;
156
168
  transition: all var(--theme-form-transition-duration) ease-in-out;
157
169
 
158
170
  &:hover {
159
- background-color: var(--theme-input-surface-hover);
171
+ background-color: var(--_input-select-surface-hover);
160
172
  }
161
173
 
162
174
  .input-select-core-option-decorator-icon {
@@ -0,0 +1,60 @@
1
+ # InputTextCore — Consumer Styling Guide
2
+
3
+ ## Two override paths
4
+
5
+ Before 2026-08-22, `.input-text-wrapper` read the global `--theme-*` tokens directly
6
+ (`--theme-input-surface`, `--theme-border`, `--theme-border-focus`, `--theme-input-surface-hover`).
7
+ Overriding those globally (e.g. in a consumer app's unlayered `:root` block) should always have
8
+ worked on pure CSS-cascade grounds — an unlayered `:root` declaration (specificity `0,1,0`) beats
9
+ the layer's own `:where(html, [data-theme], [data-invalid])` declaration (specificity `0`)
10
+ regardless of source/import order — but a consumer app hit a case where a global override wasn't
11
+ visibly landing and the root cause wasn't pinned down (see `nuxt-components`'s own git history
12
+ around the same date for a *different*, confirmed bug in a sibling app: wrapping consumer CSS in
13
+ `@layer consumer` broke in production because SSR-inlined per-chunk `<style>` tags fix layer
14
+ priority by first-reference document order, not the app's intended `@layer` statement order — sic
15
+ that isn't what was happening here, since the consumer app's CSS was already unlayered, but it's
16
+ the same class of "cascade behaves differently than a clean mental model predicts" issue).
17
+
18
+ Rather than leave global-token overrides as the only lever, `.input-text-wrapper` now also
19
+ exposes its own local tokens, one indirection step below the global ones:
20
+
21
+ ```css
22
+ --_input-text-surface: var(--theme-input-surface);
23
+ --_input-text-surface-hover: var(--theme-input-surface-hover);
24
+ --_input-text-border: var(--theme-border);
25
+ --_input-text-border-focus: var(--theme-border-focus);
26
+ ```
27
+
28
+ - **Global override** (affects every themed component, not just this one): redeclare
29
+ `--theme-input-surface` / `--theme-border` / `--theme-border-focus` / `--theme-input-surface-hover`
30
+ at whatever scope you'd normally set theme tokens (`:root`, `[data-theme]`, a page wrapper).
31
+ - **Local override** (this component only, guaranteed to win — it's the last declaration before
32
+ the property that consumes it, no global-token indirection to reason about):
33
+
34
+ ```css
35
+ /* Unscoped consumer CSS, no :deep() needed */
36
+ .input-text-wrapper {
37
+ --_input-text-border: var(--slate-06);
38
+ --_input-text-border-focus: var(--slate-04);
39
+ --_input-text-surface: var(--slate-01);
40
+ }
41
+ ```
42
+
43
+ Prefer the local override when you only want to change this one component's look, or when you've
44
+ hit a case (like the one above) where a global-token change isn't landing and you don't have time
45
+ to dig into why — the local path is a strictly simpler cascade to reason about.
46
+
47
+ ---
48
+
49
+ ## Other tokens
50
+
51
+ - `--input-icon-slot-gap`, `--input-padding-inline`, `--input-padding-block`, `--input-min-height`,
52
+ `--input-font-size`, `--form-element-border-width`, `--form-input-border-radius`,
53
+ `--form-element-border-bottom-width-underlined`, `--form-element-outline-width(-focus)`,
54
+ `--form-element-outline-offset-focus` — all generic form-geometry tokens shared across every
55
+ `05.forms` component, declared in `setup/04.elements/forms/*.css`. Not component-local, so
56
+ overriding one affects every form element, not just `InputTextCore`.
57
+ - `--theme-input-text-color-normal`, `--theme-input-placeholder`,
58
+ `--theme-input-placeholder-font-size` — still read directly from the global theme tokens, no
59
+ local indirection yet. Follow the same pattern above (`--_input-text-*`) if a future consumer
60
+ needs a local override for these.
@@ -127,10 +127,19 @@ onMounted(() => {
127
127
  <style lang="css">
128
128
  @layer components {
129
129
  .input-text-wrapper {
130
+ /* Local overrides, one indirection step below the global --theme-* tokens they default from
131
+ — a consumer can target `.input-text-wrapper { --_input-text-border: ...; }` directly for
132
+ a guaranteed-specific override, instead of relying solely on redefining the global token.
133
+ See CONSUMER-STYLING.md. */
134
+ --_input-text-surface: var(--theme-input-surface);
135
+ --_input-text-surface-hover: var(--theme-input-surface-hover);
136
+ --_input-text-border: var(--theme-border);
137
+ --_input-text-border-focus: var(--theme-border-focus);
138
+
130
139
  display: flex;
131
140
  align-items: center;
132
141
  gap: var(--input-icon-slot-gap);
133
- background-color: var(--theme-input-surface);
142
+ background-color: var(--_input-text-surface);
134
143
  overflow: hidden;
135
144
  transition: all var(--theme-form-transition-duration) ease-in-out;
136
145
 
@@ -138,25 +147,25 @@ onMounted(() => {
138
147
  position: relative;
139
148
 
140
149
  &.normal {
141
- border: var(--form-element-border-width) solid var(--theme-border);
150
+ border: var(--form-element-border-width) solid var(--_input-text-border);
142
151
  border-radius: var(--form-input-border-radius);
143
152
  outline: var(--form-element-outline-width) solid transparent;
144
153
 
145
154
  padding-inline: var(--input-padding-inline);
146
155
 
147
156
  &:has(input:is(:hover), button:is(:hover)) {
148
- outline: var(--form-element-outline-width-focus) solid var(--theme-border-focus);
157
+ outline: var(--form-element-outline-width-focus) solid var(--_input-text-border-focus);
149
158
  outline-offset: var(--form-element-outline-offset-focus);
150
159
  }
151
160
 
152
161
  &:has(input:focus-visible, button:focus-visible) {
153
- outline: var(--form-element-outline-width-focus) solid var(--theme-border-focus);
162
+ outline: var(--form-element-outline-width-focus) solid var(--_input-text-border-focus);
154
163
  outline-offset: var(--form-element-outline-offset-focus);
155
164
  }
156
165
  }
157
166
 
158
167
  &.underlined {
159
- border-bottom: var(--form-element-border-bottom-width-underlined) solid var(--theme-border);
168
+ border-bottom: var(--form-element-border-bottom-width-underlined) solid var(--_input-text-border);
160
169
  padding-inline: var(--input-padding-inline);
161
170
  }
162
171
 
@@ -171,17 +180,17 @@ onMounted(() => {
171
180
  box-sizing: content-box;
172
181
 
173
182
  .input-button-core {
174
- background-color: var(--theme-input-surface);
183
+ background-color: var(--_input-text-surface);
175
184
  aspect-ratio: 1;
176
185
  border-radius: 0;
177
186
  width: var(--input-min-height);
178
187
 
179
188
  &:hover {
180
- background-color: var(--theme-input-surface-hover);
189
+ background-color: var(--_input-text-surface-hover);
181
190
  }
182
191
 
183
192
  &:is(:focus-visible) {
184
- outline: var(--form-element-outline-width-focus) solid var(--theme-border-focus);
193
+ outline: var(--form-element-outline-width-focus) solid var(--_input-text-border-focus);
185
194
  outline-offset: -4px;
186
195
  }
187
196
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "9.3.1",
4
+ "version": "9.3.2",
5
5
  "main": "nuxt.config.ts",
6
6
  "types": "types.d.ts",
7
7
  "license": "MIT",