innoboxrr-form-core 1.0.0 → 2.0.0
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.
- package/package.json +10 -2
- package/src/components.css +543 -0
- package/src/layout.css +250 -0
- package/src/theme.js +62 -43
- package/src/tokens.css +187 -0
- package/styles.css +16 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "innoboxrr-form-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "El nucleo agnostico de los formularios innoboxrr: tema, archivos y zonas horarias.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -9,13 +9,21 @@
|
|
|
9
9
|
"./theme": "./src/theme.js",
|
|
10
10
|
"./files": "./src/files.js",
|
|
11
11
|
"./timezone": "./src/timezone.js",
|
|
12
|
+
"./styles": "./styles.css",
|
|
13
|
+
"./styles.css": "./styles.css",
|
|
14
|
+
"./tokens.css": "./src/tokens.css",
|
|
15
|
+
"./components.css": "./src/components.css",
|
|
16
|
+
"./layout.css": "./src/layout.css",
|
|
12
17
|
"./src/*": "./src/*"
|
|
13
18
|
},
|
|
14
19
|
"files": [
|
|
15
20
|
"index.js",
|
|
21
|
+
"styles.css",
|
|
16
22
|
"src"
|
|
17
23
|
],
|
|
18
|
-
"sideEffects":
|
|
24
|
+
"sideEffects": [
|
|
25
|
+
"*.css"
|
|
26
|
+
],
|
|
19
27
|
"scripts": {
|
|
20
28
|
"test": "vitest run",
|
|
21
29
|
"test:watch": "vitest"
|
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Las clases del sistema de diseño innoboxrr, construidas sobre las
|
|
3
|
+
* primitivas de tokens.css.
|
|
4
|
+
*
|
|
5
|
+
* Sustituyen a lo que antes venía de fuera sin declararse: 305 clases de
|
|
6
|
+
* UIkit y 551 de Tailwind repartidas por los paquetes, ninguna de las dos
|
|
7
|
+
* declarada como dependencia. Un módulo generado solo se montaba dentro de
|
|
8
|
+
* una aplicación que ya trajera UIkit cargado, y nada lo decía.
|
|
9
|
+
*
|
|
10
|
+
* Todo lo de aquí depende únicamente de las variables de tokens.css, así que
|
|
11
|
+
* el paquete ya no exige ningún framework de CSS y el aspecto de todo el
|
|
12
|
+
* ecosistema se cambia en un sitio.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/* ============================================================
|
|
16
|
+
CAMPOS
|
|
17
|
+
============================================================ */
|
|
18
|
+
|
|
19
|
+
.fe-field {
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
gap: var(--fe-space-1);
|
|
23
|
+
margin-bottom: var(--fe-space-4);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.fe-field-inner {
|
|
27
|
+
position: relative;
|
|
28
|
+
width: 100%;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.fe-label {
|
|
32
|
+
display: inline-flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
gap: var(--fe-space-1);
|
|
35
|
+
font-size: var(--fe-text-sm);
|
|
36
|
+
font-weight: 500;
|
|
37
|
+
color: var(--fe-text);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.fe-help {
|
|
41
|
+
cursor: help;
|
|
42
|
+
color: var(--fe-text-subtle);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Dibujado, no una fuente de iconos. El token `helpIcon` valía
|
|
46
|
+
`fa-solid fa-circle-question`, así que el paquete exigía Font Awesome sin
|
|
47
|
+
declararlo: si la aplicación no lo cargaba, el icono no aparecía y nadie
|
|
48
|
+
se enteraba. */
|
|
49
|
+
.fe-help-icon {
|
|
50
|
+
display: inline-flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
justify-content: center;
|
|
53
|
+
width: 1rem;
|
|
54
|
+
height: 1rem;
|
|
55
|
+
font-size: 0.6875rem;
|
|
56
|
+
font-weight: 600;
|
|
57
|
+
line-height: 1;
|
|
58
|
+
color: var(--fe-text-inverse);
|
|
59
|
+
background: var(--fe-text-subtle);
|
|
60
|
+
border-radius: var(--fe-radius-full);
|
|
61
|
+
cursor: help;
|
|
62
|
+
user-select: none;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.fe-help-icon::before {
|
|
66
|
+
content: '?';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.fe-error {
|
|
70
|
+
font-size: var(--fe-text-xs);
|
|
71
|
+
font-weight: 500;
|
|
72
|
+
color: var(--fe-danger);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* ============================================================
|
|
76
|
+
CONTROLES
|
|
77
|
+
============================================================ */
|
|
78
|
+
|
|
79
|
+
.fe-input,
|
|
80
|
+
.fe-select,
|
|
81
|
+
.fe-textarea,
|
|
82
|
+
.fe-file {
|
|
83
|
+
width: 100%;
|
|
84
|
+
min-height: var(--fe-control-height);
|
|
85
|
+
padding: 0 var(--fe-control-padding-x);
|
|
86
|
+
font-family: var(--fe-font);
|
|
87
|
+
font-size: var(--fe-text-base);
|
|
88
|
+
color: var(--fe-text);
|
|
89
|
+
background: var(--fe-surface);
|
|
90
|
+
border: 1px solid var(--fe-border);
|
|
91
|
+
border-radius: var(--fe-radius);
|
|
92
|
+
transition: border-color var(--fe-transition), box-shadow var(--fe-transition);
|
|
93
|
+
appearance: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.fe-textarea {
|
|
97
|
+
padding: var(--fe-space-2) var(--fe-control-padding-x);
|
|
98
|
+
min-height: calc(var(--fe-control-height) * 3);
|
|
99
|
+
line-height: 1.5;
|
|
100
|
+
resize: vertical;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.fe-select {
|
|
104
|
+
/* La flecha va en el CSS y no en un icono suelto: así el control no
|
|
105
|
+
depende de que la aplicación haya cargado una fuente de iconos. */
|
|
106
|
+
padding-right: calc(var(--fe-control-padding-x) * 2.5);
|
|
107
|
+
background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
|
|
108
|
+
linear-gradient(135deg, currentColor 50%, transparent 50%);
|
|
109
|
+
background-position: right var(--fe-control-padding-x) center,
|
|
110
|
+
calc(100% - var(--fe-control-padding-x) + 5px) center;
|
|
111
|
+
background-size: 5px 5px, 5px 5px;
|
|
112
|
+
background-repeat: no-repeat;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.fe-input::placeholder,
|
|
116
|
+
.fe-textarea::placeholder {
|
|
117
|
+
color: var(--fe-text-subtle);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.fe-input:hover,
|
|
121
|
+
.fe-select:hover,
|
|
122
|
+
.fe-textarea:hover {
|
|
123
|
+
border-color: var(--fe-border-strong);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.fe-input:focus,
|
|
127
|
+
.fe-select:focus,
|
|
128
|
+
.fe-textarea:focus,
|
|
129
|
+
.fe-file:focus {
|
|
130
|
+
outline: none;
|
|
131
|
+
border-color: var(--fe-focus);
|
|
132
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--fe-focus) 22%, transparent);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.fe-input:disabled,
|
|
136
|
+
.fe-select:disabled,
|
|
137
|
+
.fe-textarea:disabled {
|
|
138
|
+
background: var(--fe-surface-sunk);
|
|
139
|
+
color: var(--fe-text-subtle);
|
|
140
|
+
cursor: not-allowed;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* El componente de validación marca el campo inválido con esta clase. */
|
|
144
|
+
.fe-input-error,
|
|
145
|
+
.fe-input[aria-invalid='true'],
|
|
146
|
+
.fe-select[aria-invalid='true'],
|
|
147
|
+
.fe-textarea[aria-invalid='true'] {
|
|
148
|
+
border-color: var(--fe-danger);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.fe-checkbox,
|
|
152
|
+
.fe-radio {
|
|
153
|
+
width: 1rem;
|
|
154
|
+
height: 1rem;
|
|
155
|
+
accent-color: var(--fe-primary);
|
|
156
|
+
border: 1px solid var(--fe-border-strong);
|
|
157
|
+
cursor: pointer;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.fe-radio {
|
|
161
|
+
border-radius: var(--fe-radius-full);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.fe-checkbox {
|
|
165
|
+
border-radius: var(--fe-radius-sm);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.fe-checkbox:focus-visible,
|
|
169
|
+
.fe-radio:focus-visible {
|
|
170
|
+
outline: 2px solid var(--fe-focus);
|
|
171
|
+
outline-offset: 2px;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* ============================================================
|
|
175
|
+
BOTONES
|
|
176
|
+
============================================================ */
|
|
177
|
+
|
|
178
|
+
.fe-button,
|
|
179
|
+
.fe-button-secondary,
|
|
180
|
+
.fe-button-danger,
|
|
181
|
+
.fe-button-link {
|
|
182
|
+
display: inline-flex;
|
|
183
|
+
align-items: center;
|
|
184
|
+
justify-content: center;
|
|
185
|
+
gap: var(--fe-space-2);
|
|
186
|
+
min-height: var(--fe-control-height);
|
|
187
|
+
padding: 0 calc(var(--fe-control-padding-x) * 1.25);
|
|
188
|
+
font-family: var(--fe-font);
|
|
189
|
+
font-size: var(--fe-text-base);
|
|
190
|
+
font-weight: 500;
|
|
191
|
+
line-height: 1;
|
|
192
|
+
border: 1px solid transparent;
|
|
193
|
+
border-radius: var(--fe-radius);
|
|
194
|
+
cursor: pointer;
|
|
195
|
+
transition: background var(--fe-transition), border-color var(--fe-transition), color var(--fe-transition);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.fe-button {
|
|
199
|
+
color: var(--fe-primary-text);
|
|
200
|
+
background: var(--fe-primary);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.fe-button:hover:not(:disabled) {
|
|
204
|
+
background: var(--fe-primary-hover);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.fe-button-secondary {
|
|
208
|
+
color: var(--fe-text);
|
|
209
|
+
background: var(--fe-surface);
|
|
210
|
+
border-color: var(--fe-border);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.fe-button-secondary:hover:not(:disabled) {
|
|
214
|
+
background: var(--fe-surface-hover);
|
|
215
|
+
border-color: var(--fe-border-strong);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.fe-button-danger {
|
|
219
|
+
color: var(--fe-danger-text);
|
|
220
|
+
background: var(--fe-danger);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.fe-button-danger:hover:not(:disabled) {
|
|
224
|
+
background: var(--fe-danger-hover);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.fe-button-link {
|
|
228
|
+
min-height: 0;
|
|
229
|
+
padding: 0;
|
|
230
|
+
color: var(--fe-primary);
|
|
231
|
+
background: none;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.fe-button-sm {
|
|
235
|
+
min-height: calc(1.75rem * var(--fe-density));
|
|
236
|
+
padding: 0 var(--fe-space-2);
|
|
237
|
+
font-size: var(--fe-text-sm);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* El icono que va dentro del control, a la izquierda. Sustituye a
|
|
241
|
+
`uk-form-icon`, que además de la clase traía el componente de iconos de
|
|
242
|
+
UIkit. */
|
|
243
|
+
.fe-field-icon {
|
|
244
|
+
position: absolute;
|
|
245
|
+
top: 50%;
|
|
246
|
+
left: var(--fe-space-3);
|
|
247
|
+
transform: translateY(-50%);
|
|
248
|
+
display: inline-flex;
|
|
249
|
+
align-items: center;
|
|
250
|
+
color: var(--fe-text-subtle);
|
|
251
|
+
pointer-events: none;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.fe-field-icon ~ .fe-input,
|
|
255
|
+
.fe-field-icon ~ * .fe-input {
|
|
256
|
+
padding-left: calc(var(--fe-control-padding-x) * 2.5);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.fe-button-link:hover:not(:disabled) {
|
|
260
|
+
text-decoration: underline;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.fe-button:focus-visible,
|
|
264
|
+
.fe-button-secondary:focus-visible,
|
|
265
|
+
.fe-button-danger:focus-visible,
|
|
266
|
+
.fe-button-link:focus-visible {
|
|
267
|
+
outline: 2px solid var(--fe-focus);
|
|
268
|
+
outline-offset: 2px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.fe-button:disabled,
|
|
272
|
+
.fe-button-secondary:disabled,
|
|
273
|
+
.fe-button-danger:disabled,
|
|
274
|
+
.fe-button-link:disabled {
|
|
275
|
+
opacity: 0.55;
|
|
276
|
+
cursor: not-allowed;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/* ============================================================
|
|
280
|
+
NAVEGACION Y ACCIONES
|
|
281
|
+
============================================================ */
|
|
282
|
+
|
|
283
|
+
.fe-breadcrumb {
|
|
284
|
+
display: flex;
|
|
285
|
+
align-items: center;
|
|
286
|
+
flex-wrap: wrap;
|
|
287
|
+
gap: var(--fe-space-2);
|
|
288
|
+
margin-bottom: var(--fe-space-4);
|
|
289
|
+
font-size: var(--fe-text-sm);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.fe-breadcrumb-link {
|
|
293
|
+
color: var(--fe-text-muted);
|
|
294
|
+
text-decoration: none;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.fe-breadcrumb-link:hover {
|
|
298
|
+
color: var(--fe-text);
|
|
299
|
+
text-decoration: underline;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.fe-breadcrumb-current {
|
|
303
|
+
font-weight: 500;
|
|
304
|
+
color: var(--fe-text);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.fe-breadcrumb-separator {
|
|
308
|
+
color: var(--fe-text-subtle);
|
|
309
|
+
user-select: none;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.fe-action-menu {
|
|
313
|
+
display: inline-flex;
|
|
314
|
+
align-items: center;
|
|
315
|
+
gap: var(--fe-space-3);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.fe-action-item {
|
|
319
|
+
font-size: var(--fe-text-sm);
|
|
320
|
+
color: var(--fe-primary);
|
|
321
|
+
background: none;
|
|
322
|
+
border: none;
|
|
323
|
+
padding: 0;
|
|
324
|
+
cursor: pointer;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.fe-action-item:hover {
|
|
328
|
+
text-decoration: underline;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.fe-action-danger {
|
|
332
|
+
font-size: var(--fe-text-sm);
|
|
333
|
+
color: var(--fe-danger);
|
|
334
|
+
background: none;
|
|
335
|
+
border: none;
|
|
336
|
+
padding: 0;
|
|
337
|
+
cursor: pointer;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.fe-action-danger:hover {
|
|
341
|
+
text-decoration: underline;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* ============================================================
|
|
345
|
+
SUPERFICIES
|
|
346
|
+
============================================================ */
|
|
347
|
+
|
|
348
|
+
.fe-surface {
|
|
349
|
+
background: var(--fe-surface);
|
|
350
|
+
border: 1px solid var(--fe-border);
|
|
351
|
+
border-radius: var(--fe-radius-lg);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.fe-surface-raised {
|
|
355
|
+
background: var(--fe-surface-raised);
|
|
356
|
+
border: 1px solid var(--fe-border);
|
|
357
|
+
border-radius: var(--fe-radius-lg);
|
|
358
|
+
box-shadow: var(--fe-shadow);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/* ============================================================
|
|
362
|
+
PIEZAS DE APLICACION
|
|
363
|
+
============================================================ */
|
|
364
|
+
|
|
365
|
+
.fe-toolbar {
|
|
366
|
+
display: flex;
|
|
367
|
+
align-items: center;
|
|
368
|
+
gap: var(--fe-space-3);
|
|
369
|
+
padding: var(--fe-space-3) var(--fe-space-4);
|
|
370
|
+
border-bottom: 1px solid var(--fe-border);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.fe-badge {
|
|
374
|
+
display: inline-flex;
|
|
375
|
+
align-items: center;
|
|
376
|
+
padding: 0 var(--fe-space-2);
|
|
377
|
+
height: 1.375rem;
|
|
378
|
+
font-size: var(--fe-text-xs);
|
|
379
|
+
font-weight: 500;
|
|
380
|
+
border-radius: var(--fe-radius-full);
|
|
381
|
+
background: var(--fe-surface-sunk);
|
|
382
|
+
color: var(--fe-text-muted);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* Un esqueleto en vez de un spinner: mantiene la forma de lo que va a
|
|
386
|
+
llegar, así que la página no salta al cargar. */
|
|
387
|
+
.fe-skeleton {
|
|
388
|
+
background: linear-gradient(
|
|
389
|
+
90deg,
|
|
390
|
+
var(--fe-surface-sunk) 25%,
|
|
391
|
+
var(--fe-surface-hover) 37%,
|
|
392
|
+
var(--fe-surface-sunk) 63%
|
|
393
|
+
);
|
|
394
|
+
background-size: 400% 100%;
|
|
395
|
+
border-radius: var(--fe-radius-sm);
|
|
396
|
+
animation: fe-skeleton 1.4s ease infinite;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
@keyframes fe-skeleton {
|
|
400
|
+
0% {
|
|
401
|
+
background-position: 100% 50%;
|
|
402
|
+
}
|
|
403
|
+
100% {
|
|
404
|
+
background-position: 0 50%;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.fe-overlay {
|
|
409
|
+
position: fixed;
|
|
410
|
+
inset: 0;
|
|
411
|
+
background: rgba(16, 18, 27, 0.45);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.fe-dialog {
|
|
415
|
+
background: var(--fe-surface-raised);
|
|
416
|
+
border: 1px solid var(--fe-border);
|
|
417
|
+
border-radius: var(--fe-radius-lg);
|
|
418
|
+
box-shadow: var(--fe-shadow-lg);
|
|
419
|
+
max-height: 85vh;
|
|
420
|
+
overflow: auto;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.fe-drawer {
|
|
424
|
+
position: fixed;
|
|
425
|
+
top: 0;
|
|
426
|
+
right: 0;
|
|
427
|
+
bottom: 0;
|
|
428
|
+
width: min(32rem, 100vw);
|
|
429
|
+
background: var(--fe-surface);
|
|
430
|
+
border-left: 1px solid var(--fe-border);
|
|
431
|
+
box-shadow: var(--fe-shadow-lg);
|
|
432
|
+
display: flex;
|
|
433
|
+
flex-direction: column;
|
|
434
|
+
overflow: auto;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.fe-menu {
|
|
438
|
+
min-width: 11rem;
|
|
439
|
+
padding: var(--fe-space-1);
|
|
440
|
+
background: var(--fe-surface-raised);
|
|
441
|
+
border: 1px solid var(--fe-border);
|
|
442
|
+
border-radius: var(--fe-radius);
|
|
443
|
+
box-shadow: var(--fe-shadow);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.fe-menu-item {
|
|
447
|
+
display: flex;
|
|
448
|
+
align-items: center;
|
|
449
|
+
gap: var(--fe-space-2);
|
|
450
|
+
width: 100%;
|
|
451
|
+
padding: var(--fe-space-2) var(--fe-space-3);
|
|
452
|
+
font-size: var(--fe-text-sm);
|
|
453
|
+
color: var(--fe-text);
|
|
454
|
+
text-align: left;
|
|
455
|
+
background: none;
|
|
456
|
+
border: none;
|
|
457
|
+
border-radius: var(--fe-radius-sm);
|
|
458
|
+
cursor: pointer;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
.fe-menu-item:hover,
|
|
462
|
+
.fe-menu-item[data-highlighted] {
|
|
463
|
+
background: var(--fe-surface-hover);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.fe-toast {
|
|
467
|
+
display: flex;
|
|
468
|
+
align-items: flex-start;
|
|
469
|
+
gap: var(--fe-space-3);
|
|
470
|
+
padding: var(--fe-space-3) var(--fe-space-4);
|
|
471
|
+
font-size: var(--fe-text-sm);
|
|
472
|
+
background: var(--fe-surface-raised);
|
|
473
|
+
border: 1px solid var(--fe-border);
|
|
474
|
+
border-left: 3px solid var(--fe-primary);
|
|
475
|
+
border-radius: var(--fe-radius);
|
|
476
|
+
box-shadow: var(--fe-shadow);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.fe-toast-danger {
|
|
480
|
+
border-left-color: var(--fe-danger);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
.fe-toast-success {
|
|
484
|
+
border-left-color: var(--fe-success);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/* ============================================================
|
|
488
|
+
TABLA
|
|
489
|
+
============================================================ */
|
|
490
|
+
|
|
491
|
+
.fe-table {
|
|
492
|
+
width: 100%;
|
|
493
|
+
border-collapse: collapse;
|
|
494
|
+
font-size: var(--fe-text-base);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.fe-table th {
|
|
498
|
+
padding: var(--fe-space-2) var(--fe-space-3);
|
|
499
|
+
font-size: var(--fe-text-xs);
|
|
500
|
+
font-weight: 500;
|
|
501
|
+
text-transform: uppercase;
|
|
502
|
+
letter-spacing: 0.05em;
|
|
503
|
+
color: var(--fe-text-subtle);
|
|
504
|
+
text-align: left;
|
|
505
|
+
white-space: nowrap;
|
|
506
|
+
border-bottom: 1px solid var(--fe-border);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.fe-table td {
|
|
510
|
+
padding: var(--fe-space-3);
|
|
511
|
+
color: var(--fe-text);
|
|
512
|
+
border-bottom: 1px solid var(--fe-border);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.fe-table tbody tr:hover {
|
|
516
|
+
background: var(--fe-surface-hover);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.fe-table tbody tr[data-selected='true'] {
|
|
520
|
+
background: var(--fe-primary-soft);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/* Las columnas de números se leen mucho peor si los dígitos no se alinean. */
|
|
524
|
+
.fe-table .fe-numeric {
|
|
525
|
+
font-variant-numeric: tabular-nums;
|
|
526
|
+
text-align: right;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
@media (prefers-reduced-motion: reduce) {
|
|
530
|
+
.fe-skeleton {
|
|
531
|
+
animation: none;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
.fe-input,
|
|
535
|
+
.fe-select,
|
|
536
|
+
.fe-textarea,
|
|
537
|
+
.fe-button,
|
|
538
|
+
.fe-button-secondary,
|
|
539
|
+
.fe-button-danger,
|
|
540
|
+
.fe-button-link {
|
|
541
|
+
transition: none;
|
|
542
|
+
}
|
|
543
|
+
}
|
package/src/layout.css
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Las utilidades de maquetación que los componentes tomaban prestadas de
|
|
3
|
+
* UIkit.
|
|
4
|
+
*
|
|
5
|
+
* Eran 280 usos de 68 clases distintas —`uk-margin`, `uk-grid`, `uk-flex`,
|
|
6
|
+
* `uk-width-expand`…— repartidos por form-elements, react-form-elements y los
|
|
7
|
+
* dos datatables, y **UIkit no estaba declarado como dependencia en ninguno**.
|
|
8
|
+
* Se consumía como CSS global del anfitrión: el paquete solo se veía bien
|
|
9
|
+
* dentro de una aplicación que ya lo trajera.
|
|
10
|
+
*
|
|
11
|
+
* Esto es deliberadamente pequeño. No es un framework de utilidades: es
|
|
12
|
+
* exactamente lo que los componentes usaban, y nada más. Si hace falta algo
|
|
13
|
+
* nuevo, se añade aquí y así queda a la vista lo que el ecosistema necesita
|
|
14
|
+
* de verdad.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/* ---------- ESPACIO ---------- */
|
|
18
|
+
|
|
19
|
+
.fe-mb { margin-bottom: var(--fe-space-4); }
|
|
20
|
+
.fe-mb-sm { margin-bottom: var(--fe-space-2); }
|
|
21
|
+
.fe-mt { margin-top: var(--fe-space-4); }
|
|
22
|
+
.fe-mt-sm { margin-top: var(--fe-space-2); }
|
|
23
|
+
.fe-mt-md { margin-top: var(--fe-space-5); }
|
|
24
|
+
.fe-mr-sm { margin-right: var(--fe-space-2); }
|
|
25
|
+
|
|
26
|
+
.fe-p-sm { padding: var(--fe-space-3); }
|
|
27
|
+
.fe-p-0 { padding: 0; }
|
|
28
|
+
.fe-pt-0 { padding-top: 0; }
|
|
29
|
+
|
|
30
|
+
/* ---------- CAJA ---------- */
|
|
31
|
+
|
|
32
|
+
.fe-inline {
|
|
33
|
+
position: relative;
|
|
34
|
+
display: inline-block;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.fe-inline-clip {
|
|
38
|
+
position: relative;
|
|
39
|
+
display: inline-block;
|
|
40
|
+
overflow: hidden;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.fe-relative { position: relative; }
|
|
44
|
+
|
|
45
|
+
.fe-center-abs {
|
|
46
|
+
position: absolute;
|
|
47
|
+
top: 50%;
|
|
48
|
+
left: 50%;
|
|
49
|
+
transform: translate(-50%, -50%);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* ---------- ANCHO ---------- */
|
|
53
|
+
|
|
54
|
+
.fe-w-full { width: 100%; }
|
|
55
|
+
.fe-w-auto { width: auto; }
|
|
56
|
+
.fe-w-expand { flex: 1 1 0; min-width: 0; }
|
|
57
|
+
|
|
58
|
+
@media (min-width: 960px) {
|
|
59
|
+
.fe-w-quarter { width: 25%; }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* ---------- FLEX Y REJILLA ---------- */
|
|
63
|
+
|
|
64
|
+
.fe-flex { display: flex; }
|
|
65
|
+
.fe-items-center { align-items: center; }
|
|
66
|
+
.fe-justify-start { justify-content: flex-start; }
|
|
67
|
+
.fe-justify-center { justify-content: center; }
|
|
68
|
+
.fe-justify-end { justify-content: flex-end; }
|
|
69
|
+
|
|
70
|
+
.fe-grid {
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-wrap: wrap;
|
|
73
|
+
gap: var(--fe-space-4);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.fe-grid-sm {
|
|
77
|
+
display: flex;
|
|
78
|
+
flex-wrap: wrap;
|
|
79
|
+
gap: var(--fe-space-2);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.fe-grid-divider > * + * {
|
|
83
|
+
border-left: 1px solid var(--fe-border);
|
|
84
|
+
padding-left: var(--fe-space-4);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.fe-children-expand > * { flex: 1 1 0; min-width: 0; }
|
|
88
|
+
|
|
89
|
+
/* ---------- TEXTO ---------- */
|
|
90
|
+
|
|
91
|
+
.fe-text-center { text-align: center; }
|
|
92
|
+
.fe-text-right { text-align: right; }
|
|
93
|
+
.fe-text-sm { font-size: var(--fe-text-sm); }
|
|
94
|
+
.fe-text-muted { font-size: var(--fe-text-sm); color: var(--fe-text-muted); }
|
|
95
|
+
.fe-text-success { color: var(--fe-success); }
|
|
96
|
+
|
|
97
|
+
/* ---------- CONTENEDOR ---------- */
|
|
98
|
+
|
|
99
|
+
.fe-container {
|
|
100
|
+
width: 100%;
|
|
101
|
+
max-width: 72rem;
|
|
102
|
+
margin: 0 auto;
|
|
103
|
+
padding: 0 var(--fe-space-4);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.fe-container-wide {
|
|
107
|
+
width: 100%;
|
|
108
|
+
margin: 0 auto;
|
|
109
|
+
padding: 0 var(--fe-space-4);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* ---------- TARJETA ---------- */
|
|
113
|
+
|
|
114
|
+
.fe-card {
|
|
115
|
+
background: var(--fe-surface);
|
|
116
|
+
border: 1px solid var(--fe-border);
|
|
117
|
+
border-radius: var(--fe-radius-lg);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.fe-card-body { padding: var(--fe-space-5); }
|
|
121
|
+
.fe-card-sm .fe-card-body { padding: var(--fe-space-3); }
|
|
122
|
+
|
|
123
|
+
/* ---------- MAQUETACION DE LAS VISTAS GENERADAS ---------- */
|
|
124
|
+
|
|
125
|
+
/*
|
|
126
|
+
* Estas tres no son utilidades sueltas: son la forma que tienen las vistas que
|
|
127
|
+
* genera larapack. Antes se componian con la rejilla fraccionaria de UIkit
|
|
128
|
+
* —`uk-width-1-3@m uk-width-1-1@s`— repetida en cada stub. Nombrar la
|
|
129
|
+
* intencion en vez de las fracciones deja que la maquetacion cambie en un
|
|
130
|
+
* sitio.
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
.fe-section {
|
|
134
|
+
padding: var(--fe-space-5) 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.fe-section-sm {
|
|
138
|
+
padding: var(--fe-space-3) 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* La vista de detalle: ficha a un lado, contenido al otro. */
|
|
142
|
+
.fe-split {
|
|
143
|
+
display: grid;
|
|
144
|
+
gap: var(--fe-space-4);
|
|
145
|
+
grid-template-columns: 1fr;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@media (min-width: 960px) {
|
|
149
|
+
.fe-split {
|
|
150
|
+
grid-template-columns: minmax(16rem, 1fr) 2fr;
|
|
151
|
+
align-items: start;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* Los filtros: tantas columnas como quepan, sin decidir un numero fijo. */
|
|
156
|
+
.fe-filter-grid {
|
|
157
|
+
display: grid;
|
|
158
|
+
gap: var(--fe-space-3);
|
|
159
|
+
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.fe-filter-actions {
|
|
163
|
+
display: flex;
|
|
164
|
+
flex-wrap: wrap;
|
|
165
|
+
justify-content: flex-end;
|
|
166
|
+
gap: var(--fe-space-2);
|
|
167
|
+
margin-top: var(--fe-space-3);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* ---------- LISTAS ---------- */
|
|
171
|
+
|
|
172
|
+
.fe-list {
|
|
173
|
+
list-style: none;
|
|
174
|
+
margin: 0;
|
|
175
|
+
padding: 0;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.fe-list > li + li { margin-top: var(--fe-space-2); }
|
|
179
|
+
|
|
180
|
+
/* ---------- PAGINACION ---------- */
|
|
181
|
+
|
|
182
|
+
.fe-pagination {
|
|
183
|
+
display: flex;
|
|
184
|
+
align-items: center;
|
|
185
|
+
gap: var(--fe-space-1);
|
|
186
|
+
list-style: none;
|
|
187
|
+
margin: 0;
|
|
188
|
+
padding: 0;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.fe-pagination a,
|
|
192
|
+
.fe-pagination button {
|
|
193
|
+
display: inline-flex;
|
|
194
|
+
align-items: center;
|
|
195
|
+
justify-content: center;
|
|
196
|
+
min-width: 2rem;
|
|
197
|
+
height: 2rem;
|
|
198
|
+
padding: 0 var(--fe-space-2);
|
|
199
|
+
font-size: var(--fe-text-sm);
|
|
200
|
+
color: var(--fe-text-muted);
|
|
201
|
+
background: none;
|
|
202
|
+
border: 1px solid transparent;
|
|
203
|
+
border-radius: var(--fe-radius-sm);
|
|
204
|
+
cursor: pointer;
|
|
205
|
+
text-decoration: none;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.fe-pagination a:hover,
|
|
209
|
+
.fe-pagination button:hover:not(:disabled) {
|
|
210
|
+
background: var(--fe-surface-hover);
|
|
211
|
+
color: var(--fe-text);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.fe-pagination .fe-active {
|
|
215
|
+
color: var(--fe-primary-text);
|
|
216
|
+
background: var(--fe-primary);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* Las flechas se dibujan, para no depender de la fuente de iconos de UIkit
|
|
220
|
+
(`uk-pagination-previous` es un `uk-icon`, es decir JS de UIkit). */
|
|
221
|
+
.fe-page-prev::before { content: '‹'; font-size: 1.125rem; line-height: 1; }
|
|
222
|
+
.fe-page-next::before { content: '›'; font-size: 1.125rem; line-height: 1; }
|
|
223
|
+
|
|
224
|
+
/* ---------- ESTADOS ---------- */
|
|
225
|
+
|
|
226
|
+
.fe-disabled,
|
|
227
|
+
.fe-disabled a {
|
|
228
|
+
opacity: 0.5;
|
|
229
|
+
pointer-events: none;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.fe-shrink { width: 1px; white-space: nowrap; }
|
|
233
|
+
|
|
234
|
+
/* ---------- APARICION ---------- */
|
|
235
|
+
|
|
236
|
+
.fe-fade-in { animation: fe-fade-in 160ms ease; }
|
|
237
|
+
|
|
238
|
+
@keyframes fe-fade-in {
|
|
239
|
+
from { opacity: 0; }
|
|
240
|
+
to { opacity: 1; }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.fe-reveal > .fe-reveal-target { opacity: 0; transition: opacity var(--fe-transition); }
|
|
244
|
+
.fe-reveal:hover > .fe-reveal-target,
|
|
245
|
+
.fe-reveal:focus-within > .fe-reveal-target { opacity: 1; }
|
|
246
|
+
|
|
247
|
+
@media (prefers-reduced-motion: reduce) {
|
|
248
|
+
.fe-fade-in { animation: none; }
|
|
249
|
+
.fe-reveal > .fe-reveal-target { transition: none; }
|
|
250
|
+
}
|
package/src/theme.js
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Antes cada componente llevaba su cadena incrustada como valor por defecto de
|
|
5
|
-
* `customClass`, repetida en los dos paquetes; y el codigo generado por
|
|
6
|
-
* larapack esperaba `inputClass` y `buttonClass` de un mixin global que la
|
|
7
|
-
* aplicacion anfitriona tenia que registrar sin que nada lo dijera.
|
|
8
|
-
*
|
|
9
|
-
* Ahora hay un tema: un mapa de tokens que la aplicacion ajusta una vez, al
|
|
10
|
-
* arrancar, y que leen los dos paquetes de componentes.
|
|
2
|
+
* El tema del ecosistema innoboxrr: un mapa de tokens que la aplicacion
|
|
3
|
+
* ajusta una vez, al arrancar, y que leen los dos paquetes de componentes.
|
|
11
4
|
*
|
|
12
5
|
* import { setTheme } from 'innoboxrr-form-core'
|
|
13
6
|
*
|
|
@@ -21,46 +14,72 @@
|
|
|
21
14
|
* @typedef {Record<string, string>} Theme
|
|
22
15
|
*/
|
|
23
16
|
|
|
24
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Los tokens apuntan a las clases del sistema de diseno propio, no a las de
|
|
19
|
+
* un framework ajeno.
|
|
20
|
+
*
|
|
21
|
+
* Antes cada valor era una cadena que mezclaba UIkit, Tailwind y Font Awesome
|
|
22
|
+
* —`uk-input uk-form-large uk-border-rounded`— y ninguno de esos frameworks
|
|
23
|
+
* estaba declarado como dependencia: el paquete solo funcionaba dentro de una
|
|
24
|
+
* aplicacion que ya los trajera cargados, y nada lo decia. Ademas el modo
|
|
25
|
+
* oscuro iba incrustado en cada cadena, repetido treinta veces.
|
|
26
|
+
*
|
|
27
|
+
* Ahora las clases son nuestras y su aspecto sale de las variables de
|
|
28
|
+
* `tokens.css`, donde el modo oscuro se define una sola vez. Cambiar el color
|
|
29
|
+
* principal del ecosistema vuelve a ser editar una linea.
|
|
30
|
+
*
|
|
31
|
+
* @type {Theme}
|
|
32
|
+
*/
|
|
25
33
|
export const defaultTheme = {
|
|
26
34
|
// ENVOLTORIOS
|
|
27
|
-
field: '
|
|
28
|
-
fieldInner: '
|
|
29
|
-
label: '
|
|
30
|
-
help: '
|
|
31
|
-
helpIcon: '
|
|
32
|
-
error: 'fe-
|
|
35
|
+
field: 'fe-field',
|
|
36
|
+
fieldInner: 'fe-field-inner',
|
|
37
|
+
label: 'fe-label',
|
|
38
|
+
help: 'fe-help',
|
|
39
|
+
helpIcon: 'fe-help-icon',
|
|
40
|
+
error: 'fe-error',
|
|
33
41
|
|
|
34
42
|
// CONTROLES
|
|
35
|
-
input: '
|
|
36
|
-
select: '
|
|
37
|
-
textarea: '
|
|
38
|
-
checkbox: '
|
|
39
|
-
radio: '
|
|
40
|
-
file: '
|
|
43
|
+
input: 'fe-input',
|
|
44
|
+
select: 'fe-select',
|
|
45
|
+
textarea: 'fe-textarea',
|
|
46
|
+
checkbox: 'fe-checkbox',
|
|
47
|
+
radio: 'fe-radio',
|
|
48
|
+
file: 'fe-file',
|
|
41
49
|
|
|
42
50
|
// BOTONES
|
|
43
|
-
button: '
|
|
44
|
-
buttonSecondary: '
|
|
45
|
-
buttonDanger: '
|
|
46
|
-
buttonLink: '
|
|
47
|
-
|
|
48
|
-
// NAVEGACION
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
button: 'fe-button',
|
|
52
|
+
buttonSecondary: 'fe-button-secondary',
|
|
53
|
+
buttonDanger: 'fe-button-danger',
|
|
54
|
+
buttonLink: 'fe-button-link',
|
|
55
|
+
|
|
56
|
+
// NAVEGACION Y ACCIONES
|
|
57
|
+
breadcrumb: 'fe-breadcrumb',
|
|
58
|
+
breadcrumbLink: 'fe-breadcrumb-link',
|
|
59
|
+
breadcrumbCurrent: 'fe-breadcrumb-current',
|
|
60
|
+
breadcrumbSeparator: 'fe-breadcrumb-separator',
|
|
61
|
+
actionMenu: 'fe-action-menu',
|
|
62
|
+
actionMenuItem: 'fe-action-item',
|
|
63
|
+
actionMenuDanger: 'fe-action-danger',
|
|
64
|
+
|
|
65
|
+
// SUPERFICIES Y PIEZAS DE APLICACION
|
|
66
|
+
surface: 'fe-surface',
|
|
67
|
+
surfaceRaised: 'fe-surface-raised',
|
|
68
|
+
toolbar: 'fe-toolbar',
|
|
69
|
+
badge: 'fe-badge',
|
|
70
|
+
skeleton: 'fe-skeleton',
|
|
71
|
+
overlay: 'fe-overlay',
|
|
72
|
+
dialog: 'fe-dialog',
|
|
73
|
+
drawer: 'fe-drawer',
|
|
74
|
+
menu: 'fe-menu',
|
|
75
|
+
menuItem: 'fe-menu-item',
|
|
76
|
+
toast: 'fe-toast',
|
|
77
|
+
toastDanger: 'fe-toast-danger',
|
|
78
|
+
toastSuccess: 'fe-toast-success',
|
|
79
|
+
|
|
80
|
+
// TABLA
|
|
81
|
+
table: 'fe-table',
|
|
82
|
+
tableNumeric: 'fe-numeric',
|
|
64
83
|
}
|
|
65
84
|
|
|
66
85
|
/** @type {Theme} */
|
package/src/tokens.css
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Las primitivas del sistema de diseño innoboxrr.
|
|
3
|
+
*
|
|
4
|
+
* Antes no había primitivas: el tema eran 23 cadenas de clases sueltas que
|
|
5
|
+
* mezclaban UIkit, Tailwind y Font Awesome, con el modo oscuro incrustado en
|
|
6
|
+
* cada una (`dark:text-white` repetido treinta veces). Cambiar el color
|
|
7
|
+
* principal del ecosistema no era una edición, era una búsqueda.
|
|
8
|
+
*
|
|
9
|
+
* Aquí cada decisión vive una vez. El modo oscuro redefine solo los colores,
|
|
10
|
+
* y en tres estados, porque el visitante tiene tres:
|
|
11
|
+
*
|
|
12
|
+
* - `:root` → el tema claro completo
|
|
13
|
+
* - `prefers-color-scheme: dark` → lo que ve quien no ha elegido nada
|
|
14
|
+
* - `[data-theme="dark"]` → la elección explícita, que manda sobre el SO
|
|
15
|
+
*
|
|
16
|
+
* La densidad es una variable, no un conjunto de clases: `--fe-density: 0.875`
|
|
17
|
+
* en un contenedor compacta todo lo que hay dentro sin tocar un componente.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
:root {
|
|
21
|
+
/* ---------- COLOR ---------- */
|
|
22
|
+
|
|
23
|
+
/* Neutros con sesgo frío: un gris puro se lee como falta de decisión. */
|
|
24
|
+
--fe-bg: #f7f8fa;
|
|
25
|
+
--fe-surface: #ffffff;
|
|
26
|
+
--fe-surface-raised: #ffffff;
|
|
27
|
+
--fe-surface-sunk: #f1f2f6;
|
|
28
|
+
--fe-surface-hover: #f1f2f6;
|
|
29
|
+
|
|
30
|
+
--fe-border: #e3e5eb;
|
|
31
|
+
--fe-border-strong: #c8cbd4;
|
|
32
|
+
|
|
33
|
+
--fe-text: #1b1c22;
|
|
34
|
+
--fe-text-muted: #5c5f6b;
|
|
35
|
+
--fe-text-subtle: #8b8e9a;
|
|
36
|
+
--fe-text-inverse: #ffffff;
|
|
37
|
+
|
|
38
|
+
--fe-primary: #4b5bd7;
|
|
39
|
+
--fe-primary-hover: #3f4dc0;
|
|
40
|
+
--fe-primary-text: #ffffff;
|
|
41
|
+
--fe-primary-soft: #eceefb;
|
|
42
|
+
|
|
43
|
+
--fe-danger: #c0392f;
|
|
44
|
+
--fe-danger-hover: #a32e26;
|
|
45
|
+
--fe-danger-text: #ffffff;
|
|
46
|
+
--fe-danger-soft: #fbeceb;
|
|
47
|
+
|
|
48
|
+
--fe-success: #17714d;
|
|
49
|
+
--fe-success-soft: #e6f2ec;
|
|
50
|
+
|
|
51
|
+
--fe-warning: #8a6212;
|
|
52
|
+
--fe-warning-soft: #f8f0dd;
|
|
53
|
+
|
|
54
|
+
--fe-focus: #4b5bd7;
|
|
55
|
+
|
|
56
|
+
/* ---------- FORMA ---------- */
|
|
57
|
+
|
|
58
|
+
--fe-radius-sm: 4px;
|
|
59
|
+
--fe-radius: 6px;
|
|
60
|
+
--fe-radius-lg: 10px;
|
|
61
|
+
--fe-radius-full: 9999px;
|
|
62
|
+
|
|
63
|
+
/* ---------- ESPACIO ---------- */
|
|
64
|
+
|
|
65
|
+
--fe-space-1: 0.25rem;
|
|
66
|
+
--fe-space-2: 0.5rem;
|
|
67
|
+
--fe-space-3: 0.75rem;
|
|
68
|
+
--fe-space-4: 1rem;
|
|
69
|
+
--fe-space-5: 1.5rem;
|
|
70
|
+
--fe-space-6: 2rem;
|
|
71
|
+
|
|
72
|
+
/* ---------- TIPOGRAFIA ---------- */
|
|
73
|
+
|
|
74
|
+
--fe-font: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
75
|
+
--fe-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
76
|
+
|
|
77
|
+
--fe-text-xs: 0.75rem;
|
|
78
|
+
--fe-text-sm: 0.8125rem;
|
|
79
|
+
--fe-text-base: 0.875rem;
|
|
80
|
+
--fe-text-lg: 1rem;
|
|
81
|
+
--fe-text-xl: 1.25rem;
|
|
82
|
+
|
|
83
|
+
/* ---------- ELEVACION ---------- */
|
|
84
|
+
|
|
85
|
+
--fe-shadow-sm: 0 1px 2px rgba(16, 18, 27, 0.06);
|
|
86
|
+
--fe-shadow: 0 4px 12px rgba(16, 18, 27, 0.08);
|
|
87
|
+
--fe-shadow-lg: 0 16px 40px rgba(16, 18, 27, 0.16);
|
|
88
|
+
|
|
89
|
+
/* ---------- DENSIDAD ---------- */
|
|
90
|
+
|
|
91
|
+
/* Multiplica alturas y padding de los controles. 1 es cómodo; 0.875
|
|
92
|
+
compacta una tabla sin que sus celdas dejen de ser pulsables. */
|
|
93
|
+
--fe-density: 1;
|
|
94
|
+
--fe-control-height: calc(2.25rem * var(--fe-density));
|
|
95
|
+
--fe-control-padding-x: calc(0.75rem * var(--fe-density));
|
|
96
|
+
|
|
97
|
+
/* ---------- MOVIMIENTO ---------- */
|
|
98
|
+
|
|
99
|
+
--fe-transition: 120ms ease;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* La elección explícita de claro gana sobre un sistema en oscuro, de ahí el
|
|
103
|
+
:not(). Sin él, un usuario que pide claro seguiría viendo oscuro. */
|
|
104
|
+
@media (prefers-color-scheme: dark) {
|
|
105
|
+
:root:not([data-theme='light']) {
|
|
106
|
+
--fe-bg: #101116;
|
|
107
|
+
--fe-surface: #181a21;
|
|
108
|
+
--fe-surface-raised: #1f222b;
|
|
109
|
+
--fe-surface-sunk: #14161c;
|
|
110
|
+
--fe-surface-hover: #22252f;
|
|
111
|
+
|
|
112
|
+
--fe-border: #2b2e39;
|
|
113
|
+
--fe-border-strong: #3d4150;
|
|
114
|
+
|
|
115
|
+
--fe-text: #e8e9ef;
|
|
116
|
+
--fe-text-muted: #a7aab8;
|
|
117
|
+
--fe-text-subtle: #767a89;
|
|
118
|
+
--fe-text-inverse: #101116;
|
|
119
|
+
|
|
120
|
+
--fe-primary: #8b95f0;
|
|
121
|
+
--fe-primary-hover: #a0a8f5;
|
|
122
|
+
--fe-primary-text: #101116;
|
|
123
|
+
--fe-primary-soft: #21243a;
|
|
124
|
+
|
|
125
|
+
--fe-danger: #e08b83;
|
|
126
|
+
--fe-danger-hover: #eda29a;
|
|
127
|
+
--fe-danger-text: #101116;
|
|
128
|
+
--fe-danger-soft: #2c1d1c;
|
|
129
|
+
|
|
130
|
+
--fe-success: #5ec79c;
|
|
131
|
+
--fe-success-soft: #142b23;
|
|
132
|
+
|
|
133
|
+
--fe-warning: #d9ac53;
|
|
134
|
+
--fe-warning-soft: #2a2417;
|
|
135
|
+
|
|
136
|
+
--fe-focus: #8b95f0;
|
|
137
|
+
|
|
138
|
+
--fe-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
139
|
+
--fe-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
|
|
140
|
+
--fe-shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.55);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* Y el interruptor manda en las dos direcciones. */
|
|
145
|
+
:root[data-theme='dark'] {
|
|
146
|
+
--fe-bg: #101116;
|
|
147
|
+
--fe-surface: #181a21;
|
|
148
|
+
--fe-surface-raised: #1f222b;
|
|
149
|
+
--fe-surface-sunk: #14161c;
|
|
150
|
+
--fe-surface-hover: #22252f;
|
|
151
|
+
|
|
152
|
+
--fe-border: #2b2e39;
|
|
153
|
+
--fe-border-strong: #3d4150;
|
|
154
|
+
|
|
155
|
+
--fe-text: #e8e9ef;
|
|
156
|
+
--fe-text-muted: #a7aab8;
|
|
157
|
+
--fe-text-subtle: #767a89;
|
|
158
|
+
--fe-text-inverse: #101116;
|
|
159
|
+
|
|
160
|
+
--fe-primary: #8b95f0;
|
|
161
|
+
--fe-primary-hover: #a0a8f5;
|
|
162
|
+
--fe-primary-text: #101116;
|
|
163
|
+
--fe-primary-soft: #21243a;
|
|
164
|
+
|
|
165
|
+
--fe-danger: #e08b83;
|
|
166
|
+
--fe-danger-hover: #eda29a;
|
|
167
|
+
--fe-danger-text: #101116;
|
|
168
|
+
--fe-danger-soft: #2c1d1c;
|
|
169
|
+
|
|
170
|
+
--fe-success: #5ec79c;
|
|
171
|
+
--fe-success-soft: #142b23;
|
|
172
|
+
|
|
173
|
+
--fe-warning: #d9ac53;
|
|
174
|
+
--fe-warning-soft: #2a2417;
|
|
175
|
+
|
|
176
|
+
--fe-focus: #8b95f0;
|
|
177
|
+
|
|
178
|
+
--fe-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
179
|
+
--fe-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
|
|
180
|
+
--fe-shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.55);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Una variante compacta lista para usar: se pone en un contenedor y todo lo
|
|
184
|
+
de dentro encoge, sin que ningún componente sepa nada. */
|
|
185
|
+
.fe-dense {
|
|
186
|
+
--fe-density: 0.875;
|
|
187
|
+
}
|
package/styles.css
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* La hoja de estilos del ecosistema innoboxrr.
|
|
3
|
+
*
|
|
4
|
+
* import 'innoboxrr-form-core/styles'
|
|
5
|
+
*
|
|
6
|
+
* Una sola linea en el arranque de la aplicacion, y los componentes de
|
|
7
|
+
* innoboxrr-form-elements, innoboxrr-react-form-elements y todo lo que genera
|
|
8
|
+
* larapack tienen aspecto sin depender de UIkit, Tailwind ni Font Awesome.
|
|
9
|
+
*
|
|
10
|
+
* Si la aplicacion ya tiene su propio sistema visual, puede no importar esto y
|
|
11
|
+
* apuntar los tokens a sus clases con `setTheme`.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
@import './src/tokens.css';
|
|
15
|
+
@import './src/layout.css';
|
|
16
|
+
@import './src/components.css';
|