@keenmate/web-components-devkit 1.0.0-rc02 → 1.0.0-rc04

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.
@@ -32,8 +32,10 @@
32
32
  position: absolute;
33
33
  top: 0.5rem;
34
34
  right: 0.5rem;
35
+ min-height: 0; /* not the control height (button rule) */
35
36
  padding: 0.25rem 0.75rem;
36
37
  font-size: 0.75rem;
38
+ line-height: normal;
37
39
  background: color-mix(in srgb, var(--kmwc-code-text-color) 10%, transparent);
38
40
  color: var(--kmwc-code-text-color);
39
41
  border: 1px solid color-mix(in srgb, var(--kmwc-code-text-color) 20%, transparent);
@@ -0,0 +1,285 @@
1
+ /* ==============================================================================
2
+ EXAMPLES KIT — FORM CONTROLS
3
+ ==============================================================================
4
+ One look for the native controls a demo page uses — text fields, selects
5
+ (single and multiple), textareas, checkboxes, radios, switches, ranges,
6
+ colour and file inputs — wherever the page puts them, not only in a
7
+ `.controls` row. Modelled on pure-admin's forms (fixed control height,
8
+ accent focus border + halo, the shared --base-icon-check tick) and read
9
+ through the --base-* contract, so a theme restyles them with the component.
10
+
11
+ Every selector is wrapped in :where() — zero specificity — so any page or
12
+ component rule wins. `.kmwc-native` on an element (or an ancestor) keeps
13
+ the browser's own controls, e.g. for a light-DOM component that draws its
14
+ own inputs. A switch is `<input type="checkbox" role="switch">`. */
15
+ @layer kmwc {
16
+ /* ==========================================================================
17
+ TEXT FIELDS & SELECT
18
+ ==========================================================================
19
+ A fixed height and no vertical padding: the browser centres the text. */
20
+ :where(
21
+ input:not([type]),
22
+ input[type="text"], input[type="search"], input[type="email"], input[type="url"],
23
+ input[type="tel"], input[type="password"], input[type="number"], input[type="date"],
24
+ input[type="time"], input[type="datetime-local"], input[type="month"], input[type="week"],
25
+ select, textarea
26
+ ):not(:where(.kmwc-native, .kmwc-native *)) {
27
+ box-sizing: border-box;
28
+ height: var(--kmwc-control-height);
29
+ padding: 0 0.625rem;
30
+ border: var(--kmwc-input-border);
31
+ border-radius: var(--kmwc-radius-sm);
32
+ background-color: var(--kmwc-input-bg);
33
+ color: var(--kmwc-input-color);
34
+ font: inherit;
35
+ font-size: 0.875rem;
36
+ transition: border-color 0.15s ease-out, box-shadow 0.15s ease-out;
37
+ }
38
+
39
+ :where(input, select, textarea):not(:where(.kmwc-native, .kmwc-native *))::placeholder {
40
+ color: var(--kmwc-input-placeholder-color);
41
+ opacity: 1;
42
+ }
43
+
44
+ :where(
45
+ input:not([type]),
46
+ input[type="text"], input[type="search"], input[type="email"], input[type="url"],
47
+ input[type="tel"], input[type="password"], input[type="number"], input[type="date"],
48
+ input[type="time"], input[type="datetime-local"], input[type="month"], input[type="week"],
49
+ select, textarea
50
+ ):not(:where(.kmwc-native, .kmwc-native *)):hover {
51
+ border: var(--kmwc-input-border-hover);
52
+ }
53
+
54
+ :where(
55
+ input:not([type]),
56
+ input[type="text"], input[type="search"], input[type="email"], input[type="url"],
57
+ input[type="tel"], input[type="password"], input[type="number"], input[type="date"],
58
+ input[type="time"], input[type="datetime-local"], input[type="month"], input[type="week"],
59
+ select, textarea
60
+ ):not(:where(.kmwc-native, .kmwc-native *)):focus {
61
+ outline: none;
62
+ border: var(--kmwc-input-border-focus);
63
+ box-shadow: var(--kmwc-input-box-shadow-focus);
64
+ }
65
+
66
+ /* A field the user has left invalid (not one that starts empty). */
67
+ :where(input, select, textarea):not(:where(.kmwc-native, .kmwc-native *)):user-invalid {
68
+ border-color: var(--kmwc-danger-fill-color);
69
+ }
70
+
71
+ :where(input, select, textarea):not(:where(.kmwc-native, .kmwc-native *)):disabled {
72
+ background-color: var(--kmwc-input-disabled-bg);
73
+ opacity: var(--kmwc-disabled-opacity);
74
+ cursor: not-allowed;
75
+ }
76
+
77
+ :where(input[type="number"]):not(:where(.kmwc-native, .kmwc-native *)) {
78
+ padding-inline-end: 0.25rem; /* room for the spin buttons */
79
+ }
80
+
81
+ /* Single select: the kit's caret (drawn from the input icon colour, so it
82
+ follows the theme) instead of the platform's. */
83
+ :where(select:not([multiple], [size])):not(:where(.kmwc-native, .kmwc-native *)) {
84
+ appearance: none;
85
+ padding-inline-end: 2rem;
86
+ background-image:
87
+ linear-gradient(45deg, transparent 50%, var(--kmwc-input-icon-color) 50%),
88
+ linear-gradient(135deg, var(--kmwc-input-icon-color) 50%, transparent 50%);
89
+ background-position:
90
+ right 0.95rem center,
91
+ right 0.65rem center;
92
+ background-size: 0.3rem 0.3rem;
93
+ background-repeat: no-repeat;
94
+ cursor: pointer;
95
+ }
96
+
97
+ /* Multiple select / list box: grows with its rows; options are rows. */
98
+ :where(select[multiple], select[size]):not(:where(.kmwc-native, .kmwc-native *)) {
99
+ height: auto;
100
+ padding: 0.25rem;
101
+ }
102
+
103
+ :where(select[multiple], select[size]):not(:where(.kmwc-native, .kmwc-native *)) option {
104
+ padding: 0.25rem 0.5rem;
105
+ border-radius: var(--kmwc-radius-sm);
106
+ }
107
+
108
+ :where(select[multiple], select[size]):not(:where(.kmwc-native, .kmwc-native *)) option:checked {
109
+ background: var(--kmwc-accent-light-bg-hover);
110
+ color: var(--kmwc-text-color-1);
111
+ }
112
+
113
+ :where(textarea):not(:where(.kmwc-native, .kmwc-native *)) {
114
+ height: auto;
115
+ min-height: 5rem;
116
+ padding: 0.5rem 0.625rem;
117
+ line-height: 1.5;
118
+ resize: vertical;
119
+ }
120
+
121
+ /* Inside a form group a field takes the row (pure-admin .pa-input). */
122
+ :where(.form-group) :where(
123
+ input:not([type]),
124
+ input[type="text"], input[type="search"], input[type="email"], input[type="url"],
125
+ input[type="tel"], input[type="password"], input[type="number"], input[type="date"],
126
+ input[type="time"], input[type="datetime-local"], input[type="month"], input[type="week"],
127
+ select, textarea
128
+ ) {
129
+ width: 100%;
130
+ }
131
+
132
+ /* ==========================================================================
133
+ CHECKBOX & RADIO
134
+ ==========================================================================
135
+ The native input, redrawn: the contract's checkbox render method — a
136
+ border-box square sized by --base-checkbox-scale, the tick / dash masked
137
+ from --base-icon-check / --base-icon-indeterminate (the glyph every
138
+ Keenmate component draws). Radios get a dot from the same tokens. */
139
+ :where(input[type="checkbox"], input[type="radio"]):not(:where(.kmwc-native, .kmwc-native *)) {
140
+ appearance: none;
141
+ box-sizing: border-box;
142
+ position: relative;
143
+ flex-shrink: 0;
144
+ display: inline-block;
145
+ width: var(--kmwc-checkbox-size);
146
+ height: var(--kmwc-checkbox-size);
147
+ margin: 0;
148
+ vertical-align: -0.15em;
149
+ border: calc(1px * var(--base-checkbox-scale, 1)) solid var(--kmwc-checkbox-border-color);
150
+ border-radius: calc(4px * var(--base-checkbox-scale, 1));
151
+ background-color: var(--kmwc-input-bg);
152
+ cursor: pointer;
153
+ transition: background-color 0.15s ease, border-color 0.15s ease;
154
+ }
155
+
156
+ :where(input[type="radio"]):not(:where(.kmwc-native, .kmwc-native *)) {
157
+ border-radius: 50%;
158
+ }
159
+
160
+ :where(input[type="checkbox"], input[type="radio"]):not(:where(.kmwc-native, .kmwc-native *)):hover:not(:checked, :indeterminate, :disabled) {
161
+ border-color: var(--kmwc-accent-color);
162
+ }
163
+
164
+ :where(input[type="checkbox"], input[type="radio"]):not(:where(.kmwc-native, .kmwc-native *)):focus-visible {
165
+ outline: none;
166
+ border-color: var(--kmwc-accent-color);
167
+ box-shadow: 0 0 0 3px var(--kmwc-accent-light-bg-hover);
168
+ }
169
+
170
+ :where(input[type="checkbox"]):not(:where(.kmwc-native, .kmwc-native *)):is(:checked, :indeterminate) {
171
+ background-color: var(--kmwc-accent-color);
172
+ border-color: var(--kmwc-accent-color);
173
+ }
174
+
175
+ :where(input[type="checkbox"]):not(:where(.kmwc-native, .kmwc-native *, [role="switch"])):is(:checked, :indeterminate)::before {
176
+ content: '';
177
+ position: absolute;
178
+ inset: 0;
179
+ background-color: var(--kmwc-text-color-on-accent);
180
+ mask: var(--kmwc-icon-check) center / var(--kmwc-icon-check-size) no-repeat;
181
+ }
182
+
183
+ :where(input[type="checkbox"]):not(:where(.kmwc-native, .kmwc-native *, [role="switch"])):indeterminate::before {
184
+ mask-image: var(--kmwc-icon-indeterminate);
185
+ }
186
+
187
+ :where(input[type="radio"]):not(:where(.kmwc-native, .kmwc-native *)):checked {
188
+ border-color: var(--kmwc-accent-color);
189
+ background: radial-gradient(circle, var(--kmwc-text-color-on-accent) 0 30%, var(--kmwc-accent-color) 34%);
190
+ }
191
+
192
+ :where(input[type="checkbox"], input[type="radio"]):not(:where(.kmwc-native, .kmwc-native *)):disabled {
193
+ opacity: var(--kmwc-disabled-opacity);
194
+ cursor: not-allowed;
195
+ }
196
+
197
+ /* The option's label fades with it. */
198
+ :where(label):has(> :is(input, select, textarea):disabled) {
199
+ color: var(--kmwc-text-color-3);
200
+ cursor: not-allowed;
201
+ }
202
+
203
+ /* ==========================================================================
204
+ SWITCH — <input type="checkbox" role="switch">
205
+ ========================================================================== */
206
+ :where(input[type="checkbox"][role="switch"]):not(:where(.kmwc-native, .kmwc-native *)) {
207
+ width: calc(var(--kmwc-checkbox-size) * 1.9);
208
+ border-radius: 999px;
209
+ background-color: var(--kmwc-checkbox-border-color);
210
+ border-color: var(--kmwc-checkbox-border-color);
211
+ }
212
+
213
+ :where(input[type="checkbox"][role="switch"]):not(:where(.kmwc-native, .kmwc-native *))::before {
214
+ content: '';
215
+ position: absolute;
216
+ top: 1px;
217
+ left: 1px;
218
+ width: calc(var(--kmwc-checkbox-size) - 4px);
219
+ height: calc(var(--kmwc-checkbox-size) - 4px);
220
+ border-radius: 50%;
221
+ background-color: var(--kmwc-main-bg);
222
+ transition: translate 0.15s ease;
223
+ }
224
+
225
+ :where(input[type="checkbox"][role="switch"]):not(:where(.kmwc-native, .kmwc-native *)):checked::before {
226
+ translate: calc(var(--kmwc-checkbox-size) * 0.9) 0;
227
+ }
228
+
229
+ /* ==========================================================================
230
+ RANGE, COLOUR, FILE
231
+ ========================================================================== */
232
+ :where(input[type="range"], progress, meter):not(:where(.kmwc-native, .kmwc-native *)) {
233
+ accent-color: var(--kmwc-accent-color);
234
+ vertical-align: middle;
235
+ }
236
+
237
+ :where(input[type="color"]):not(:where(.kmwc-native, .kmwc-native *)) {
238
+ box-sizing: border-box;
239
+ width: var(--kmwc-control-height);
240
+ height: var(--kmwc-control-height);
241
+ padding: 0.2rem;
242
+ border: var(--kmwc-input-border);
243
+ border-radius: var(--kmwc-radius-sm);
244
+ background-color: var(--kmwc-input-bg);
245
+ cursor: pointer;
246
+ }
247
+
248
+ :where(input[type="file"]):not(:where(.kmwc-native, .kmwc-native *)) {
249
+ font: inherit;
250
+ font-size: 0.875rem;
251
+ color: var(--kmwc-text-color-2);
252
+ }
253
+
254
+ :where(input[type="file"]):not(:where(.kmwc-native, .kmwc-native *))::file-selector-button {
255
+ height: var(--kmwc-control-height);
256
+ margin-inline-end: 0.75rem;
257
+ padding: 0 1rem;
258
+ border: 1px solid var(--kmwc-border-color-strong);
259
+ border-radius: var(--kmwc-radius-sm);
260
+ background: var(--kmwc-main-bg);
261
+ color: var(--kmwc-text-color-1);
262
+ font: inherit;
263
+ cursor: pointer;
264
+ }
265
+
266
+ :where(input[type="file"]):not(:where(.kmwc-native, .kmwc-native *))::file-selector-button:hover {
267
+ background: var(--kmwc-hover-bg);
268
+ }
269
+
270
+ /* ==========================================================================
271
+ FIELDSET
272
+ ========================================================================== */
273
+ :where(fieldset):not(:where(.kmwc-native, .kmwc-native *)) {
274
+ border: 1px solid var(--kmwc-border-color);
275
+ border-radius: var(--kmwc-radius-md);
276
+ padding: 0.75rem 1rem 1rem;
277
+ }
278
+
279
+ :where(legend):not(:where(.kmwc-native, .kmwc-native *)) {
280
+ padding: 0 0.375rem;
281
+ font-weight: 600;
282
+ font-size: 0.875rem;
283
+ color: var(--kmwc-text-color-2);
284
+ }
285
+ }