@erplora/outfitkit 0.1.26 → 0.1.27
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/dist/components/ok-data-table/locale-defaults.test.d.ts +1 -0
- package/dist/components/ok-data-table/ok-data-table.d.ts +6 -2
- package/dist/layout.css +135 -1
- package/dist/ok-data-table.js +61 -2
- package/dist/ok-navbar.js +33 -11
- package/dist/outfitkit.bundle.js +641 -569
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './ok-data-table.js';
|
|
@@ -56,8 +56,9 @@ export interface DataTablePrimaryAction {
|
|
|
56
56
|
}
|
|
57
57
|
/** Clave estable de fila: nombre de campo o función que la devuelve. */
|
|
58
58
|
export type DataTableRowKey = string | ((row: Record<string, unknown>) => string);
|
|
59
|
-
/** (NUEVO, additivo) Todos los textos humanos del data-table, para i18n.
|
|
60
|
-
* Se pasan desde fuera vía la prop `.labels` (parcial); lo no pasado cae al
|
|
59
|
+
/** (NUEVO, additivo) Todos los textos humanos del data-table, para i18n.
|
|
60
|
+
* Se pasan desde fuera vía la prop `.labels` (parcial); lo no pasado cae al idioma del documento
|
|
61
|
+
* (`<html lang="es">` → español; cualquier otro idioma → inglés).
|
|
61
62
|
* El contenido data-driven (columns/rows/options) NO va aquí — ya es externo. */
|
|
62
63
|
export interface OkDataTableLabels {
|
|
63
64
|
/** Placeholder del buscador. */
|
|
@@ -234,6 +235,9 @@ export declare class OkDataTable extends LitElement {
|
|
|
234
235
|
private internalSelection;
|
|
235
236
|
private menuOpen;
|
|
236
237
|
private menuEv?;
|
|
238
|
+
private readonly onLocaleChanged;
|
|
239
|
+
connectedCallback(): void;
|
|
240
|
+
disconnectedCallback(): void;
|
|
237
241
|
private get t();
|
|
238
242
|
/** Placeholder efectivo del buscador (prop explícita → label i18n → default inglés). */
|
|
239
243
|
private get effSearchPlaceholder();
|
package/dist/layout.css
CHANGED
|
@@ -205,6 +205,141 @@
|
|
|
205
205
|
color: var(--ok-muted, rgba(var(--ion-text-color-rgb, 24, 24, 27), 0.62));
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
+
/* ===== Editorial content and documentation surfaces =====
|
|
209
|
+
*
|
|
210
|
+
* Reusable public/documentation primitives: constrained readable width,
|
|
211
|
+
* Ionic search/accordion theming and rich-text content generated from Markdown.
|
|
212
|
+
*/
|
|
213
|
+
ion-searchbar.ok-search {
|
|
214
|
+
--background: var(--ok-surface, var(--ion-card-background, #fff));
|
|
215
|
+
--border-radius: 0.875rem;
|
|
216
|
+
--box-shadow: 0 10px 28px -22px color-mix(in oklab, var(--ok-text, var(--ion-text-color, #18181b)) 45%, transparent);
|
|
217
|
+
--color: var(--ok-text, var(--ion-text-color, #18181b));
|
|
218
|
+
--icon-color: var(--ok-primary, var(--ion-color-primary, #1496d6));
|
|
219
|
+
--placeholder-color: var(--ok-text, var(--ion-text-color, #18181b));
|
|
220
|
+
--placeholder-opacity: 0.55;
|
|
221
|
+
padding-inline: 0;
|
|
222
|
+
margin-block-end: 1rem;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
ion-accordion.ok-accordion {
|
|
226
|
+
--background: var(--ok-surface, var(--ion-card-background, var(--ion-background-color, #fff)));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
ion-item.ok-accordion-header {
|
|
230
|
+
--background: var(--ok-surface, var(--ion-card-background, var(--ion-background-color, #fff)));
|
|
231
|
+
--color: var(--ok-text, var(--ion-text-color, #18181b));
|
|
232
|
+
--padding-start: 1.125rem;
|
|
233
|
+
--inner-padding-end: 1rem;
|
|
234
|
+
font-weight: 600;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
ion-item.ok-accordion-header iconify-icon {
|
|
238
|
+
color: var(--ok-primary, var(--ion-color-primary, #1496d6));
|
|
239
|
+
margin-inline-end: 0.75rem;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.ok-accordion-body {
|
|
243
|
+
padding: 0.25rem 1.25rem 1.5rem;
|
|
244
|
+
background: var(--ok-surface, var(--ion-card-background, var(--ion-background-color, #fff)));
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.ok-prose {
|
|
248
|
+
color: var(--ok-text, var(--ion-text-color, #18181b));
|
|
249
|
+
line-height: 1.7;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.ok-prose h2 {
|
|
253
|
+
margin: 1.5rem 0 0.75rem;
|
|
254
|
+
font-family: var(--ok-font-display, var(--ok-font, system-ui, sans-serif));
|
|
255
|
+
font-size: 1.25rem;
|
|
256
|
+
font-weight: 600;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.ok-prose h3 {
|
|
260
|
+
margin: 1.25rem 0 0.5rem;
|
|
261
|
+
font-family: var(--ok-font-display, var(--ok-font, system-ui, sans-serif));
|
|
262
|
+
font-size: 1.1rem;
|
|
263
|
+
font-weight: 600;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.ok-prose p {
|
|
267
|
+
margin: 0.5rem 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.ok-prose :is(ul, ol) {
|
|
271
|
+
margin: 0.5rem 0;
|
|
272
|
+
padding-inline-start: 1.5rem;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.ok-prose ul {
|
|
276
|
+
list-style: disc;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.ok-prose ol {
|
|
280
|
+
list-style: decimal;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.ok-prose li {
|
|
284
|
+
margin: 0.25rem 0;
|
|
285
|
+
line-height: 1.6;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.ok-prose table {
|
|
289
|
+
width: 100%;
|
|
290
|
+
margin: 1rem 0;
|
|
291
|
+
border-collapse: collapse;
|
|
292
|
+
font-size: 0.9rem;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.ok-prose :is(th, td) {
|
|
296
|
+
padding: 0.5rem 0.75rem;
|
|
297
|
+
border: 1px solid color-mix(in oklab, var(--ok-text, var(--ion-text-color, #18181b)) 12%, transparent);
|
|
298
|
+
text-align: start;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.ok-prose th {
|
|
302
|
+
background: color-mix(in oklab, var(--ok-text, var(--ion-text-color, #18181b)) 5%, transparent);
|
|
303
|
+
font-weight: 600;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.ok-prose code {
|
|
307
|
+
padding: 0.15rem 0.4rem;
|
|
308
|
+
border-radius: 0.25rem;
|
|
309
|
+
background: color-mix(in oklab, var(--ok-text, var(--ion-text-color, #18181b)) 6%, transparent);
|
|
310
|
+
font-size: 0.875em;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.ok-prose pre {
|
|
314
|
+
overflow-x: auto;
|
|
315
|
+
margin: 1rem 0;
|
|
316
|
+
padding: 1rem;
|
|
317
|
+
border-radius: 0.5rem;
|
|
318
|
+
background: color-mix(in oklab, var(--ok-text, var(--ion-text-color, #18181b)) 6%, transparent);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.ok-prose pre code {
|
|
322
|
+
padding: 0;
|
|
323
|
+
background: none;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.ok-prose blockquote {
|
|
327
|
+
margin: 1rem 0;
|
|
328
|
+
padding: 0.5rem 1rem;
|
|
329
|
+
border-inline-start: 3px solid var(--ok-primary, var(--ion-color-primary, #1496d6));
|
|
330
|
+
border-radius: 0 0.5rem 0.5rem 0;
|
|
331
|
+
background: color-mix(in oklab, var(--ok-primary, var(--ion-color-primary, #1496d6)) 5%, transparent);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.ok-prose strong {
|
|
335
|
+
font-weight: 600;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.ok-prose hr {
|
|
339
|
+
margin: 1.5rem 0;
|
|
340
|
+
border: 0;
|
|
341
|
+
border-top: 1px solid color-mix(in oklab, var(--ok-text, var(--ion-text-color, #18181b)) 12%, transparent);
|
|
342
|
+
}
|
|
208
343
|
/* Tipografía editorial reutilizable fuera de los componentes. El display se
|
|
209
344
|
* reserva para el hero principal; page-title para cabeceras interiores e
|
|
210
345
|
* intro/body para el texto que las acompaña. */
|
|
@@ -244,7 +379,6 @@
|
|
|
244
379
|
font-size: var(--ok-type-body-size, 1rem);
|
|
245
380
|
line-height: var(--ok-type-body-leading, 1.6);
|
|
246
381
|
}
|
|
247
|
-
|
|
248
382
|
/* ===== Tabla apilable (.ok-table-stack) — patrón «no more tables» =====
|
|
249
383
|
*
|
|
250
384
|
* Solo CSS, sin web component (para CRUDs ricos usa <ok-data-table>; esto es
|
package/dist/ok-data-table.js
CHANGED
|
@@ -59,6 +59,42 @@ const DEFAULT_LABELS = {
|
|
|
59
59
|
recordSingular: "record",
|
|
60
60
|
recordPlural: "records"
|
|
61
61
|
};
|
|
62
|
+
const ES_LABELS = {
|
|
63
|
+
search: "Buscar…",
|
|
64
|
+
empty: "Sin resultados",
|
|
65
|
+
filters: "Filtros",
|
|
66
|
+
clear: "Limpiar",
|
|
67
|
+
apply: "Aplicar",
|
|
68
|
+
selected: "{n} seleccionados",
|
|
69
|
+
importCsv: "Importar CSV",
|
|
70
|
+
exportCsv: "Exportar CSV",
|
|
71
|
+
add: "Añadir",
|
|
72
|
+
moreActions: "Más acciones",
|
|
73
|
+
rowsPerPage: "Filas por página",
|
|
74
|
+
perPageShort: "{n} / pág.",
|
|
75
|
+
viewList: "Vista lista",
|
|
76
|
+
viewCards: "Vista tarjetas",
|
|
77
|
+
columnsVisible: "Columnas visibles",
|
|
78
|
+
columns: "Columnas",
|
|
79
|
+
actions: "Acciones",
|
|
80
|
+
close: "Cerrar",
|
|
81
|
+
newRecord: "Nuevo",
|
|
82
|
+
form: "Formulario",
|
|
83
|
+
filterPlaceholder: "Filtrar…",
|
|
84
|
+
from: "Desde",
|
|
85
|
+
to: "Hasta",
|
|
86
|
+
fromOf: "{label} desde",
|
|
87
|
+
toOf: "{label} hasta",
|
|
88
|
+
gte: "≥",
|
|
89
|
+
lte: "≤",
|
|
90
|
+
noValues: "Sin valores",
|
|
91
|
+
selectAll: "Seleccionar todo",
|
|
92
|
+
selectRow: "Seleccionar fila",
|
|
93
|
+
select: "Seleccionar",
|
|
94
|
+
showing: "Mostrando {from}–{to} de",
|
|
95
|
+
recordSingular: "registro",
|
|
96
|
+
recordPlural: "registros"
|
|
97
|
+
};
|
|
62
98
|
class OkDataTable extends LitElement {
|
|
63
99
|
constructor() {
|
|
64
100
|
super(...arguments);
|
|
@@ -100,6 +136,7 @@ class OkDataTable extends LitElement {
|
|
|
100
136
|
this.hiddenKeys = /* @__PURE__ */ new Set();
|
|
101
137
|
this.internalSelection = /* @__PURE__ */ new Set();
|
|
102
138
|
this.menuOpen = false;
|
|
139
|
+
this.onLocaleChanged = () => this.requestUpdate();
|
|
103
140
|
this.onSearch = (ev) => {
|
|
104
141
|
const value = ev.target.value ?? "";
|
|
105
142
|
if (this.serverSide) {
|
|
@@ -315,6 +352,13 @@ class OkDataTable extends LitElement {
|
|
|
315
352
|
.empty .empty-ic { display: grid; place-items: center; width: 3.25rem; height: 3.25rem; border-radius: 999px; background: var(--header-background); font-size: 26px; }
|
|
316
353
|
|
|
317
354
|
.actions { display: flex; gap: 0.25rem; justify-content: flex-end; }
|
|
355
|
+
/* Las acciones de fila son icon-only y de tamaño small en escritorio. En tablet/móvil se
|
|
356
|
+
* amplía el host completo (no solo el icono) para que el área táctil alcance 44×44 px. */
|
|
357
|
+
@media (pointer: coarse), (max-width: 834px) {
|
|
358
|
+
.actions ion-button { min-width: 44px; min-height: 44px; margin: 0; }
|
|
359
|
+
.toolbtn { width: 44px; height: 44px; }
|
|
360
|
+
.pager .nav ion-button { min-width: 44px; min-height: 44px; margin: 0; }
|
|
361
|
+
}
|
|
318
362
|
/* Spinner de acción en curso (loading): contenido dentro del ion-button small (Ionic lo fija
|
|
319
363
|
* a 28px en el :host, por eso width/height y no font-size). Cubre tabla y tarjetas: los
|
|
320
364
|
* botones de fila siempre van dentro de .actions. */
|
|
@@ -335,9 +379,22 @@ class OkDataTable extends LitElement {
|
|
|
335
379
|
ion-button { --box-shadow: none; }
|
|
336
380
|
`;
|
|
337
381
|
}
|
|
338
|
-
|
|
382
|
+
connectedCallback() {
|
|
383
|
+
super.connectedCallback();
|
|
384
|
+
if (typeof window !== "undefined") {
|
|
385
|
+
window.addEventListener("erplora:locale-changed", this.onLocaleChanged);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
disconnectedCallback() {
|
|
389
|
+
if (typeof window !== "undefined") {
|
|
390
|
+
window.removeEventListener("erplora:locale-changed", this.onLocaleChanged);
|
|
391
|
+
}
|
|
392
|
+
super.disconnectedCallback();
|
|
393
|
+
}
|
|
394
|
+
// ── i18n: idioma del documento ← overrides explícitos de `.labels` ─────────────────────────
|
|
339
395
|
get t() {
|
|
340
|
-
|
|
396
|
+
const lang = typeof document === "undefined" ? "en" : document.documentElement.lang.toLowerCase();
|
|
397
|
+
return { ...lang.startsWith("es") ? ES_LABELS : DEFAULT_LABELS, ...this.labels };
|
|
341
398
|
}
|
|
342
399
|
/** Placeholder efectivo del buscador (prop explícita → label i18n → default inglés). */
|
|
343
400
|
get effSearchPlaceholder() {
|
|
@@ -838,6 +895,8 @@ class OkDataTable extends LitElement {
|
|
|
838
895
|
color=${a.color ?? "medium"}
|
|
839
896
|
?disabled=${disabled}
|
|
840
897
|
aria-disabled=${disabled ? "true" : nothing}
|
|
898
|
+
aria-label=${a.label}
|
|
899
|
+
title=${a.label}
|
|
841
900
|
@click=${() => this.emit("rowAction", { actionId: a.id, row })}
|
|
842
901
|
>
|
|
843
902
|
${loading ? html`<ion-spinner slot="icon-only" name="dots"></ion-spinner>` : a.icon ? html`<ion-icon slot="icon-only" .icon=${okIcon(a.icon)}></ion-icon>` : a.label}
|
package/dist/ok-navbar.js
CHANGED
|
@@ -22,7 +22,7 @@ function adoptPanelSheet() {
|
|
|
22
22
|
const sheet = new CSSStyleSheet();
|
|
23
23
|
sheet.replaceSync(`
|
|
24
24
|
ion-modal.ok-navbar-modal {
|
|
25
|
-
--width: var(--ok-navbar-panel-width, min(
|
|
25
|
+
--width: var(--ok-navbar-panel-width, min(20rem, 86vw));
|
|
26
26
|
--height: 100%;
|
|
27
27
|
--border-radius: 0;
|
|
28
28
|
--background: var(--ok-surface, var(--ion-card-background, #ffffff));
|
|
@@ -39,17 +39,26 @@ function adoptPanelSheet() {
|
|
|
39
39
|
overflow-y: auto;
|
|
40
40
|
display: flex;
|
|
41
41
|
flex-direction: column;
|
|
42
|
-
padding: 0.5rem var(--ok-spacing, var(--ion-padding,
|
|
42
|
+
padding: 0.5rem var(--ok-spacing, var(--ion-padding, 1rem)) max(var(--ok-spacing, var(--ion-padding, 1rem)), env(safe-area-inset-bottom));
|
|
43
43
|
background: var(--ok-surface, var(--ion-card-background, #ffffff));
|
|
44
44
|
color: var(--ok-text, var(--ion-text-color, #1c1b17));
|
|
45
45
|
font-family: var(--ok-font, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif);
|
|
46
46
|
}
|
|
47
|
-
.ok-navbar-modal .ok-navbar-panel-head {
|
|
47
|
+
.ok-navbar-modal .ok-navbar-panel-head {
|
|
48
|
+
display: flex;
|
|
49
|
+
justify-content: flex-end;
|
|
50
|
+
min-height: 2.75rem;
|
|
51
|
+
}
|
|
48
52
|
.ok-navbar-modal .ok-navbar-close {
|
|
49
53
|
background: none;
|
|
50
54
|
border: 0;
|
|
51
55
|
cursor: pointer;
|
|
52
|
-
|
|
56
|
+
width: 2.75rem;
|
|
57
|
+
height: 2.75rem;
|
|
58
|
+
padding: 0;
|
|
59
|
+
display: grid;
|
|
60
|
+
place-items: center;
|
|
61
|
+
border-radius: var(--ok-radius-md, var(--ion-border-radius, 0.5rem));
|
|
53
62
|
color: inherit;
|
|
54
63
|
}
|
|
55
64
|
.ok-navbar-modal .ok-navbar-close span { display: block; width: 22px; height: 2px; position: relative; }
|
|
@@ -68,11 +77,13 @@ function adoptPanelSheet() {
|
|
|
68
77
|
.ok-navbar-modal .ok-navbar-close span::after { transform: rotate(-45deg); }
|
|
69
78
|
.ok-navbar-modal .ok-navbar-links { display: flex; flex-direction: column; }
|
|
70
79
|
.ok-navbar-modal .ok-navbar-links a {
|
|
71
|
-
|
|
72
|
-
|
|
80
|
+
min-height: 3.25rem;
|
|
81
|
+
display: flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
padding-inline: 0.25rem;
|
|
73
84
|
color: inherit;
|
|
74
85
|
text-decoration: none;
|
|
75
|
-
font-size:
|
|
86
|
+
font-size: 1rem;
|
|
76
87
|
border-top: 1px solid var(--ok-border-soft, rgba(var(--ion-text-color-rgb, 24, 24, 27), 0.07));
|
|
77
88
|
}
|
|
78
89
|
.ok-navbar-modal .ok-navbar-links a:first-child { border-top: 0; }
|
|
@@ -82,11 +93,15 @@ function adoptPanelSheet() {
|
|
|
82
93
|
flex-direction: column;
|
|
83
94
|
align-items: stretch;
|
|
84
95
|
gap: 0.6rem;
|
|
85
|
-
margin-top:
|
|
96
|
+
margin-top: auto;
|
|
86
97
|
padding-top: 1.25rem;
|
|
87
98
|
border-top: 1px solid var(--ok-border, rgba(var(--ion-text-color-rgb, 24, 24, 27), 0.12));
|
|
88
99
|
}
|
|
89
|
-
.ok-navbar-modal .ok-navbar-actions ion-button {
|
|
100
|
+
.ok-navbar-modal .ok-navbar-actions ion-button {
|
|
101
|
+
width: 100%;
|
|
102
|
+
min-height: 2.75rem;
|
|
103
|
+
margin: 0;
|
|
104
|
+
}
|
|
90
105
|
`);
|
|
91
106
|
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
|
|
92
107
|
}
|
|
@@ -162,11 +177,15 @@ class OkNavbar extends LitElement {
|
|
|
162
177
|
}
|
|
163
178
|
|
|
164
179
|
.burger {
|
|
165
|
-
|
|
180
|
+
width: 2.75rem;
|
|
181
|
+
height: 2.75rem;
|
|
182
|
+
display: grid;
|
|
183
|
+
place-items: center;
|
|
166
184
|
background: none;
|
|
167
185
|
border: 0;
|
|
168
186
|
cursor: pointer;
|
|
169
|
-
padding: 0
|
|
187
|
+
padding: 0;
|
|
188
|
+
border-radius: var(--ok-radius-md, var(--ion-border-radius, 0.5rem));
|
|
170
189
|
color: var(--color);
|
|
171
190
|
/* Micro-interacción: feedback sutil al presionar el burger. */
|
|
172
191
|
transition: background-color var(--ok-transition, 150ms ease), color var(--ok-transition, 150ms ease), border-color var(--ok-transition, 150ms ease), box-shadow var(--ok-transition, 150ms ease), transform 120ms ease;
|
|
@@ -182,6 +201,9 @@ class OkNavbar extends LitElement {
|
|
|
182
201
|
.burger span::before, .burger span::after { content: ''; position: absolute; left: 0; width: 22px; height: 2px; background: currentColor; border-radius: 2px; }
|
|
183
202
|
.burger span::before { top: -7px; }
|
|
184
203
|
.burger span::after { top: 7px; }
|
|
204
|
+
@media (max-width: 800px) {
|
|
205
|
+
.bar { padding-block: 0.25rem; }
|
|
206
|
+
}
|
|
185
207
|
`;
|
|
186
208
|
}
|
|
187
209
|
get t() {
|