@edc-motor/ui 0.5.6 → 0.5.7

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edc-motor/ui",
3
- "version": "0.5.6",
3
+ "version": "0.5.7",
4
4
  "description": "EdC Motor — componentes públicos Vue 3 + tokens SCSS para webs de juegos de mesa (paquete fuente: lo compila el consumidor con Vite)",
5
5
  "license": "GPL-3.0-only",
6
6
  "type": "module",
@@ -0,0 +1,125 @@
1
+ @use "tokens" as *;
2
+
3
+ // =========================================================
4
+ // Sistema COMPARTIDO de filas y grupos de formulario
5
+ // =========================================================
6
+ // Un único lenguaje para TODOS los formularios modales del admin:
7
+ // sustituye a los layouts ad hoc que había repartidos (el `__common-row` de
8
+ // PageBlocks y las filas `--pair`/`--row`/`--image-group` de SchemaFields).
9
+ //
10
+ // PROHIBIDO auto-fit/auto-fill en todo el sistema: columnas FIJAS + cortes
11
+ // EXPLÍCITOS de container query. Con auto-fit las pistas se re-resolvían
12
+ // contra el ancho de `modal-body` (que depende de si hay scrollbar),
13
+ // quedaban pistas fantasma a 0px y los `1fr` resultaban fraccionales
14
+ // desiguales: al repintar con hover a DPI 125 %/150 % los campos vecinos
15
+ // temblaban («baile» en modales largos). Con pistas fijas el layout es
16
+ // idéntico en cada repintado.
17
+ //
18
+ // El contenedor `modal-body` lo define _modal.scss sobre el cuerpo del
19
+ // modal: el patrón funciona en CUALQUIER modal y los cortes miden el ancho
20
+ // REAL del formulario, no el del viewport.
21
+ .form-row {
22
+ display: grid;
23
+ // Base: dos columnas fijas iguales.
24
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
25
+ gap: $space-3;
26
+ align-items: start;
27
+
28
+ > * { min-width: 0; }
29
+
30
+ // Un checkbox como celda: flex para que se comporte como bloque de su
31
+ // celda junto a sus compañeros de fila.
32
+ > .checkbox { display: flex; }
33
+
34
+ // Tres columnas fijas iguales, para filas de 3 campos pequeños.
35
+ &--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
36
+
37
+ // Columna izquierda MUCHO más ancha que la derecha (2:1): un textarea o
38
+ // wysiwyg a la izquierda con su campo pequeño natural al lado (p. ej. el
39
+ // select de alineación). 2fr y no 2.5fr: en el modal `md` (~520px útiles)
40
+ // 2:1 deja ~170px a la derecha — lo justo para un select con su etiqueta
41
+ // («Alineación del subtítulo»…) sin cortarse; con 2.5fr quedaría corto.
42
+ &--wide-left { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
43
+
44
+ // Fila de imagen (especial): la celda izquierda (el input de imagen, con
45
+ // su etiqueta) es UNA sola celda que llena TODO el alto de la fila; la
46
+ // derecha es una pila de filas (.form-row__stack) con los ajustes
47
+ // (posición, escalado, reparto de columnas…). El cuadro de arrastre NO se
48
+ // estira con la celda: conserva su tamaño natural y se centra en el
49
+ // espacio (margin-block auto en _image-upload.scss).
50
+ &--media {
51
+ align-items: stretch;
52
+
53
+ > :first-child {
54
+ display: flex;
55
+ flex-direction: column;
56
+ gap: $space-1;
57
+ min-width: 0;
58
+ min-height: 0;
59
+
60
+ // El input crece para llenar la celda (envoltorios de etiqueta
61
+ // incluidos: .form-field de TranslatableImage, etc.).
62
+ .image-upload {
63
+ flex: 1;
64
+ min-height: 0;
65
+ }
66
+ }
67
+ }
68
+
69
+ // Pila de filas apiladas dentro de una celda (la columna derecha de
70
+ // --media): mismo ritmo que la propia fila.
71
+ &__stack {
72
+ display: grid;
73
+ gap: $space-3;
74
+ align-content: start;
75
+ }
76
+
77
+ // Cortes explícitos (en vez del auto-fit):
78
+ // — la fila de 3 apila ANTES que el resto: por debajo de ~564px de
79
+ // modal-body (3 campos de 180px mínimos cómodos + 2 gaps) ya no caben
80
+ // tres columnas. Pasa DIRECTA a una columna, sin estadio intermedio
81
+ // 2+1 que dejaría una celda huérfana descolgada.
82
+ @container modal-body (max-width: 563px) {
83
+ &--3 { grid-template-columns: minmax(0, 1fr); }
84
+ }
85
+
86
+ // — TODAS las variantes apilan a una columna en el modal angosto.
87
+ @container modal-body (max-width: #{$bp-sm - 1px}) {
88
+ &,
89
+ &--3,
90
+ &--wide-left,
91
+ &--media {
92
+ grid-template-columns: minmax(0, 1fr);
93
+ }
94
+ }
95
+ }
96
+
97
+ // Separador de grupos de campos relacionados dentro de un formulario:
98
+ // <fieldset class="form-fieldset"><legend>…</legend>…</fieldset>
99
+ // Raya superior dashed (el mismo lenguaje que tenía la divisoria de la
100
+ // sección General del form de bloque); el navegador corta la raya donde
101
+ // asienta el legend (comportamiento nativo de fieldset+legend).
102
+ .form-fieldset {
103
+ margin: 0;
104
+ padding: $space-3 0 0; // aire entre la raya y el primer campo
105
+ border: 0;
106
+ border-top: 1px dashed $border;
107
+ min-width: 0; // los fieldset traen min-width min-content; aquí estorba
108
+ display: grid;
109
+ gap: $space-4; // el mismo ritmo que .edit-modal__body
110
+
111
+ // Legend discreto asentado sobre la raya: pegado al borde izquierdo y
112
+ // con un poco de aire antes de que sigan los guiones.
113
+ > legend {
114
+ padding-inline: 0 $space-2;
115
+ font-size: $fs-13;
116
+ color: $text-2;
117
+ }
118
+
119
+ // El PRIMER grupo del formulario no lleva raya superior (el formulario
120
+ // empieza directamente con él; su legend hace de título).
121
+ &:first-child {
122
+ border-top: 0;
123
+ padding-top: 0;
124
+ }
125
+ }
@@ -3,6 +3,7 @@
3
3
  @use "icon-button";
4
4
  @use "motor-badge";
5
5
  @use "form-field";
6
+ @use "form-row";
6
7
  @use "base-select";
7
8
  @use "base-pagination";
8
9
  @use "search-select";