@prolibu-suite/cobalt-core 0.11.1 → 0.11.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.
- package/custom-elements.json +113 -34
- package/dist/cjs/co-button.cjs.entry.js +1 -1
- package/dist/cjs/co-chip_2.cjs.entry.js +1 -1
- package/dist/cjs/co-document-editor.cjs.entry.js +1 -1
- package/dist/cjs/co-modal.cjs.entry.js +27 -1
- package/dist/cjs/co-overlay.cjs.entry.js +205 -34
- package/dist/cjs/co-rich-text-editor.cjs.entry.js +2 -2
- package/dist/cjs/co-rich-text-viewer.cjs.entry.js +1 -1
- package/dist/cjs/cobalt.cjs.js +1 -1
- package/dist/cjs/{index-oMHzCXm6.js → index-BbSD1Eyw.js} +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{pagination-DV43TRj9.js → pagination-S2sSAgdl.js} +26 -2
- package/dist/cobalt/cobalt.esm.js +1 -1
- package/dist/cobalt/{p-d6e7c258.entry.js → p-02ff847e.entry.js} +1 -1
- package/dist/cobalt/{p-87e62e2b.entry.js → p-12914c0a.entry.js} +1 -1
- package/dist/cobalt/p-38eb2615.entry.js +1 -0
- package/dist/cobalt/{p-47eca182.entry.js → p-6c7e423c.entry.js} +1 -1
- package/dist/cobalt/p-93063876.entry.js +1 -0
- package/dist/cobalt/{p-RVQJEYxa.js → p-Ch-Tygdb.js} +1 -1
- package/dist/cobalt/p-DGLDAl09.js +1 -0
- package/dist/cobalt/{p-3b6efb79.entry.js → p-bb7bbe70.entry.js} +1 -1
- package/dist/cobalt/p-efd3e0de.entry.js +1 -0
- package/dist/collection/components/co-autocomplete/co-autocomplete.js +1 -1
- package/dist/collection/components/co-avatar-group/co-avatar-group.js +1 -1
- package/dist/collection/components/co-button/co-button.css +15 -0
- package/dist/collection/components/co-checkbox-group/co-checkbox-group.js +1 -1
- package/dist/collection/components/co-chip/co-chip.css +16 -11
- package/dist/collection/components/co-color-area/co-color-area.js +2 -2
- package/dist/collection/components/co-color-slider/co-color-slider.js +1 -1
- package/dist/collection/components/co-combobox/co-combobox.js +1 -1
- package/dist/collection/components/co-command-search/co-command-search.js +1 -1
- package/dist/collection/components/co-data-table/co-data-table.js +1 -1
- package/dist/collection/components/co-date-range-picker/co-date-range-picker.js +2 -2
- package/dist/collection/components/co-document-editor/co-document-editor.js +5 -5
- package/dist/collection/components/co-modal/co-modal.js +68 -1
- package/dist/collection/components/co-overlay/co-overlay.css +7 -0
- package/dist/collection/components/co-overlay/co-overlay.js +130 -26
- package/dist/collection/components/co-overlay/focusTrap.js +111 -3
- package/dist/collection/components/co-popover/co-popover.js +1 -1
- package/dist/collection/components/co-radio-group/co-radio-group.js +1 -1
- package/dist/collection/components/co-ref-field/co-ref-field.js +4 -4
- package/dist/collection/components/co-segmented-bar/co-segmented-bar.js +1 -1
- package/dist/collection/components/co-select/co-select.js +1 -1
- package/dist/collection/components/co-sidebar-nav/co-sidebar-nav.js +1 -1
- package/dist/collection/components/co-toast/co-toast.js +2 -2
- package/dist/collection/components/co-transfer-list/co-transfer-list.js +1 -1
- package/dist/collection/components/co-tree-item/co-tree-item.js +2 -2
- package/dist/components/co-autocomplete.js +1 -1
- package/dist/components/co-button.js +1 -1
- package/dist/components/co-chip.js +1 -1
- package/dist/components/co-column-picker.js +1 -1
- package/dist/components/co-combobox.js +1 -1
- package/dist/components/co-command-search.js +1 -1
- package/dist/components/co-data-table.js +1 -1
- package/dist/components/co-date-picker.js +1 -1
- package/dist/components/co-date-range-picker.js +1 -1
- package/dist/components/co-date-range.js +1 -1
- package/dist/components/co-date-time-picker.js +1 -1
- package/dist/components/co-document-editor.js +1 -1
- package/dist/components/co-drawer.js +1 -1
- package/dist/components/co-modal.js +1 -1
- package/dist/components/co-overlay.js +1 -1
- package/dist/components/co-rich-text-editor.js +1 -1
- package/dist/components/co-rich-text-viewer.js +1 -1
- package/dist/components/{p-BVdCvEza.js → p-BI_VaFsx.js} +1 -1
- package/dist/components/{p-Du8EpQb-.js → p-C_6szR7t.js} +1 -1
- package/dist/components/{p-RVQJEYxa.js → p-Ch-Tygdb.js} +1 -1
- package/dist/components/{p-zJ3pjFzW.js → p-DB8DGMc-.js} +1 -1
- package/dist/components/p-DGLDAl09.js +1 -0
- package/dist/components/{p-Hi57w2_2.js → p-DhPxNA2f.js} +1 -1
- package/dist/components/p-wUXcJGdy.js +1 -0
- package/dist/esm/co-button.entry.js +1 -1
- package/dist/esm/co-chip_2.entry.js +1 -1
- package/dist/esm/co-document-editor.entry.js +1 -1
- package/dist/esm/co-modal.entry.js +28 -2
- package/dist/esm/co-overlay.entry.js +205 -34
- package/dist/esm/co-rich-text-editor.entry.js +2 -2
- package/dist/esm/co-rich-text-viewer.entry.js +1 -1
- package/dist/esm/cobalt.js +1 -1
- package/dist/esm/{index-Cpo8HTwr.js → index-CgyOJePd.js} +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{pagination-D9OfZUnY.js → pagination-BzrIQtrk.js} +26 -2
- package/dist/types/components/co-modal/co-modal.d.ts +23 -0
- package/dist/types/components/co-overlay/co-overlay.d.ts +29 -1
- package/dist/types/components/co-overlay/focusTrap.d.ts +24 -3
- package/dist/types/components.d.ts +21 -2
- package/package.json +4 -4
- package/dist/cobalt/p-1a5bec8c.entry.js +0 -1
- package/dist/cobalt/p-67a024dd.entry.js +0 -1
- package/dist/cobalt/p-B1JT7us1.js +0 -1
- package/dist/cobalt/p-c4c997f3.entry.js +0 -1
- package/dist/components/p-B1JT7us1.js +0 -1
- package/dist/components/p-nrwDl_gx.js +0 -1
|
@@ -57,20 +57,112 @@ function resolveTabIndex(count, activeIndex, shiftKey) {
|
|
|
57
57
|
// Forward: from the last element (or from outside) wrap to the first.
|
|
58
58
|
return activeIndex === -1 || activeIndex >= count - 1 ? 0 : activeIndex + 1;
|
|
59
59
|
}
|
|
60
|
+
// ── Recorrido compuesto (QA 2026-09-24, «Generar contrato» de contratos V2) ──
|
|
61
|
+
// El foco nunca entraba ni quedaba atrapado en un co-modal: `getFocusableElements`
|
|
62
|
+
// solo mira el light DOM de co-overlay (el frame del modal: el ✕). El contenido
|
|
63
|
+
// del consumidor llega por DOS <slot> (el de co-overlay y el del frame) y los
|
|
64
|
+
// controles reales viven en el shadow de cada co-* (el <button> de co-button, el
|
|
65
|
+
// <input> de co-input). El recorrido sigue el árbol PLANO: baja por shadowRoots
|
|
66
|
+
// y, en cada <slot>, por sus asignados — o por su contenido por defecto si no
|
|
67
|
+
// tiene. Todo esto corre solo en el navegador (abrir la trampa / cada Tab).
|
|
68
|
+
/** Hijos en el árbol plano: el shadow del host, los asignados de un slot o los hijos. */
|
|
69
|
+
function composedChildren(el) {
|
|
70
|
+
if (el.shadowRoot)
|
|
71
|
+
return Array.from(el.shadowRoot.children);
|
|
72
|
+
if (el.tagName === 'SLOT') {
|
|
73
|
+
const assigned = el.assignedElements({ flatten: true });
|
|
74
|
+
return assigned.length ? assigned : Array.from(el.children);
|
|
75
|
+
}
|
|
76
|
+
return Array.from(el.children);
|
|
77
|
+
}
|
|
78
|
+
/** Subárbol fuera de la trampa entero: oculto a AT o inerte. */
|
|
79
|
+
function isExcludedSubtree(el) {
|
|
80
|
+
return el.getAttribute('aria-hidden') === 'true' || el.hasAttribute('inert');
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Parada de Tab: matchea el selector, no está deshabilitado, no se sacó del
|
|
84
|
+
* orden con tabindex negativo (los botones internos de un trigger co-* —clear,
|
|
85
|
+
* chips— van con `tabIndex={-1}`, y `button:not([disabled])` los matchearía
|
|
86
|
+
* igual), tiene caja (offsetParent null = display:none; getClientRects cubre
|
|
87
|
+
* position:fixed) y no es `visibility:hidden`: un acordeón o fieldset colapsado
|
|
88
|
+
* conserva la caja pero el navegador no le da el foco, y la trampa lo elegiría
|
|
89
|
+
* igual → Tab clavado (WCAG 2.1.2). Sin la API (navegador viejo, jsdom) no filtra.
|
|
90
|
+
*/
|
|
91
|
+
function isTabStop(el) {
|
|
92
|
+
var _a, _b;
|
|
93
|
+
if (!((_a = el.matches) === null || _a === void 0 ? void 0 : _a.call(el, FOCUSABLE_SELECTOR)) || el.hasAttribute('disabled'))
|
|
94
|
+
return false;
|
|
95
|
+
const tabindex = el.getAttribute('tabindex');
|
|
96
|
+
if (tabindex !== null && Number(tabindex) < 0)
|
|
97
|
+
return false;
|
|
98
|
+
if (el.offsetParent === null && el.getClientRects().length === 0)
|
|
99
|
+
return false;
|
|
100
|
+
return ((_b = el.checkVisibility) === null || _b === void 0 ? void 0 : _b.call(el, { visibilityProperty: true })) !== false;
|
|
101
|
+
}
|
|
60
102
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* out of scope — the common dialog/modal content lives in the slotted subtree.)
|
|
103
|
+
* Recorre en orden del árbol plano los descendientes compuestos de `root` (sin
|
|
104
|
+
* incluirlo) hasta que `visit` devuelve true. Poda aria-hidden / inert.
|
|
64
105
|
*/
|
|
65
|
-
function
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
106
|
+
function walkComposed(root, visit) {
|
|
107
|
+
const step = (node) => {
|
|
108
|
+
if (isExcludedSubtree(node))
|
|
109
|
+
return false;
|
|
110
|
+
if (visit(node))
|
|
111
|
+
return true;
|
|
112
|
+
return composedChildren(node).some(step);
|
|
113
|
+
};
|
|
114
|
+
composedChildren(root).some(step);
|
|
115
|
+
}
|
|
116
|
+
/** Primer descendiente compuesto que cumple `match`, en orden del árbol plano. */
|
|
117
|
+
function findComposed(root, match) {
|
|
118
|
+
let found = null;
|
|
119
|
+
walkComposed(root, (el) => {
|
|
120
|
+
if (!match(el))
|
|
121
|
+
return false;
|
|
122
|
+
found = el;
|
|
123
|
+
return true;
|
|
124
|
+
});
|
|
125
|
+
return found;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Paradas de Tab dentro de `root` en el árbol COMPUESTO (shadowRoots + slots
|
|
129
|
+
* asignados), con las mismas exclusiones que `getFocusableElements`.
|
|
130
|
+
*/
|
|
131
|
+
function getComposedFocusables(root) {
|
|
132
|
+
const out = [];
|
|
133
|
+
walkComposed(root, (el) => {
|
|
134
|
+
if (isTabStop(el))
|
|
135
|
+
out.push(el);
|
|
136
|
+
return false;
|
|
137
|
+
});
|
|
138
|
+
return out;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Dónde cae el foco al abrir la trampa: el primer `[autofocus]` del recorrido
|
|
142
|
+
* compuesto —si es un host con shadow (`<co-input autofocus>`), su primer
|
|
143
|
+
* enfocable compuesto—; si no hay, la primera parada de Tab. `null` = nada
|
|
144
|
+
* enfocable (el llamador cae al contenedor).
|
|
145
|
+
*/
|
|
146
|
+
function resolveInitialFocus(root) {
|
|
147
|
+
const autofocus = findComposed(root, (el) => el.hasAttribute('autofocus'));
|
|
148
|
+
if (autofocus) {
|
|
149
|
+
if (isTabStop(autofocus))
|
|
150
|
+
return autofocus;
|
|
151
|
+
const inner = autofocus.shadowRoot ? getComposedFocusables(autofocus)[0] : undefined;
|
|
152
|
+
if (inner)
|
|
153
|
+
return inner;
|
|
154
|
+
}
|
|
155
|
+
return findComposed(root, isTabStop);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Con dos trampas abiertas (un confirm sobre un modal, un modal anidado) las dos
|
|
159
|
+
* escuchan el keydown de document: solo la capa MÁS RECIENTE maneja Tab.
|
|
160
|
+
*/
|
|
161
|
+
function isTopTrap(stack, id) {
|
|
162
|
+
return stack.length > 0 && stack[stack.length - 1] === id;
|
|
71
163
|
}
|
|
72
164
|
|
|
73
|
-
const coOverlayCss = () => `:host{display:contents}.co-overlay{position:fixed;inset:0;z-index:1000;margin:0;border:0;padding:0;width:auto;height:auto;max-width:none;max-height:none;overflow:visible;display:flex;align-items:center;justify-content:center;background:var(--co-overlay-bg, rgba(0, 0, 0, 0.4));-webkit-backdrop-filter:blur(var(--co-overlay-blur, 2px));backdrop-filter:blur(var(--co-overlay-blur, 2px));opacity:0;pointer-events:none;transition:opacity var(--co-motion-duration-fast) var(--co-motion-ease-in)}.co-overlay--open{opacity:1;pointer-events:auto;transition:opacity var(--co-motion-duration-base) var(--co-motion-ease-out)}`;
|
|
165
|
+
const coOverlayCss = () => `:host{display:contents}.co-overlay{position:fixed;inset:0;z-index:1000;margin:0;border:0;padding:0;width:auto;height:auto;max-width:none;max-height:none;overflow:visible;display:flex;align-items:center;justify-content:center;background:var(--co-overlay-bg, rgba(0, 0, 0, 0.4));-webkit-backdrop-filter:blur(var(--co-overlay-blur, 2px));backdrop-filter:blur(var(--co-overlay-blur, 2px));opacity:0;pointer-events:none;transition:opacity var(--co-motion-duration-fast) var(--co-motion-ease-in)}.co-overlay--open{opacity:1;pointer-events:auto;transition:opacity var(--co-motion-duration-base) var(--co-motion-ease-out)}.co-overlay--refront{transition:none !important}`;
|
|
74
166
|
|
|
75
167
|
/**
|
|
76
168
|
* Module-level body-scroll lock shared by every overlay instance.
|
|
@@ -98,6 +190,16 @@ function unlockBodyScroll() {
|
|
|
98
190
|
document.body.style.overflow = savedOverflow;
|
|
99
191
|
}
|
|
100
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Pila de trampas de foco ABIERTAS, compartida por todas las instancias (como el
|
|
195
|
+
* scroll lock). Todas escuchan el keydown de document: con un confirm encima de
|
|
196
|
+
* un modal, las dos movían el foco en el mismo Tab. Solo la capa más reciente
|
|
197
|
+
* (`isTopTrap`) maneja Tab y el foco inicial.
|
|
198
|
+
*/
|
|
199
|
+
const trapStack = [];
|
|
200
|
+
let trapSeq = 0;
|
|
201
|
+
/** Clase del div mientras dura el re-apilado de `bringToFront()` (ver co-overlay.css). */
|
|
202
|
+
const REFRONT_CLASS = 'co-overlay--refront';
|
|
101
203
|
function nextFrame(cb) {
|
|
102
204
|
if (typeof requestAnimationFrame === 'function')
|
|
103
205
|
requestAnimationFrame(cb);
|
|
@@ -117,6 +219,11 @@ const CoOverlay = class {
|
|
|
117
219
|
* previously-focused element, moves focus into the overlay, cycles Tab /
|
|
118
220
|
* Shift+Tab within the slotted content, and restores focus on close.
|
|
119
221
|
* Default false → existing consumers are unchanged.
|
|
222
|
+
*
|
|
223
|
+
* The walk is COMPOSED (shadow roots + assigned slots): it reaches the
|
|
224
|
+
* consumer's content projected through a host's slots and the inner control
|
|
225
|
+
* of every co-* (a co-button's `<button>`). With several traps open, only the
|
|
226
|
+
* most recent one handles Tab.
|
|
120
227
|
*/
|
|
121
228
|
this.trapFocus = false;
|
|
122
229
|
/**
|
|
@@ -126,6 +233,10 @@ const CoOverlay = class {
|
|
|
126
233
|
this.closeOnEscape = false;
|
|
127
234
|
/** Whether THIS instance currently holds a scroll lock (prevents double-count). */
|
|
128
235
|
this.hasLock = false;
|
|
236
|
+
/** Identidad de esta instancia en `trapStack`. */
|
|
237
|
+
this.trapId = `co-overlay-trap-${++trapSeq}`;
|
|
238
|
+
/** Whether THIS instance is currently in `trapStack` (prevents double push). */
|
|
239
|
+
this.trapping = false;
|
|
129
240
|
// Origen de la pulsación en curso (ver isBackdropDismiss): un drag que
|
|
130
241
|
// empieza dentro del contenido y suelta en el fondo NO es un cierre —el
|
|
131
242
|
// navegador despacha ese `click` al ancestro común, el propio scrim—, ni
|
|
@@ -167,27 +278,55 @@ const CoOverlay = class {
|
|
|
167
278
|
else
|
|
168
279
|
this.releaseLock();
|
|
169
280
|
this.syncPopover();
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
this.restoreFocus();
|
|
175
|
-
}
|
|
281
|
+
this.syncTrap();
|
|
282
|
+
}
|
|
283
|
+
onTrapFocusChange() {
|
|
284
|
+
this.syncTrap();
|
|
176
285
|
}
|
|
177
286
|
componentDidLoad() {
|
|
178
287
|
// Handle the case where the overlay mounts already open.
|
|
179
288
|
if (this.open)
|
|
180
289
|
this.acquireLock();
|
|
181
290
|
this.syncPopover();
|
|
182
|
-
|
|
183
|
-
this.captureAndFocus();
|
|
291
|
+
this.syncTrap();
|
|
184
292
|
}
|
|
185
293
|
disconnectedCallback() {
|
|
186
294
|
// Safety: never leave the body locked if removed while open.
|
|
187
295
|
this.releaseLock();
|
|
188
|
-
// Safety: return focus if
|
|
189
|
-
|
|
190
|
-
|
|
296
|
+
// Safety: leave the trap stack and return focus if removed while trapping.
|
|
297
|
+
this.releaseTrap();
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Re-promueve el scrim al TOPE del top layer (QA 2026-09-24, «Generar
|
|
301
|
+
* contrato»): un drawer abierto DESPUÉS de un modal pintaba encima, porque en
|
|
302
|
+
* el top layer gana el último promovido y no hay z-index que lo corrija.
|
|
303
|
+
* `hidePopover()` + `showPopover()` lo vuelven a meter último.
|
|
304
|
+
*
|
|
305
|
+
* No es un cierre: no emite `coClose` / `coAfterClose` / `coAfterOpen`, no
|
|
306
|
+
* toca `open` ni el scroll lock, y no re-anima la entrada (la clase
|
|
307
|
+
* `co-overlay--refront` anula la transición durante el re-show y se retira en
|
|
308
|
+
* el frame siguiente). Tampoco mueve el foco: si el re-show dispara los
|
|
309
|
+
* «popover focusing steps» (un `[autofocus]` adentro), se devuelve a donde
|
|
310
|
+
* estaba. No-op cerrado, sin Popover API o fuera del top layer.
|
|
311
|
+
*/
|
|
312
|
+
async bringToFront() {
|
|
313
|
+
const el = this.overlayEl;
|
|
314
|
+
if (!this.open || !el || typeof el.showPopover !== 'function')
|
|
315
|
+
return;
|
|
316
|
+
if (!el.matches(':popover-open'))
|
|
317
|
+
return;
|
|
318
|
+
const active = this.deepActiveElement();
|
|
319
|
+
el.classList.add(REFRONT_CLASS);
|
|
320
|
+
try {
|
|
321
|
+
el.hidePopover();
|
|
322
|
+
el.showPopover();
|
|
323
|
+
}
|
|
324
|
+
catch (_a) {
|
|
325
|
+
/* desconectado entre medio: no hay nada que re-apilar */
|
|
326
|
+
}
|
|
327
|
+
if (active && active.isConnected && this.deepActiveElement() !== active)
|
|
328
|
+
active.focus({ preventScroll: true });
|
|
329
|
+
nextFrame(() => el.classList.remove(REFRONT_CLASS));
|
|
191
330
|
}
|
|
192
331
|
acquireLock() {
|
|
193
332
|
if (this.hasLock)
|
|
@@ -225,19 +364,43 @@ const CoOverlay = class {
|
|
|
225
364
|
/* not connected yet, or already in the desired state */
|
|
226
365
|
}
|
|
227
366
|
}
|
|
228
|
-
/**
|
|
367
|
+
/** La trampa está activa exactamente mientras el overlay está abierto con `trapFocus`. */
|
|
368
|
+
syncTrap() {
|
|
369
|
+
if (this.open && this.trapFocus)
|
|
370
|
+
this.engageTrap();
|
|
371
|
+
else
|
|
372
|
+
this.releaseTrap();
|
|
373
|
+
}
|
|
374
|
+
engageTrap() {
|
|
375
|
+
if (this.trapping)
|
|
376
|
+
return;
|
|
377
|
+
this.trapping = true;
|
|
378
|
+
trapStack.push(this.trapId);
|
|
379
|
+
this.captureAndFocus();
|
|
380
|
+
}
|
|
381
|
+
releaseTrap() {
|
|
382
|
+
if (!this.trapping)
|
|
383
|
+
return;
|
|
384
|
+
this.trapping = false;
|
|
385
|
+
const i = trapStack.indexOf(this.trapId);
|
|
386
|
+
if (i >= 0)
|
|
387
|
+
trapStack.splice(i, 1);
|
|
388
|
+
this.restoreFocus();
|
|
389
|
+
}
|
|
390
|
+
/** Record the current focus and move it into the overlay (only while trapping). */
|
|
229
391
|
captureAndFocus() {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
392
|
+
// El activo PROFUNDO: `document.activeElement` se queda en el host de un
|
|
393
|
+
// co-* (co-button), cuyo focus() no llega al <button> interno.
|
|
394
|
+
this.returnFocusEl = this.deepActiveElement();
|
|
233
395
|
// Defer so slotted content / the open transition is ready to take focus.
|
|
234
396
|
nextFrame(() => {
|
|
235
397
|
var _a;
|
|
236
|
-
|
|
398
|
+
// Una trampa abierta en el mismo frame por ENCIMA (confirm) se queda el foco.
|
|
399
|
+
if (!this.open || !this.trapping || !isTopTrap(trapStack, this.trapId))
|
|
237
400
|
return;
|
|
238
|
-
const
|
|
239
|
-
if (
|
|
240
|
-
|
|
401
|
+
const target = resolveInitialFocus(this.el);
|
|
402
|
+
if (target)
|
|
403
|
+
target.focus();
|
|
241
404
|
else
|
|
242
405
|
(_a = this.overlayEl) === null || _a === void 0 ? void 0 : _a.focus();
|
|
243
406
|
});
|
|
@@ -246,8 +409,9 @@ const CoOverlay = class {
|
|
|
246
409
|
restoreFocus() {
|
|
247
410
|
const target = this.returnFocusEl;
|
|
248
411
|
this.returnFocusEl = null;
|
|
249
|
-
|
|
250
|
-
|
|
412
|
+
// Desmontado mientras el overlay estaba abierto (el paso de un wizard): no hay adónde volver.
|
|
413
|
+
if (target && target.isConnected && typeof target.focus === 'function')
|
|
414
|
+
target.focus({ preventScroll: true });
|
|
251
415
|
}
|
|
252
416
|
/** Deepest active element, descending through nested shadow roots. */
|
|
253
417
|
deepActiveElement() {
|
|
@@ -266,12 +430,16 @@ const CoOverlay = class {
|
|
|
266
430
|
this.coClose.emit();
|
|
267
431
|
return;
|
|
268
432
|
}
|
|
269
|
-
if (this.
|
|
433
|
+
if (this.trapping && e.key === 'Tab' && isTopTrap(trapStack, this.trapId))
|
|
270
434
|
this.trapTab(e);
|
|
271
435
|
}
|
|
272
436
|
trapTab(e) {
|
|
273
437
|
var _a;
|
|
274
|
-
|
|
438
|
+
// Tab ya manejado por un control de adentro (co-tags-field agrega el tag, las listas de co-rich-text y
|
|
439
|
+
// CodeMirror indentan): el listener de document corre DESPUÉS y no le roba el foco.
|
|
440
|
+
if (e.defaultPrevented)
|
|
441
|
+
return;
|
|
442
|
+
const focusables = getComposedFocusables(this.el);
|
|
275
443
|
if (focusables.length === 0) {
|
|
276
444
|
// Nothing to move to — keep focus pinned to the overlay container.
|
|
277
445
|
e.preventDefault();
|
|
@@ -286,12 +454,15 @@ const CoOverlay = class {
|
|
|
286
454
|
focusables[nextIndex].focus();
|
|
287
455
|
}
|
|
288
456
|
render() {
|
|
289
|
-
return (index.h("div", { key: '
|
|
457
|
+
return (index.h("div", { key: 'e18d7b0e3ebd4933a78a9f2d39af6058ce429105', class: { 'co-overlay': true, 'co-overlay--open': this.open }, part: "overlay", popover: "manual", tabindex: this.trapFocus ? -1 : undefined, ref: (el) => (this.overlayEl = el), onPointerDown: this.handlePointerDown, onPointerUp: this.handlePointerUp, onClick: this.handleClick, onTransitionEnd: this.handleTransitionEnd }, index.h("slot", { key: '2f29233d44de8a0cc3100cfa08233cdc10ebf352' })));
|
|
290
458
|
}
|
|
291
459
|
get el() { return index.getElement(this); }
|
|
292
460
|
static get watchers() { return {
|
|
293
461
|
"open": [{
|
|
294
462
|
"onOpenChange": 0
|
|
463
|
+
}],
|
|
464
|
+
"trapFocus": [{
|
|
465
|
+
"onTrapFocusChange": 0
|
|
295
466
|
}]
|
|
296
467
|
}; }
|
|
297
468
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var index = require('./index-bHoidDwv.js');
|
|
4
|
-
var index$1 = require('./index-
|
|
4
|
+
var index$1 = require('./index-BbSD1Eyw.js');
|
|
5
5
|
var richTextI18n = require('./richTextI18n-DXGIv5w1.js');
|
|
6
6
|
var richTextHost = require('./rich-text-host-ueFSfW-6.js');
|
|
7
|
-
require('./pagination-
|
|
7
|
+
require('./pagination-S2sSAgdl.js');
|
|
8
8
|
require('./purify.es-DX41ZWS2.js');
|
|
9
9
|
require('./toolbar-config-DczL6C4W.js');
|
|
10
10
|
|
|
@@ -135,7 +135,7 @@ const CoRichTextViewer = class {
|
|
|
135
135
|
// JSON mode — lazily import the serializer (pulls Tiptap on demand only).
|
|
136
136
|
try {
|
|
137
137
|
const doc = JSON.parse(this.value);
|
|
138
|
-
const rt = await Promise.resolve().then(function () { return require('./index-
|
|
138
|
+
const rt = await Promise.resolve().then(function () { return require('./index-BbSD1Eyw.js'); }).then(function (n) { return n.RichText; });
|
|
139
139
|
this.html = rt.jsonToHtml(doc, this.preset);
|
|
140
140
|
}
|
|
141
141
|
catch (_a) {
|