@edc-motor/ui 0.5.5 → 0.5.6

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.5",
3
+ "version": "0.5.6",
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",
@@ -87,6 +87,23 @@ $icon-chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000
87
87
  cursor: pointer;
88
88
  }
89
89
 
90
+ // MITIGACIÓN del «baile» al hover en el modal de bloque (DPI fraccionario):
91
+ // dentro de un modal, el realce de hover/focus es INSTANTÁNEO. La
92
+ // transición de border-color/box-shadow fuerza ~10 repintados seguidos con
93
+ // un área de invalidación mayor que el propio input (el box-shadow pinta
94
+ // fuera de su caja) y, con las filas del esquema en columnas de ancho
95
+ // fraccional (auto-fit 1fr) y un devicePixelRatio no entero (125%/150%),
96
+ // esa re-rasterización repetida puede hacer temblar los campos VECINOS.
97
+ // Un único repintado por cambio de estado elimina el tembleque sin tocar
98
+ // la geometría ni el aspecto final.
99
+ .modal & {
100
+ &__input,
101
+ &__textarea,
102
+ &__select {
103
+ transition: none;
104
+ }
105
+ }
106
+
90
107
  &--error &__input,
91
108
  &--error &__textarea,
92
109
  &--error &__select {
@@ -59,10 +59,17 @@ const { hasContent, collapsed, mobileOpen, overlay, title, isOpen, toggle, close
59
59
  const OVERLAY_BREAKPOINT = 900
60
60
 
61
61
  function checkOverlay() {
62
- overlay.value = props.overlayAlways || window.innerWidth < OVERLAY_BREAKPOINT
62
+ overlay.value =
63
+ props.overlayAlways || (typeof window !== 'undefined' && window.innerWidth < OVERLAY_BREAKPOINT)
63
64
  if (!overlay.value) mobileOpen.value = false
64
65
  }
65
66
 
67
+ // EAGER, en el propio setup (no esperar a mounted): que no exista NI UN
68
+ // frame en el que overlayAlways pudiera pintarse como columna atracada
69
+ // (p. ej. si el singleton del composable se recrea en caliente con HMR y
70
+ // `overlay` vuelve a su valor inicial `false`).
71
+ checkOverlay()
72
+
66
73
  // Si el consumidor cambia el modo en caliente, el estado se recalcula.
67
74
  watch(() => props.overlayAlways, checkOverlay)
68
75
 
@@ -87,8 +94,13 @@ const handleLabel = computed(() => (isOpen.value ? props.closeLabel : props.open
87
94
 
88
95
  // Desplegada en ANCHO: el cascarón le hace hueco (body:has en su scss).
89
96
  // hasContent va en la clase porque v-show (display: none) no saca al aside
90
- // de los selectores :has.
91
- const docked = computed(() => hasContent.value && !overlay.value && !collapsed.value)
97
+ // de los selectores :has. Con `overlayAlways`, `--docked` es imposible por
98
+ // construcción (aunque `overlay` aún no se hubiera recalculado): el
99
+ // cascarón no puede hacerle hueco JAMÁS y el drawer estrecho es la única
100
+ // versión que existe.
101
+ const docked = computed(
102
+ () => !props.overlayAlways && hasContent.value && !overlay.value && !collapsed.value,
103
+ )
92
104
  </script>
93
105
 
94
106
  <template>