@erplora/outfitkit 0.1.1
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/LICENSE +21 -0
- package/README.md +457 -0
- package/dist/base/anchor.d.ts +13 -0
- package/dist/base/define.d.ts +1 -0
- package/dist/base/relay.d.ts +1 -0
- package/dist/cdn.d.ts +96 -0
- package/dist/components/ok-app-launcher/ok-app-launcher.d.ts +57 -0
- package/dist/components/ok-audio/ok-audio.d.ts +45 -0
- package/dist/components/ok-avatar/ok-avatar.d.ts +36 -0
- package/dist/components/ok-avatar-group/ok-avatar-group.d.ts +38 -0
- package/dist/components/ok-bar-list/ok-bar-list.d.ts +36 -0
- package/dist/components/ok-bento/ok-bento.d.ts +17 -0
- package/dist/components/ok-bento-item/ok-bento-item.d.ts +34 -0
- package/dist/components/ok-calculator/ok-calculator.d.ts +46 -0
- package/dist/components/ok-calendar/ok-calendar.d.ts +63 -0
- package/dist/components/ok-carousel/ok-carousel.d.ts +48 -0
- package/dist/components/ok-chart/ok-chart.d.ts +55 -0
- package/dist/components/ok-chat/ok-chat.d.ts +54 -0
- package/dist/components/ok-coachmark/ok-coachmark.d.ts +69 -0
- package/dist/components/ok-code/ok-code.d.ts +28 -0
- package/dist/components/ok-color-picker/ok-color-picker.d.ts +63 -0
- package/dist/components/ok-combo/ok-combo.d.ts +46 -0
- package/dist/components/ok-command-palette/ok-command-palette.d.ts +72 -0
- package/dist/components/ok-contact-form/ok-contact-form.d.ts +54 -0
- package/dist/components/ok-cropper/ok-cropper.d.ts +60 -0
- package/dist/components/ok-cta-band/ok-cta-band.d.ts +18 -0
- package/dist/components/ok-currency/ok-currency.d.ts +31 -0
- package/dist/components/ok-data-table/ok-data-table.d.ts +312 -0
- package/dist/components/ok-date-picker/ok-date-picker.d.ts +81 -0
- package/dist/components/ok-detail-list/ok-detail-list.d.ts +30 -0
- package/dist/components/ok-diff/ok-diff.d.ts +38 -0
- package/dist/components/ok-donut/ok-donut.d.ts +38 -0
- package/dist/components/ok-drawer/ok-drawer.d.ts +56 -0
- package/dist/components/ok-dropzone/ok-dropzone.d.ts +48 -0
- package/dist/components/ok-empty-state/ok-empty-state.d.ts +16 -0
- package/dist/components/ok-error-page/ok-error-page.d.ts +77 -0
- package/dist/components/ok-event-card/ok-event-card.d.ts +56 -0
- package/dist/components/ok-feature-card/ok-feature-card.d.ts +23 -0
- package/dist/components/ok-file-item/ok-file-item.d.ts +31 -0
- package/dist/components/ok-file-manager/ok-file-manager.d.ts +145 -0
- package/dist/components/ok-footer/ok-footer.d.ts +10 -0
- package/dist/components/ok-funnel/ok-funnel.d.ts +31 -0
- package/dist/components/ok-gallery/ok-gallery.d.ts +34 -0
- package/dist/components/ok-gauge/ok-gauge.d.ts +49 -0
- package/dist/components/ok-heatmap/ok-heatmap.d.ts +45 -0
- package/dist/components/ok-hero/ok-hero.d.ts +10 -0
- package/dist/components/ok-hover-card/ok-hover-card.d.ts +76 -0
- package/dist/components/ok-icon-tile/ok-icon-tile.d.ts +24 -0
- package/dist/components/ok-image/ok-image.d.ts +56 -0
- package/dist/components/ok-inline-feedback/ok-inline-feedback.d.ts +33 -0
- package/dist/components/ok-invoice/ok-invoice.d.ts +137 -0
- package/dist/components/ok-json-viewer/ok-json-viewer.d.ts +31 -0
- package/dist/components/ok-kanban/ok-kanban.d.ts +56 -0
- package/dist/components/ok-kbd/ok-kbd.d.ts +21 -0
- package/dist/components/ok-keyboard/ok-keyboard.d.ts +35 -0
- package/dist/components/ok-kpi/ok-kpi.d.ts +24 -0
- package/dist/components/ok-language-select/ok-language-select.d.ts +31 -0
- package/dist/components/ok-lightbox/ok-lightbox.d.ts +59 -0
- package/dist/components/ok-logo-cloud/ok-logo-cloud.d.ts +14 -0
- package/dist/components/ok-loyalty-card/ok-loyalty-card.d.ts +35 -0
- package/dist/components/ok-mail/ok-mail.d.ts +117 -0
- package/dist/components/ok-menu/ok-menu.d.ts +75 -0
- package/dist/components/ok-menubar/ok-menubar.d.ts +75 -0
- package/dist/components/ok-navbar/ok-navbar.d.ts +42 -0
- package/dist/components/ok-notification-center/ok-notification-center.d.ts +79 -0
- package/dist/components/ok-org-chart/ok-org-chart.d.ts +67 -0
- package/dist/components/ok-otp/ok-otp.d.ts +31 -0
- package/dist/components/ok-page-header/ok-page-header.d.ts +23 -0
- package/dist/components/ok-pagination/ok-pagination.d.ts +44 -0
- package/dist/components/ok-pdf/ok-pdf.d.ts +32 -0
- package/dist/components/ok-phone/ok-phone.d.ts +48 -0
- package/dist/components/ok-pinpad/ok-pinpad.d.ts +29 -0
- package/dist/components/ok-pricing-card/ok-pricing-card.d.ts +31 -0
- package/dist/components/ok-product-card/ok-product-card.d.ts +25 -0
- package/dist/components/ok-qr/ok-qr.d.ts +24 -0
- package/dist/components/ok-qty-stepper/ok-qty-stepper.d.ts +35 -0
- package/dist/components/ok-range-dual/ok-range-dual.d.ts +38 -0
- package/dist/components/ok-rating/ok-rating.d.ts +33 -0
- package/dist/components/ok-receipt/ok-receipt.d.ts +103 -0
- package/dist/components/ok-reveal/ok-reveal.d.ts +21 -0
- package/dist/components/ok-rich-text/ok-rich-text.d.ts +46 -0
- package/dist/components/ok-scheduler/ok-scheduler.d.ts +74 -0
- package/dist/components/ok-select-card/ok-select-card.d.ts +37 -0
- package/dist/components/ok-signature/ok-signature.d.ts +55 -0
- package/dist/components/ok-skeleton/ok-skeleton.d.ts +40 -0
- package/dist/components/ok-sparkline/ok-sparkline.d.ts +27 -0
- package/dist/components/ok-split-button/ok-split-button.d.ts +49 -0
- package/dist/components/ok-splitter/ok-splitter.d.ts +36 -0
- package/dist/components/ok-stat/ok-stat.d.ts +16 -0
- package/dist/components/ok-status-dot/ok-status-dot.d.ts +24 -0
- package/dist/components/ok-status-pill/ok-status-pill.d.ts +22 -0
- package/dist/components/ok-stepper/ok-stepper.d.ts +33 -0
- package/dist/components/ok-store/ok-store.d.ts +33 -0
- package/dist/components/ok-tag-input/ok-tag-input.d.ts +39 -0
- package/dist/components/ok-testimonial/ok-testimonial.d.ts +21 -0
- package/dist/components/ok-time-picker/ok-time-picker.d.ts +50 -0
- package/dist/components/ok-timeline/ok-timeline.d.ts +33 -0
- package/dist/components/ok-tree/ok-tree.d.ts +46 -0
- package/dist/components/ok-video/ok-video.d.ts +49 -0
- package/dist/components/ok-widget-board/ok-widget-board.d.ts +71 -0
- package/dist/components/ok-wizard/ok-wizard.d.ts +30 -0
- package/dist/define.js +8 -0
- package/dist/erplora.css +112 -0
- package/dist/index.d.ts +158 -0
- package/dist/index.js +197 -0
- package/dist/layout.css +338 -0
- package/dist/ok-app-launcher.js +396 -0
- package/dist/ok-audio.js +308 -0
- package/dist/ok-avatar-group.js +158 -0
- package/dist/ok-avatar.js +179 -0
- package/dist/ok-bar-list.js +189 -0
- package/dist/ok-bento-item.js +168 -0
- package/dist/ok-bento.js +63 -0
- package/dist/ok-calculator.js +406 -0
- package/dist/ok-calendar.js +541 -0
- package/dist/ok-carousel.js +352 -0
- package/dist/ok-chart.js +325 -0
- package/dist/ok-chat.js +320 -0
- package/dist/ok-coachmark.js +500 -0
- package/dist/ok-code.js +190 -0
- package/dist/ok-color-picker.js +569 -0
- package/dist/ok-combo.js +294 -0
- package/dist/ok-command-palette.js +448 -0
- package/dist/ok-contact-form.js +288 -0
- package/dist/ok-cropper.js +404 -0
- package/dist/ok-cta-band.js +134 -0
- package/dist/ok-currency.js +172 -0
- package/dist/ok-data-table.js +1281 -0
- package/dist/ok-date-picker.js +736 -0
- package/dist/ok-detail-list.js +156 -0
- package/dist/ok-diff.js +200 -0
- package/dist/ok-donut.js +280 -0
- package/dist/ok-drawer.js +357 -0
- package/dist/ok-dropzone.js +376 -0
- package/dist/ok-empty-state.js +104 -0
- package/dist/ok-error-page.js +547 -0
- package/dist/ok-event-card.js +384 -0
- package/dist/ok-feature-card.js +152 -0
- package/dist/ok-file-item.js +259 -0
- package/dist/ok-file-manager.js +1116 -0
- package/dist/ok-footer.js +67 -0
- package/dist/ok-funnel.js +181 -0
- package/dist/ok-gallery.js +293 -0
- package/dist/ok-gauge.js +385 -0
- package/dist/ok-heatmap.js +268 -0
- package/dist/ok-hero.js +43 -0
- package/dist/ok-hover-card.js +480 -0
- package/dist/ok-icon-tile.js +123 -0
- package/dist/ok-image.js +471 -0
- package/dist/ok-inline-feedback.js +221 -0
- package/dist/ok-invoice.js +229 -0
- package/dist/ok-json-viewer.js +330 -0
- package/dist/ok-kanban.js +427 -0
- package/dist/ok-kbd.js +159 -0
- package/dist/ok-keyboard.js +402 -0
- package/dist/ok-kpi.js +147 -0
- package/dist/ok-language-select.js +188 -0
- package/dist/ok-lightbox.js +490 -0
- package/dist/ok-logo-cloud.js +92 -0
- package/dist/ok-loyalty-card.js +353 -0
- package/dist/ok-mail.js +562 -0
- package/dist/ok-menu.js +529 -0
- package/dist/ok-menubar.js +628 -0
- package/dist/ok-navbar.js +306 -0
- package/dist/ok-notification-center.js +545 -0
- package/dist/ok-org-chart.js +619 -0
- package/dist/ok-otp.js +199 -0
- package/dist/ok-page-header.js +202 -0
- package/dist/ok-pagination.js +366 -0
- package/dist/ok-pdf.js +160 -0
- package/dist/ok-phone.js +225 -0
- package/dist/ok-pinpad.js +171 -0
- package/dist/ok-pricing-card.js +184 -0
- package/dist/ok-product-card.js +178 -0
- package/dist/ok-qr.js +652 -0
- package/dist/ok-qty-stepper.js +212 -0
- package/dist/ok-range-dual.js +280 -0
- package/dist/ok-rating.js +199 -0
- package/dist/ok-receipt.js +183 -0
- package/dist/ok-reveal.js +94 -0
- package/dist/ok-rich-text.js +538 -0
- package/dist/ok-scheduler.js +518 -0
- package/dist/ok-select-card.js +231 -0
- package/dist/ok-signature.js +267 -0
- package/dist/ok-skeleton.js +345 -0
- package/dist/ok-sparkline.js +150 -0
- package/dist/ok-split-button.js +251 -0
- package/dist/ok-splitter.js +289 -0
- package/dist/ok-stat.js +77 -0
- package/dist/ok-status-dot.js +163 -0
- package/dist/ok-status-pill.js +123 -0
- package/dist/ok-stepper.js +299 -0
- package/dist/ok-store.js +83 -0
- package/dist/ok-tag-input.js +358 -0
- package/dist/ok-testimonial.js +136 -0
- package/dist/ok-time-picker.js +472 -0
- package/dist/ok-timeline.js +251 -0
- package/dist/ok-tree.js +266 -0
- package/dist/ok-video.js +362 -0
- package/dist/ok-widget-board.js +265 -0
- package/dist/ok-wizard.js +153 -0
- package/dist/outfitkit.js +96 -0
- package/dist/shared/anchor.js +14 -0
- package/dist/store/controller.d.ts +17 -0
- package/dist/store/idb.d.ts +16 -0
- package/dist/store/store.d.ts +39 -0
- package/dist/store-controller.js +31 -0
- package/dist/store.js +182 -0
- package/dist/theme.example.css +70 -0
- package/package.json +147 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OutfitKit contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
# OutfitKit (`@erplora/outfitkit`)
|
|
2
|
+
|
|
3
|
+
**OutfitKit** es una librería de **Web Components (Lit)** que **CONSTRUYE lo que Ionic NO tiene**,
|
|
4
|
+
sobre primitivos de Ionic.
|
|
5
|
+
|
|
6
|
+
> **Ionic es la base.** Para botones, inputs, listas, modales, toolbars, layout/app-shell, tabs,
|
|
7
|
+
> etc. usas **Ionic directo** (`ion-*`): OutfitKit **no** los envuelve. OutfitKit solo cubre los
|
|
8
|
+
> **huecos** —componentes que Ionic no trae (árbol, tabla rica, calendario, kanban, kpi, charts,
|
|
9
|
+
> inputs especializados…)— y el **chrome web/marketing** que Ionic (pensado para apps) no cubre.
|
|
10
|
+
|
|
11
|
+
Esto **sustituye** el enfoque anterior de "wrapper completo de Ionic" (`ok-button`/`ok-input`/…),
|
|
12
|
+
que se retiró por redundante.
|
|
13
|
+
|
|
14
|
+
- **Construye SOBRE Ionic** — por dentro reusa `ion-*` nativos que registra el host; OutfitKit no
|
|
15
|
+
los importa por componente.
|
|
16
|
+
- **Usable en cualquier sitio** — plantillas **Django**, apps **Lit/Vue**, o el **Hub** de ERPlora.
|
|
17
|
+
Son custom elements estándar: van donde vaya HTML.
|
|
18
|
+
- **Distribución dual** — **npm** (`@erplora/outfitkit`) con imports individuales por componente, o
|
|
19
|
+
**CDN** (bundle único `outfitkit.js`).
|
|
20
|
+
- **CSP-safe** — el output no contiene `eval` / `new Function`; funciona bajo `script-src 'self'`.
|
|
21
|
+
- **Tema por tokens `--ok-*`** (espejo de `--ion-*`), claro/oscuro sin esfuerzo.
|
|
22
|
+
|
|
23
|
+
Showcase en vivo: **https://erplora.github.io/outfitkit/**
|
|
24
|
+
Convenciones de desarrollo: [`docs/CONVENTIONS.md`](docs/CONVENTIONS.md) ·
|
|
25
|
+
Backlog de componentes: [`docs/PLAN-COMPONENTES.md`](docs/PLAN-COMPONENTES.md)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Instalación
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
npm i @erplora/outfitkit
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
OutfitKit declara **peer dependencies de entorno**: el host debe cargar **`@ionic/core`** (los
|
|
36
|
+
componentes reusan `ion-*` por dentro, que el host registra una sola vez) y **`lit`** (queda
|
|
37
|
+
external en los bundles para compartir una única copia). Instálalas en tu app:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
npm i @ionic/core lit
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Import individual (recomendado en apps con bundler)
|
|
44
|
+
|
|
45
|
+
Cada componente es un entry independiente con *side-effect* de registro (`define('ok-x', …)`):
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
import '@erplora/outfitkit/ok-data-table';
|
|
49
|
+
import '@erplora/outfitkit/ok-tree';
|
|
50
|
+
// ...solo lo que uses → menor peso
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Las clases y tipos también se re-exportan desde el barrel:
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
import { OkDataTable } from '@erplora/outfitkit';
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Bundle (registra todo de golpe)
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import '@erplora/outfitkit/cdn'; // auto-registra todos los ok-*
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Uso por CDN
|
|
66
|
+
|
|
67
|
+
El bundle `outfitkit.js` deja `lit` external, así que necesitas un **import-map** para resolver
|
|
68
|
+
`lit` (y cargar Ionic aparte):
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css" />
|
|
72
|
+
<script type="importmap">
|
|
73
|
+
{
|
|
74
|
+
"imports": {
|
|
75
|
+
"lit": "https://cdn.jsdelivr.net/npm/lit@3/index.js",
|
|
76
|
+
"lit/": "https://cdn.jsdelivr.net/npm/lit@3/"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
</script>
|
|
80
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"></script>
|
|
81
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@erplora/outfitkit/dist/outfitkit.js"></script>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> Nota: un import-map en línea choca con una CSP `script-src 'self'`. Bajo CSP estricta (Cloud/Hub
|
|
85
|
+
> de ERPlora) usa **imports individuales con un bundler** que hornee `lit` y los `ok-*` en el dist
|
|
86
|
+
> same-origin; el CDN + import-map queda para entornos sin CSP estricta.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Inventario de componentes
|
|
91
|
+
|
|
92
|
+
95 web components rellena-huecos (todos registran su tag `ok-*` vía `define()`). Abajo el qué-hace y
|
|
93
|
+
los **eventos `ok-*`** que emite cada uno (`—` = presentacional, sin eventos). La **referencia viva
|
|
94
|
+
de props/slots** es el [showcase](https://erplora.github.io/outfitkit/).
|
|
95
|
+
|
|
96
|
+
### Datos y tablas
|
|
97
|
+
|
|
98
|
+
| Componente | Qué hace | Eventos clave |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| `ok-data-table` | Tabla rica: lista/tarjetas, búsqueda, filtros, orden, paginación (server-side), selección, columnas, vistas, CSV import/export. Componente central, API congelada. | `pageChange`, `sortChange`, `searchChange`, `filterChange`, `selectionChange`, `rowAction`, `primaryAction`, `menuAction`, `columnsChange`, `csvImport`, `csvExport` |
|
|
101
|
+
| `ok-tree` | Árbol expandible recursivo por datos, con líneas guía y selección. | `ok-toggle`, `ok-select` |
|
|
102
|
+
| `ok-detail-list` | Description list (`dl`) para fichas: pares label/value alineados, 1–2 columnas. | — |
|
|
103
|
+
| `ok-bar-list` | Ranking de barras horizontales animadas con formateo de valores. | — |
|
|
104
|
+
| `ok-sparkline` | Mini-gráfico inline (línea/barras) en SVG, sin ejes, autoescalado. | — |
|
|
105
|
+
| `ok-code` | Visor de código monospace con etiqueta de lenguaje y botón copiar. | `ok-copy` |
|
|
106
|
+
| `ok-json-viewer` | Árbol JSON tipado colapsable, coloreado por tipo, con guías de indentación. | `ok-toggle` |
|
|
107
|
+
| `ok-diff` | Visor de diff unificado línea a línea con numeración dual y glifos +/−. | — |
|
|
108
|
+
|
|
109
|
+
### Dashboard y charts
|
|
110
|
+
|
|
111
|
+
| Componente | Qué hace | Eventos clave |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `ok-kpi` | Tarjeta KPI: label, valor grande, delta coloreado y flecha de tendencia. | — |
|
|
114
|
+
| `ok-stat` | Métrica inline compacta (label + value + hint) para filas de stats. | — |
|
|
115
|
+
| `ok-widget-board` | Panel de widgets configurable (activar/desactivar/reordenar), presets, persistencia `localStorage`. | `ok-change` |
|
|
116
|
+
| `ok-gauge` | Medidor arc / ring / bullet animado con thresholds coloreados. | — |
|
|
117
|
+
| `ok-chart` | Gráfico SVG inline (línea/área/barras) sin librerías externas. | — |
|
|
118
|
+
| `ok-donut` | Donut/pie proporcional con leyenda opcional. | — |
|
|
119
|
+
| `ok-heatmap` | Heatmap de calendario (estilo GitHub) o anual, con cuantiles e intensidad. | — |
|
|
120
|
+
| `ok-funnel` | Embudo de conversión apilado con % y conteo por paso. | — |
|
|
121
|
+
|
|
122
|
+
### Feedback y estado de UI
|
|
123
|
+
|
|
124
|
+
| Componente | Qué hace | Eventos clave |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| `ok-inline-feedback` | Banner/callout persistente en flujo (no efímero), tonal, con acciones y cierre. | `ok-dismiss` |
|
|
127
|
+
| `ok-empty-state` | Estado vacío centrado: icono + título + mensaje + acción. | — |
|
|
128
|
+
| `ok-error-page` | Plantilla full-screen para errores HTTP (403/404/500), retry con cuenta atrás, modo bootstrap con checklist. | `ok-retry`, `ok-shortcut` |
|
|
129
|
+
| `ok-status-pill` | Pill de estado con fondo tonal suave + icono/punto (celdas de tabla). | — |
|
|
130
|
+
| `ok-status-dot` | Punto de presencia coloreado con pulso opcional. | — |
|
|
131
|
+
| `ok-skeleton` | Placeholders de carga (shimmer) con variantes y presets (card/table/chart). | — |
|
|
132
|
+
| `ok-coachmark` | Tour guiado con spotlight, bubble anclado y navegación por teclado. | `ok-step`, `ok-next`, `ok-prev`, `ok-finish`, `ok-skip` |
|
|
133
|
+
| `ok-hover-card` | Popover de previsualización (avatar/título/stats/acciones) anclada a hover/focus. | `ok-action`, `ok-open` |
|
|
134
|
+
|
|
135
|
+
### Flujo de tareas
|
|
136
|
+
|
|
137
|
+
| Componente | Qué hace | Eventos clave |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| `ok-stepper` | Indicador de pasos (círculos numerados conectados), horizontal/compacto. | `ok-step-select` |
|
|
140
|
+
| `ok-wizard` | Asistente multi-paso: compone `ok-stepper` + slots + barra Atrás/Siguiente/Finalizar. | `ok-step-change`, `ok-finish` |
|
|
141
|
+
| `ok-pagination` | Paginador numerado con prev/next, elipsis y selector de filas por página. | `ok-page-change`, `ok-page-size-change` |
|
|
142
|
+
| `ok-command-palette` | Paleta de comandos Cmd+K con búsqueda y agrupación. | `ok-select`, `ok-open` |
|
|
143
|
+
| `ok-qty-stepper` | Selector de cantidad −/+ con campo numérico y clamp. | `ok-change` |
|
|
144
|
+
|
|
145
|
+
### Calendario y planificación
|
|
146
|
+
|
|
147
|
+
| Componente | Qué hace | Eventos clave |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `ok-calendar` | Calendario mes/agenda con eventos como chips y presets. | `ok-date-select`, `ok-event-click`, `ok-view-change`, `ok-nav` |
|
|
150
|
+
| `ok-scheduler` | Timeline de recursos/turnos (filas × franjas horarias) con eventos posicionados. | `ok-event-click`, `ok-slot-click`, `ok-nav` |
|
|
151
|
+
| `ok-kanban` | Tablero Kanban con HTML5 drag&drop (sin libs), columnas y tarjetas reordenables. | `ok-card-move`, `ok-card-click` |
|
|
152
|
+
| `ok-timeline` | Línea de tiempo vertical con estados (done/current/pending), modo alternado. | `ok-item-click` |
|
|
153
|
+
|
|
154
|
+
### Inputs (los que Ionic no trae)
|
|
155
|
+
|
|
156
|
+
| Componente | Qué hace | Eventos clave |
|
|
157
|
+
|---|---|---|
|
|
158
|
+
| `ok-combo` | Combobox con búsqueda filtrada y navegación por teclado. | `ok-input`, `ok-change` |
|
|
159
|
+
| `ok-tag-input` | Entrada de tags (chips) con Enter/coma, Backspace y sugerencias. | `ok-change` |
|
|
160
|
+
| `ok-rating` | Estrellas con hover-preview, medias estrellas y readonly. | `ok-change` |
|
|
161
|
+
| `ok-otp` | Código OTP/2FA con N casillas, auto-avance y pegado. | `ok-change`, `ok-complete` |
|
|
162
|
+
| `ok-pinpad` | Teclado numérico PIN con display enmascarable. | `ok-input`, `ok-complete` |
|
|
163
|
+
| `ok-currency` | Input monetario con máscara (miles/decimales/símbolo `Intl`). | `ok-change` |
|
|
164
|
+
| `ok-phone` | Teléfono con prefijo de país (bandera + dial) y número (E.164). | `ok-change` |
|
|
165
|
+
| `ok-dropzone` | Subida drag&drop + click con validación de tipo/tamaño. | `ok-change`, `ok-error` |
|
|
166
|
+
| `ok-date-picker` | Campo fecha + popover calendario, single/range, chips de preset. | `ok-change` |
|
|
167
|
+
| `ok-time-picker` | Pastilla HH:MM + popover de listas (horas/minutos/AM-PM), canónico 24h. | `ok-change` |
|
|
168
|
+
| `ok-range-dual` | Slider min-max de doble thumb con readout. | `ok-change` |
|
|
169
|
+
| `ok-color-picker` | Selector de color (SV + hue + hex + presets). | `ok-change`, `ok-open` |
|
|
170
|
+
| `ok-rich-text` | Editor WYSIWYG con toolbar y contador de palabras. | `ok-input` |
|
|
171
|
+
| `ok-signature` | Pad de firma sobre canvas con limpiar/exportar. | `ok-change`, `ok-clear` |
|
|
172
|
+
| `ok-calculator` | Calculadora con teclado 4×4 y máquina de estados. | `ok-input`, `ok-change` |
|
|
173
|
+
| `ok-keyboard` | Teclado virtual QWERTY/numérico para kiosco/táctil. | `ok-input`, `ok-key`, `ok-enter` |
|
|
174
|
+
| `ok-select-card` | Tarjeta seleccionable (checkbox/radio) con borde de marca al marcar. | `ok-change` |
|
|
175
|
+
|
|
176
|
+
### Acciones y menús
|
|
177
|
+
|
|
178
|
+
| Componente | Qué hace | Eventos clave |
|
|
179
|
+
|---|---|---|
|
|
180
|
+
| `ok-app-launcher` | Botón "apps" estilo Google (rejilla 3×3 en hoja de acción). | `ok-app-select`, `ok-open` |
|
|
181
|
+
| `ok-split-button` | Botón principal pegado a un caret que abre menú. | `ok-main`, `ok-select`, `ok-open` |
|
|
182
|
+
| `ok-menu` | Menú desplegable/contextual con submenús, checkbox/radio, divisores. | `ok-select`, `ok-open` |
|
|
183
|
+
| `ok-menubar` | Barra de menús de app (Archivo/Editar/Ver) con dropdowns. | `ok-select`, `ok-open` |
|
|
184
|
+
| `ok-drawer` | Panel lateral deslizante (slide-over) modal con focus-trap y cierre por ESC/scrim. | `ok-open`, `ok-close` |
|
|
185
|
+
|
|
186
|
+
### Media y archivos
|
|
187
|
+
|
|
188
|
+
| Componente | Qué hace | Eventos clave |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| `ok-image` | Imagen lazy con skeleton, fade-in, caption y zoom (lupa/lightbox). | `ok-open` |
|
|
191
|
+
| `ok-gallery` | Grid de imágenes seleccionables con caption hover y lightbox opcional. | `ok-select`, `ok-open` |
|
|
192
|
+
| `ok-lightbox` | Visor de medios full-screen con filmstrip, zoom y teclado. | `ok-close`, `ok-index` |
|
|
193
|
+
| `ok-cropper` | Recortador de imagen con rect arrastrable/redimensionable y rule-of-thirds. | `ok-crop`, `ok-cancel` |
|
|
194
|
+
| `ok-audio` | Reproductor de audio con controles propios. | `ok-play`, `ok-pause`, `ok-ended` |
|
|
195
|
+
| `ok-video` | Reproductor de vídeo con controles propios, 16:9 responsive. | `ok-play`, `ok-pause`, `ok-ended` |
|
|
196
|
+
| `ok-pdf` | Visor de PDF nativo del navegador con fallback de descarga. | — |
|
|
197
|
+
| `ok-qr` | Generador de QR en JS puro (Reed-Solomon, v1–40, 4 niveles EC). | — |
|
|
198
|
+
| `ok-carousel` | Carrusel con swipe, flechas, puntos y autoplay. | `ok-change` |
|
|
199
|
+
| `ok-avatar` | Avatar de iniciales/imagen con tamaños, formas y tono por hash. | — |
|
|
200
|
+
| `ok-avatar-group` | Pila de avatares solapados con overflow "+N". | — |
|
|
201
|
+
| `ok-file-item` | Fila de archivo/adjunto con badge, meta, barra de progreso y quitar. | `ok-remove` |
|
|
202
|
+
| `ok-file-manager` | Gestor de archivos backend-agnóstico (árbol + toolbar + grid/lista + cuota). | `ok-navigate`, `ok-open`, `ok-download`, `ok-delete`, `ok-create-folder`, `ok-search`, `ok-upload`, `ok-view-change` |
|
|
203
|
+
| `ok-icon-tile` | Pastilla cuadrada coloreada con icono (leading icon para cabeceras). | — |
|
|
204
|
+
| `ok-splitter` | Split-pane redimensionable (h/v) con divisor arrastrable. | `ok-resize` |
|
|
205
|
+
|
|
206
|
+
### Comunicación
|
|
207
|
+
|
|
208
|
+
| Componente | Qué hace | Eventos clave |
|
|
209
|
+
|---|---|---|
|
|
210
|
+
| `ok-chat` | Hilo de mensajes con compositor opcional (Enter envía). | `ok-send` |
|
|
211
|
+
| `ok-mail` | Cliente de correo (carpetas + lista filtrada + panel de lectura). | `ok-folder-select`, `ok-message-select`, `ok-reply`, `ok-archive`, `ok-delete`, `ok-compose`, … |
|
|
212
|
+
| `ok-notification-center` | Bandeja de notificaciones (drawer) con filtros y "marcar todas leídas". | `ok-read`, `ok-read-all`, `ok-filter`, `ok-close`, `ok-open` |
|
|
213
|
+
|
|
214
|
+
### Documentos y tarjetas de negocio
|
|
215
|
+
|
|
216
|
+
| Componente | Qué hace | Eventos clave |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| `ok-receipt` | Tiquet de venta formato impresora térmica 80mm (líneas, totales, impuestos, QR). | — |
|
|
219
|
+
| `ok-invoice` | Factura fiscal A4 (emisor/receptor/líneas/totales/pago/QR VeriFactu), JSON-in. | — |
|
|
220
|
+
| `ok-loyalty-card` | Tarjeta de fidelización estilo tarjeta de crédito con chip EMV y tier. | — |
|
|
221
|
+
| `ok-event-card` | Tarjeta de evento (bloque fecha + hora/lugar + avatares), pulso en "now". | — |
|
|
222
|
+
| `ok-kbd` | Chips keycap con glifos (⌘/↵/⌫) y combos `+`. | — |
|
|
223
|
+
| `ok-org-chart` | Organigrama jerárquico (tidy-tree) con pan/zoom y colapso. | `ok-node-toggle` |
|
|
224
|
+
|
|
225
|
+
### Web / marketing (chrome público)
|
|
226
|
+
|
|
227
|
+
| Componente | Qué hace | Eventos clave |
|
|
228
|
+
|---|---|---|
|
|
229
|
+
| `ok-navbar` | Barra de navegación responsive de landing (logo, enlaces, CTAs, drawer móvil). | navegación por `href` |
|
|
230
|
+
| `ok-footer` | Footer multi-columna responsive (slots `default` + `bottom`). | — |
|
|
231
|
+
| `ok-hero` | Sección hero de marketing con slots `title`/`subtitle`/`actions` (SEO). | — |
|
|
232
|
+
| `ok-page-header` | Cabecera de página in-content (título + descripción + metadatos + acciones). | — |
|
|
233
|
+
| `ok-bento` / `ok-bento-item` | Rejilla bento modular y sus celdas (icono/eyebrow/título, glass, hover). | — |
|
|
234
|
+
| `ok-reveal` | Anima contenido al entrar en viewport (`IntersectionObserver`). | — |
|
|
235
|
+
| `ok-feature-card` | Tarjeta de característica (icono + eyebrow + título + descripción). | — |
|
|
236
|
+
| `ok-pricing-card` | Tarjeta de plan/precio con features checklist y CTA. | — |
|
|
237
|
+
| `ok-product-card` | Tarjeta de módulo/producto (icono Iconify, categoría, badge, precio). | navegación por `href` |
|
|
238
|
+
| `ok-logo-cloud` | Banda de logos "Trusted by" con marquee opcional. | — |
|
|
239
|
+
| `ok-testimonial` | Cita de cliente con rating, avatar, autor/rol y glass. | — |
|
|
240
|
+
| `ok-cta-band` | Banda de llamada a la acción (degradado/glass, título, subtítulo, botones). | — |
|
|
241
|
+
| `ok-language-select` | Selector de idioma para landing (banderas emoji). | navegación por `href` |
|
|
242
|
+
| `ok-contact-form` | Formulario web (nombre/email/asunto/mensaje) con validación inline y POST. | `ok-submit` |
|
|
243
|
+
|
|
244
|
+
### Layout (CSS plano, **no** web component)
|
|
245
|
+
|
|
246
|
+
`@erplora/outfitkit/layout.css` — `.ok-container` / `.ok-container-fluid`, `.ok-grid` / `.ok-col` /
|
|
247
|
+
`.ok-md-*` / `.ok-grid-cards`, `.ok-section` (+ encabezado), `.ok-table-stack` (tabla responsive).
|
|
248
|
+
Geometría/tipografía pura → CSS; comportamiento/estado → web component.
|
|
249
|
+
|
|
250
|
+
### Estado
|
|
251
|
+
|
|
252
|
+
`store` (reactivo + IndexedDB) + `<ok-store>` (emite `ok-store-change` / `ok-store-ready`) +
|
|
253
|
+
`StoreController` (Lit) — ver [sección Estado](#estado-store-con-indexeddb).
|
|
254
|
+
|
|
255
|
+
> **No** se construye lo que Ionic ya da (botones, inputs, listas, modales, toolbars, tabs, layout
|
|
256
|
+
> de app, app-shell). El **shell** del dashboard se compone con `ion-*` directos. Los componentes de
|
|
257
|
+
> **dominio** (POS, RRHH, comercio…) viven en sus **módulos** de negocio reusando estos genéricos,
|
|
258
|
+
> no en el core.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Estado (store con IndexedDB)
|
|
263
|
+
|
|
264
|
+
OutfitKit incluye en su CORE un **store de estado reactivo** respaldado por **IndexedDB**,
|
|
265
|
+
reutilizable por cualquier componente. CERO dependencias externas y CSP-safe (sin `eval`/`new
|
|
266
|
+
Function`). La **fuente de verdad síncrona** es una caché en memoria; IndexedDB solo **persiste** en
|
|
267
|
+
segundo plano, así que `get()` es síncrono y `set()` notifica al instante.
|
|
268
|
+
|
|
269
|
+
API:
|
|
270
|
+
|
|
271
|
+
| Miembro | Descripción |
|
|
272
|
+
|---|---|
|
|
273
|
+
| `createStore({ name?, storeName? })` | Crea un store (defaults DB `outfitkit` / store `kv`). |
|
|
274
|
+
| `store` | Singleton por defecto, listo para usar. |
|
|
275
|
+
| `ready: Promise<void>` | Resuelve cuando la caché se hidrató desde IndexedDB. |
|
|
276
|
+
| `get(key)` | Lee de la caché (SÍNCRONO). |
|
|
277
|
+
| `set(key, value)` | Escribe, notifica suscriptores y persiste (fire-and-forget). |
|
|
278
|
+
| `update(key, fn)` | `fn(prev) => next`. |
|
|
279
|
+
| `delete(key)` / `remove(key)` | Borra una clave. |
|
|
280
|
+
| `clear()` | Vacía el store. |
|
|
281
|
+
| `has(key)` / `keys()` / `entries()` | Introspección. |
|
|
282
|
+
| `subscribe(key, cb)` / `subscribe(cb)` | Suscripción a una clave o a todo. `cb(value, key)`. Devuelve `unsubscribe`. |
|
|
283
|
+
| `flush(): Promise<void>` | Resuelve cuando se han escrito a IndexedDB las operaciones pendientes. |
|
|
284
|
+
|
|
285
|
+
### En JS suelto
|
|
286
|
+
|
|
287
|
+
```js
|
|
288
|
+
import { store, createStore } from '@erplora/outfitkit/store';
|
|
289
|
+
|
|
290
|
+
await store.ready; // hidrata la caché desde IndexedDB
|
|
291
|
+
store.set('theme', 'dark'); // notifica + persiste
|
|
292
|
+
store.get('theme'); // 'dark' (síncrono)
|
|
293
|
+
const off = store.subscribe('theme', (v) => console.log('tema:', v));
|
|
294
|
+
await store.flush(); // espera a que se escriba en disco (opcional)
|
|
295
|
+
off(); // desuscribirse
|
|
296
|
+
|
|
297
|
+
// Store propio (otra DB):
|
|
298
|
+
const prefs = createStore({ name: 'mi-app', storeName: 'prefs' });
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### En Lit (`StoreController`)
|
|
302
|
+
|
|
303
|
+
`StoreController` implementa el `ReactiveController` de Lit: se suscribe al store y llama a
|
|
304
|
+
`requestUpdate()` en cada cambio.
|
|
305
|
+
|
|
306
|
+
```js
|
|
307
|
+
import { LitElement, html } from 'lit';
|
|
308
|
+
import { store } from '@erplora/outfitkit/store';
|
|
309
|
+
import { StoreController } from '@erplora/outfitkit/store-controller';
|
|
310
|
+
|
|
311
|
+
class ThemeToggle extends LitElement {
|
|
312
|
+
#theme = new StoreController(this, store, 'theme');
|
|
313
|
+
render() {
|
|
314
|
+
return html`<ion-toggle
|
|
315
|
+
.checked=${this.#theme.value === 'dark'}
|
|
316
|
+
@ionChange=${(e) => this.#theme.set(e.detail.checked ? 'dark' : 'light')}
|
|
317
|
+
>Modo oscuro</ion-toggle>`;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### En Django (elemento `<ok-store>`, sin escribir JS de wiring)
|
|
323
|
+
|
|
324
|
+
`<ok-store>` posee un store (atributo `name` = DB), no renderiza UI (pasa su contenido por slot) y
|
|
325
|
+
emite `ok-store-change` `{ key, value }` en cada cambio y `ok-store-ready` cuando hidrata. Expone
|
|
326
|
+
`.store` y los proxies `get/set/updateValue/delete` (es `updateValue` porque `update` lo reserva
|
|
327
|
+
LitElement).
|
|
328
|
+
|
|
329
|
+
```html
|
|
330
|
+
<ok-store name="prefs" id="prefs"></ok-store>
|
|
331
|
+
<output id="count">0</output>
|
|
332
|
+
<ion-button id="inc">+1</ion-button>
|
|
333
|
+
|
|
334
|
+
<script type="module" nonce="{{ request.csp_nonce }}">
|
|
335
|
+
const prefs = document.getElementById('prefs');
|
|
336
|
+
const out = document.getElementById('count');
|
|
337
|
+
prefs.addEventListener('ok-store-ready', () => { out.textContent = prefs.get('count') ?? 0; });
|
|
338
|
+
prefs.addEventListener('ok-store-change', (e) => { if (e.detail.key === 'count') out.textContent = e.detail.value; });
|
|
339
|
+
document.getElementById('inc').addEventListener('click', () => prefs.updateValue('count', (n = 0) => n + 1));
|
|
340
|
+
</script>
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
> Si el entorno no soporta IndexedDB (SSR, tests), la persistencia se desactiva en silencio y el
|
|
344
|
+
> store funciona solo en memoria; nunca lanza al consumidor.
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Theming
|
|
349
|
+
|
|
350
|
+
OutfitKit se tematiza en **dos capas**:
|
|
351
|
+
|
|
352
|
+
1. **Tokens globales `--ok-*`** (espejo de `--ion-*`). Son la fuente de verdad.
|
|
353
|
+
2. **Vars por componente** estilo Ionic con default = cadena `--ok-* → --ion-* → hex`. El `ion-*`
|
|
354
|
+
interno hereda `--ion-*` del host, así que claro/oscuro funcionan solos.
|
|
355
|
+
|
|
356
|
+
`@erplora/outfitkit/theme.css` ([`dist/theme.example.css`](dist/theme.example.css)) es una **plantilla**
|
|
357
|
+
de tokens; cópiala y pon tus valores de marca:
|
|
358
|
+
|
|
359
|
+
```css
|
|
360
|
+
:root {
|
|
361
|
+
--ok-primary: var(--ion-color-primary);
|
|
362
|
+
--ok-surface: var(--ion-card-background);
|
|
363
|
+
--ok-radius: 14px;
|
|
364
|
+
--ok-shadow-sm: 0 1px 3px rgba(17, 24, 39, 0.06), 0 1px 2px rgba(17, 24, 39, 0.04);
|
|
365
|
+
--ok-shadow-md: 0 6px 20px rgba(17, 24, 39, 0.08), 0 2px 6px rgba(17, 24, 39, 0.04);
|
|
366
|
+
/* … */
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
El dark lo gobierna `.ion-palette-dark` de Ionic (los `ok-*` heredan `--ion-*`); define ahí los
|
|
371
|
+
overrides de marca que necesites.
|
|
372
|
+
|
|
373
|
+
Override puntual por componente (igual que `ion-button { --background: … }`):
|
|
374
|
+
|
|
375
|
+
```css
|
|
376
|
+
ok-kpi { --ok-radius: 999px; }
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## Uso en Django
|
|
382
|
+
|
|
383
|
+
Sirve el JS desde tus estáticos (`script-src 'self'`) y usa un `nonce` cuando lo necesites. El
|
|
384
|
+
**shell** se arma con `ion-*` directos; OutfitKit aporta los huecos (aquí `ok-data-table`):
|
|
385
|
+
|
|
386
|
+
```html
|
|
387
|
+
{% load static %}
|
|
388
|
+
<link rel="stylesheet" href="{% static 'css/ionic.bundle.css' %}" />
|
|
389
|
+
<link rel="stylesheet" href="{% static 'css/outfitkit-theme.css' %}" />
|
|
390
|
+
|
|
391
|
+
<script type="module" nonce="{{ request.csp_nonce }}">
|
|
392
|
+
import '{% static "outfitkit/dist/cdn.js" %}'; // o imports individuales
|
|
393
|
+
</script>
|
|
394
|
+
|
|
395
|
+
<ion-split-pane content-id="main">
|
|
396
|
+
<ion-menu content-id="main"><!-- ion-list de navegación --></ion-menu>
|
|
397
|
+
<ion-content id="main">
|
|
398
|
+
<ion-header><ion-toolbar><ion-title>Clientes</ion-title></ion-toolbar></ion-header>
|
|
399
|
+
<ok-data-table id="tabla"></ok-data-table>
|
|
400
|
+
</ion-content>
|
|
401
|
+
</ion-split-pane>
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Las props complejas (arrays/objetos como `columns`, `rows`) se asignan en JS:
|
|
405
|
+
|
|
406
|
+
```html
|
|
407
|
+
<script type="module" nonce="{{ request.csp_nonce }}">
|
|
408
|
+
document.getElementById('tabla').columns = [/* ... */];
|
|
409
|
+
document.getElementById('tabla').rows = [/* ... */];
|
|
410
|
+
</script>
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## Uso en Lit / Hub
|
|
414
|
+
|
|
415
|
+
Importa los componentes (side-effect de registro) y úsalos en tus templates Lit:
|
|
416
|
+
|
|
417
|
+
```js
|
|
418
|
+
import { html } from 'lit';
|
|
419
|
+
import '@erplora/outfitkit/ok-data-table';
|
|
420
|
+
|
|
421
|
+
export const view = (cols, rows) => html`
|
|
422
|
+
<ok-data-table
|
|
423
|
+
.columns=${cols}
|
|
424
|
+
.rows=${rows}
|
|
425
|
+
@rowAction=${(e) => handle(e.detail)}
|
|
426
|
+
></ok-data-table>
|
|
427
|
+
`;
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
> En el Hub, `lit` y `@ionic/core` ya los carga el host; OutfitKit los reutiliza (no duplica copias).
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## Comandos de desarrollo
|
|
435
|
+
|
|
436
|
+
```sh
|
|
437
|
+
npm run build # vite (dist/*.js, outfitkit.js, theme.example.css) + tsc (dist/*.d.ts)
|
|
438
|
+
npm run typecheck # comprobación de tipos sin emitir
|
|
439
|
+
npm run verify:csp # rechaza eval / new Function en dist (CSP estricta)
|
|
440
|
+
npm run dev # vite build --watch (showcase en local)
|
|
441
|
+
npm run release # release-it: corta una versión (ver docs/RELEASING.md)
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Publicación a npm: [`docs/RELEASING.md`](docs/RELEASING.md) (Trusted Publishing / OIDC).
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Enlaces
|
|
449
|
+
|
|
450
|
+
- **Showcase (GitHub Pages):** https://erplora.github.io/outfitkit/
|
|
451
|
+
- **Convenciones de desarrollo:** [`docs/CONVENTIONS.md`](docs/CONVENTIONS.md)
|
|
452
|
+
- **Backlog de componentes:** [`docs/PLAN-COMPONENTES.md`](docs/PLAN-COMPONENTES.md)
|
|
453
|
+
- **Cómo contribuir:** [`CONTRIBUTING.md`](CONTRIBUTING.md)
|
|
454
|
+
|
|
455
|
+
## Licencia
|
|
456
|
+
|
|
457
|
+
[MIT](LICENSE) — Copyright (c) 2026 OutfitKit contributors.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface AnchorOptions {
|
|
2
|
+
/** Separación vertical entre botón y panel (px). */
|
|
3
|
+
gap?: number;
|
|
4
|
+
/** Margen mínimo respecto a los bordes del viewport (px). */
|
|
5
|
+
margin?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface AnchorSide {
|
|
8
|
+
/** true → alinear el borde DERECHO del panel con el del botón (abrir hacia la izquierda). */
|
|
9
|
+
end: boolean;
|
|
10
|
+
/** true → abrir hacia ARRIBA del botón (no hay sitio debajo y sí encima). */
|
|
11
|
+
above: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function computeAnchor(trigger: HTMLElement, panel: HTMLElement, opts?: AnchorOptions): AnchorSide;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function define(tag: string, ctor: CustomElementConstructor): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function relay(host: HTMLElement, source: Event, type: string): void;
|
package/dist/cdn.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import './components/ok-store/ok-store.js';
|
|
2
|
+
import './store/store.js';
|
|
3
|
+
import './components/ok-data-table/ok-data-table.js';
|
|
4
|
+
import './components/ok-mail/ok-mail.js';
|
|
5
|
+
import './components/ok-tree/ok-tree.js';
|
|
6
|
+
import './components/ok-inline-feedback/ok-inline-feedback.js';
|
|
7
|
+
import './components/ok-empty-state/ok-empty-state.js';
|
|
8
|
+
import './components/ok-kpi/ok-kpi.js';
|
|
9
|
+
import './components/ok-stat/ok-stat.js';
|
|
10
|
+
import './components/ok-stepper/ok-stepper.js';
|
|
11
|
+
import './components/ok-wizard/ok-wizard.js';
|
|
12
|
+
import './components/ok-widget-board/ok-widget-board.js';
|
|
13
|
+
import './components/ok-contact-form/ok-contact-form.js';
|
|
14
|
+
import './components/ok-calendar/ok-calendar.js';
|
|
15
|
+
import './components/ok-kanban/ok-kanban.js';
|
|
16
|
+
import './components/ok-app-launcher/ok-app-launcher.js';
|
|
17
|
+
import './components/ok-split-button/ok-split-button.js';
|
|
18
|
+
import './components/ok-combo/ok-combo.js';
|
|
19
|
+
import './components/ok-tag-input/ok-tag-input.js';
|
|
20
|
+
import './components/ok-rating/ok-rating.js';
|
|
21
|
+
import './components/ok-otp/ok-otp.js';
|
|
22
|
+
import './components/ok-pinpad/ok-pinpad.js';
|
|
23
|
+
import './components/ok-currency/ok-currency.js';
|
|
24
|
+
import './components/ok-phone/ok-phone.js';
|
|
25
|
+
import './components/ok-dropzone/ok-dropzone.js';
|
|
26
|
+
import './components/ok-sparkline/ok-sparkline.js';
|
|
27
|
+
import './components/ok-chat/ok-chat.js';
|
|
28
|
+
import './components/ok-scheduler/ok-scheduler.js';
|
|
29
|
+
import './components/ok-menubar/ok-menubar.js';
|
|
30
|
+
import './components/ok-carousel/ok-carousel.js';
|
|
31
|
+
import './components/ok-signature/ok-signature.js';
|
|
32
|
+
import './components/ok-qr/ok-qr.js';
|
|
33
|
+
import './components/ok-audio/ok-audio.js';
|
|
34
|
+
import './components/ok-video/ok-video.js';
|
|
35
|
+
import './components/ok-pdf/ok-pdf.js';
|
|
36
|
+
import './components/ok-receipt/ok-receipt.js';
|
|
37
|
+
import './components/ok-invoice/ok-invoice.js';
|
|
38
|
+
import './components/ok-timeline/ok-timeline.js';
|
|
39
|
+
import './components/ok-qty-stepper/ok-qty-stepper.js';
|
|
40
|
+
import './components/ok-command-palette/ok-command-palette.js';
|
|
41
|
+
import './components/ok-color-picker/ok-color-picker.js';
|
|
42
|
+
import './components/ok-avatar/ok-avatar.js';
|
|
43
|
+
import './components/ok-status-pill/ok-status-pill.js';
|
|
44
|
+
import './components/ok-drawer/ok-drawer.js';
|
|
45
|
+
import './components/ok-page-header/ok-page-header.js';
|
|
46
|
+
import './components/ok-bento/ok-bento.js';
|
|
47
|
+
import './components/ok-bento-item/ok-bento-item.js';
|
|
48
|
+
import './components/ok-reveal/ok-reveal.js';
|
|
49
|
+
import './components/ok-feature-card/ok-feature-card.js';
|
|
50
|
+
import './components/ok-pricing-card/ok-pricing-card.js';
|
|
51
|
+
import './components/ok-product-card/ok-product-card.js';
|
|
52
|
+
import './components/ok-logo-cloud/ok-logo-cloud.js';
|
|
53
|
+
import './components/ok-testimonial/ok-testimonial.js';
|
|
54
|
+
import './components/ok-cta-band/ok-cta-band.js';
|
|
55
|
+
import './components/ok-language-select/ok-language-select.js';
|
|
56
|
+
import './components/ok-navbar/ok-navbar.js';
|
|
57
|
+
import './components/ok-footer/ok-footer.js';
|
|
58
|
+
import './components/ok-hero/ok-hero.js';
|
|
59
|
+
import './components/ok-pagination/ok-pagination.js';
|
|
60
|
+
import './components/ok-skeleton/ok-skeleton.js';
|
|
61
|
+
import './components/ok-gauge/ok-gauge.js';
|
|
62
|
+
import './components/ok-chart/ok-chart.js';
|
|
63
|
+
import './components/ok-donut/ok-donut.js';
|
|
64
|
+
import './components/ok-heatmap/ok-heatmap.js';
|
|
65
|
+
import './components/ok-funnel/ok-funnel.js';
|
|
66
|
+
import './components/ok-bar-list/ok-bar-list.js';
|
|
67
|
+
import './components/ok-detail-list/ok-detail-list.js';
|
|
68
|
+
import './components/ok-icon-tile/ok-icon-tile.js';
|
|
69
|
+
import './components/ok-status-dot/ok-status-dot.js';
|
|
70
|
+
import './components/ok-kbd/ok-kbd.js';
|
|
71
|
+
import './components/ok-menu/ok-menu.js';
|
|
72
|
+
import './components/ok-hover-card/ok-hover-card.js';
|
|
73
|
+
import './components/ok-notification-center/ok-notification-center.js';
|
|
74
|
+
import './components/ok-coachmark/ok-coachmark.js';
|
|
75
|
+
import './components/ok-select-card/ok-select-card.js';
|
|
76
|
+
import './components/ok-error-page/ok-error-page.js';
|
|
77
|
+
import './components/ok-date-picker/ok-date-picker.js';
|
|
78
|
+
import './components/ok-time-picker/ok-time-picker.js';
|
|
79
|
+
import './components/ok-range-dual/ok-range-dual.js';
|
|
80
|
+
import './components/ok-file-item/ok-file-item.js';
|
|
81
|
+
import './components/ok-rich-text/ok-rich-text.js';
|
|
82
|
+
import './components/ok-code/ok-code.js';
|
|
83
|
+
import './components/ok-json-viewer/ok-json-viewer.js';
|
|
84
|
+
import './components/ok-diff/ok-diff.js';
|
|
85
|
+
import './components/ok-keyboard/ok-keyboard.js';
|
|
86
|
+
import './components/ok-calculator/ok-calculator.js';
|
|
87
|
+
import './components/ok-image/ok-image.js';
|
|
88
|
+
import './components/ok-gallery/ok-gallery.js';
|
|
89
|
+
import './components/ok-lightbox/ok-lightbox.js';
|
|
90
|
+
import './components/ok-cropper/ok-cropper.js';
|
|
91
|
+
import './components/ok-splitter/ok-splitter.js';
|
|
92
|
+
import './components/ok-loyalty-card/ok-loyalty-card.js';
|
|
93
|
+
import './components/ok-event-card/ok-event-card.js';
|
|
94
|
+
import './components/ok-avatar-group/ok-avatar-group.js';
|
|
95
|
+
import './components/ok-org-chart/ok-org-chart.js';
|
|
96
|
+
import './components/ok-file-manager/ok-file-manager.js';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export interface OkLauncherApp {
|
|
3
|
+
/** Identificador único de la app (clave de selección). */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Texto visible bajo el icono. */
|
|
6
|
+
label: string;
|
|
7
|
+
/**
|
|
8
|
+
* Icono mostrado grande sobre el label. Acepta dos formas:
|
|
9
|
+
* • el NOMBRE de un ionicon (p. ej. `cube-outline`) → se pinta vía `ion-icon name`;
|
|
10
|
+
* • un SVG ya resuelto (string `<svg…>` o `data:` URI) → se pinta vía `ion-icon icon`,
|
|
11
|
+
* útil en hosts con iconos horneados/offline (sin red ni CDN).
|
|
12
|
+
*/
|
|
13
|
+
icon?: string;
|
|
14
|
+
/** Si está presente, al hacer click navega a esta URL (en lugar de emitir evento). */
|
|
15
|
+
href?: string;
|
|
16
|
+
/** Color de fondo del cuadro del icono (cualquier valor CSS); default = primary. */
|
|
17
|
+
color?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface OkAppLauncherLabels {
|
|
20
|
+
/** aria-label del botón disparador y título de la hoja. */
|
|
21
|
+
apps: string;
|
|
22
|
+
/** Texto mostrado cuando no hay apps. */
|
|
23
|
+
empty: string;
|
|
24
|
+
/** aria-label del botón de cerrar. */
|
|
25
|
+
close: string;
|
|
26
|
+
}
|
|
27
|
+
export declare class OkAppLauncher extends LitElement {
|
|
28
|
+
static styles: import("lit").CSSResult;
|
|
29
|
+
/** Apps a mostrar en la rejilla. */
|
|
30
|
+
apps: OkLauncherApp[];
|
|
31
|
+
/** Textos traducibles (merge sobre los defaults en inglés). */
|
|
32
|
+
labels: Partial<OkAppLauncherLabels>;
|
|
33
|
+
private get t();
|
|
34
|
+
private open;
|
|
35
|
+
private shown;
|
|
36
|
+
private readonly onKeydown;
|
|
37
|
+
private portalRoot;
|
|
38
|
+
disconnectedCallback(): void;
|
|
39
|
+
private ensurePortal;
|
|
40
|
+
protected updated(): void;
|
|
41
|
+
private bind;
|
|
42
|
+
private unbind;
|
|
43
|
+
private toggle;
|
|
44
|
+
private openSheet;
|
|
45
|
+
private close;
|
|
46
|
+
private prefersReducedMotion;
|
|
47
|
+
private selectApp;
|
|
48
|
+
private isResolvedSvg;
|
|
49
|
+
private renderApp;
|
|
50
|
+
render(): unknown;
|
|
51
|
+
private overlayTemplate;
|
|
52
|
+
}
|
|
53
|
+
declare global {
|
|
54
|
+
interface HTMLElementTagNameMap {
|
|
55
|
+
'ok-app-launcher': OkAppLauncher;
|
|
56
|
+
}
|
|
57
|
+
}
|