innoboxrr-form-core 2.3.0 → 2.5.0
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/README.md +131 -29
- package/index.js +20 -4
- package/package.json +3 -2
- package/src/components.css +638 -11
- package/src/feedback.js +273 -0
- package/src/icons.js +16 -0
- package/src/theme.js +57 -0
- package/src/tokens.css +41 -0
package/README.md
CHANGED
|
@@ -1,49 +1,75 @@
|
|
|
1
1
|
# innoboxrr-form-core
|
|
2
2
|
|
|
3
|
-
Lo que comparten [`innoboxrr-form-elements`](../form-elements) (Vue)
|
|
4
|
-
[`innoboxrr-react-form-elements`](../react-form-elements) (React) y
|
|
5
|
-
de ningún framework
|
|
3
|
+
Lo que comparten [`innoboxrr-form-elements`](../form-elements) (Vue),
|
|
4
|
+
[`innoboxrr-react-form-elements`](../react-form-elements) (React) y los dos
|
|
5
|
+
datatables, y no depende de ningún framework: el tema, los iconos, las hojas de
|
|
6
|
+
estilo, los archivos y las zonas horarias.
|
|
6
7
|
|
|
7
|
-
Estaba duplicado en los
|
|
8
|
-
|
|
8
|
+
Estaba duplicado en los paquetes, que es exactamente como dos copias empiezan a
|
|
9
|
+
divergir.
|
|
9
10
|
|
|
10
11
|
```
|
|
11
12
|
npm i innoboxrr-form-core
|
|
12
13
|
```
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## Estilos
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import 'innoboxrr-form-core/styles'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Una sola importación trae las tres hojas: `tokens.css` (las variables),
|
|
22
|
+
`layout.css` (las utilidades de maquetación) y `components.css` (los
|
|
23
|
+
componentes). Nada de lo generado necesita UIkit, Tailwind ni Font Awesome.
|
|
24
|
+
|
|
25
|
+
Colores, formas, densidad, capas y movimiento son variables CSS. Para cambiar el
|
|
26
|
+
aspecto de todo, se redefinen:
|
|
27
|
+
|
|
28
|
+
```css
|
|
29
|
+
:root {
|
|
30
|
+
--fe-primary: #7c3aed;
|
|
31
|
+
--fe-radius: 10px;
|
|
32
|
+
--fe-density: 0.875;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
15
35
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
que la aplicación anfitriona tenía que registrar sin que nada lo dijera.
|
|
36
|
+
El modo oscuro responde a la preferencia del sistema y a un `data-theme="dark"`
|
|
37
|
+
en la raíz; `data-theme="light"` fuerza el claro aunque el sistema esté en
|
|
38
|
+
oscuro.
|
|
20
39
|
|
|
21
|
-
|
|
40
|
+
## Tema
|
|
41
|
+
|
|
42
|
+
Un mapa de tokens que la aplicación ajusta **una vez**, al arrancar. Cada token
|
|
43
|
+
apunta a una clase del sistema propio (`fe-*`), así que el caso normal es no
|
|
44
|
+
tocarlo; sirve para apuntar un token a las clases de otro sistema visual cuando
|
|
45
|
+
la aplicación ya tiene el suyo:
|
|
22
46
|
|
|
23
47
|
```js
|
|
24
48
|
import { setTheme } from 'innoboxrr-form-core'
|
|
25
49
|
|
|
26
50
|
setTheme({
|
|
27
51
|
input: 'form-control',
|
|
28
|
-
select: 'form-select',
|
|
29
52
|
button: 'btn btn-primary',
|
|
30
53
|
})
|
|
31
54
|
```
|
|
32
55
|
|
|
33
|
-
Los tokens:
|
|
34
|
-
|
|
35
56
|
| Grupo | Tokens |
|
|
36
57
|
|---|---|
|
|
37
58
|
| Envoltorios | `field`, `fieldInner`, `label`, `help`, `helpIcon`, `error` |
|
|
38
59
|
| Controles | `input`, `select`, `textarea`, `checkbox`, `radio`, `file` |
|
|
39
|
-
| Botones | `button`, `buttonSecondary`, `buttonDanger`, `buttonLink` |
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
60
|
+
| Botones | `button`, `buttonSecondary`, `buttonDanger`, `buttonLink`, `iconButton` |
|
|
61
|
+
| Navegación | `breadcrumb`, `breadcrumbLink`, `breadcrumbCurrent`, `breadcrumbSeparator`, `actionMenu`, `actionMenuItem`, `actionMenuDanger`, `kbd` |
|
|
62
|
+
| Superficies | `surface`, `surfaceRaised`, `toolbar`, `badge`, `badgePrimary`, `badgeSuccess`, `badgeDanger`, `badgeWarning` |
|
|
63
|
+
| Esqueletos | `skeleton`, `skeletonText`, `skeletonCircle`, `skeletonBlock` |
|
|
64
|
+
| Diálogos y drawers | `overlay`, `dialog`, `dialogSmall`, `dialogLarge`, `dialogHeader`, `dialogTitle`, `dialogBody`, `dialogFooter`, `drawer`, `drawerStart`, `drawerHeader`, `drawerTitle`, `drawerBody`, `drawerFooter` |
|
|
65
|
+
| Menús | `menu`, `menuList`, `menuItem`, `menuItemDanger`, `menuSeparator`, `menuLabel` |
|
|
66
|
+
| Paleta de comandos | `command`, `commandInput`, `commandList`, `commandGroup`, `commandItem`, `commandEmpty` |
|
|
67
|
+
| Avisos | `toast`, `toastSuccess`, `toastDanger`, `toastWarning`, `toastTitle`, `toastClose`, `toastRegion` |
|
|
68
|
+
| Tabla | `table`, `tableNumeric`, `tableSticky`, `tableSelect`, `tableResizer`, `tableEmpty`, `bulkBar`, `bulkCount` |
|
|
69
|
+
| Edición en línea | `editable` |
|
|
70
|
+
| Shell de aplicación | `shell`, `shellHeader`, `shellSidebar`, `shellMain` |
|
|
71
|
+
|
|
72
|
+
`customClass` **reemplaza** al token, para el caso puntual:
|
|
47
73
|
|
|
48
74
|
```js
|
|
49
75
|
import { getTheme, resetTheme, onThemeChange, classFor } from 'innoboxrr-form-core'
|
|
@@ -55,9 +81,89 @@ resetTheme() // vuelve a fábrica (sobre todo para pruebas)
|
|
|
55
81
|
onThemeChange(fn) // devuelve la función para dejar de escuchar
|
|
56
82
|
```
|
|
57
83
|
|
|
58
|
-
Los
|
|
59
|
-
|
|
60
|
-
|
|
84
|
+
Los paquetes de componentes se suscriben, así que **un `setTheme` en caliente
|
|
85
|
+
repinta lo que ya esté montado**.
|
|
86
|
+
|
|
87
|
+
## Piezas de escritorio
|
|
88
|
+
|
|
89
|
+
Diálogos, drawers, menús y avisos se apoyan en lo que ya hace el navegador, sin
|
|
90
|
+
librerías de interfaz: `<dialog>` con `showModal()` pone la capa superior, el
|
|
91
|
+
fondo inerte, el foco atrapado, Escape para cerrar y la devolución del foco; el
|
|
92
|
+
atributo `popover` pone el cierre al pulsar fuera. Estas hojas solo los dibujan.
|
|
93
|
+
Los componentes de Vue y React envuelven exactamente este marcado.
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<dialog class="fe-drawer">
|
|
97
|
+
<header class="fe-drawer-header">
|
|
98
|
+
<h2 class="fe-drawer-title">Nuevo producto</h2>
|
|
99
|
+
<button class="fe-icon-button" aria-label="Cerrar">…</button>
|
|
100
|
+
</header>
|
|
101
|
+
<div class="fe-drawer-body">…</div>
|
|
102
|
+
<footer class="fe-drawer-footer">…</footer>
|
|
103
|
+
</dialog>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
- **Diálogo**: `fe-dialog`, con `fe-dialog-sm` o `fe-dialog-lg` para el ancho.
|
|
107
|
+
- **Drawer**: `fe-drawer` a la derecha; `fe-drawer-start` lo pega a la izquierda.
|
|
108
|
+
- **Paleta de comandos**: `<dialog class="fe-dialog fe-command">` con
|
|
109
|
+
`fe-command-input` y una `fe-command-list` de `fe-command-item`; el elemento
|
|
110
|
+
activo lleva `aria-selected="true"`.
|
|
111
|
+
- **Avisos**: una `fe-toast-region` con `popover="manual"`, para seguir encima
|
|
112
|
+
de un drawer abierto con `showModal()`.
|
|
113
|
+
- **Menús**: `fe-menu` con `popover`, colocado con Floating UI.
|
|
114
|
+
- **Tabla**: `fe-table-select` para la columna de casillas, `data-selected` en
|
|
115
|
+
la fila, `fe-bulk-bar` para lo que se hace con la selección y
|
|
116
|
+
`fe-table-resizer` para cambiar el ancho de una columna.
|
|
117
|
+
|
|
118
|
+
Un `<dialog>` cerrado está oculto porque el navegador le pone `display: none`;
|
|
119
|
+
por eso ninguna regla fija `display` fuera del estado `[open]`. Las capas que no
|
|
120
|
+
viven en la capa superior —la cabecera fija de una tabla, un overlay dibujado a
|
|
121
|
+
mano, los tooltips— siguen la escala `--fe-z-*`, nunca un número suelto.
|
|
122
|
+
|
|
123
|
+
## Iconos
|
|
124
|
+
|
|
125
|
+
Un nombre semántico y un mapa que decide de dónde sale el dibujo. Los valores son
|
|
126
|
+
nombres de Iconify (`coleccion:icono`):
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
import { setIcons, iconFor } from 'innoboxrr-form-core'
|
|
130
|
+
|
|
131
|
+
setIcons({ plus: 'lucide:plus', delete: 'lucide:trash-2' })
|
|
132
|
+
iconFor('plus') // 'lucide:plus'
|
|
133
|
+
iconFor('mdi:home') // un nombre completo pasa tal cual
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Avisos y confirmaciones
|
|
137
|
+
|
|
138
|
+
Estado de toda la aplicación, fuera del framework: quien avisa —un store, el
|
|
139
|
+
contrato de un modelo, la tabla— no necesita saber si detrás hay Vue o React.
|
|
140
|
+
Los paquetes de componentes lo pintan con su región de avisos y su anfitrión de
|
|
141
|
+
confirmaciones, que la aplicación monta una vez.
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
import { notify, notifySuccess, notifyError, confirmAction } from 'innoboxrr-form-core'
|
|
145
|
+
|
|
146
|
+
notifySuccess('Producto creado')
|
|
147
|
+
notifyError('No se pudo guardar', { title: 'Producto' })
|
|
148
|
+
notify({ message: 'Exportación en curso', variant: 'info', duration: 8000 })
|
|
149
|
+
|
|
150
|
+
if (await confirmAction({ message: '¿Borrar el producto?', variant: 'danger' })) {
|
|
151
|
+
// …
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- Un aviso se va a los cinco segundos; **uno de peligro se queda** hasta que se
|
|
156
|
+
cierra, porque quien no lo leyó a tiempo no sabría qué falló. `duration: 0` lo
|
|
157
|
+
deja fijo.
|
|
158
|
+
- No se apilan más de cinco: sale el más antiguo.
|
|
159
|
+
- `confirmAction` resuelve `true` o `false`. Una pregunta nueva con otra
|
|
160
|
+
pendiente da la anterior por cancelada.
|
|
161
|
+
- Sin un anfitrión montado, `confirmAction` usa `window.confirm`: una promesa que
|
|
162
|
+
no se resolviera dejaría colgada la acción que la espera.
|
|
163
|
+
|
|
164
|
+
Para pintarlos desde otro sitio: `getToasts`, `onToastsChange`, `dismiss`,
|
|
165
|
+
`getConfirmation`, `onConfirmationChange` y `resolveConfirmation`. `resetToasts`
|
|
166
|
+
y `resetConfirmation` vacían el estado entre pruebas.
|
|
61
167
|
|
|
62
168
|
## Archivos
|
|
63
169
|
|
|
@@ -76,10 +182,6 @@ hay que meter en el `FormData`.
|
|
|
76
182
|
|
|
77
183
|
`validateFiles` es la misma función devolviendo una promesa, por compatibilidad.
|
|
78
184
|
|
|
79
|
-
La vista previa de lo que no es imagen es un `data:` URI. Antes era una URL de
|
|
80
|
-
`icon-library.com`: cada archivo disparaba una petición a un tercero que puede
|
|
81
|
-
caerse o cambiar.
|
|
82
|
-
|
|
83
185
|
## Zonas horarias
|
|
84
186
|
|
|
85
187
|
```js
|
package/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* innoboxrr-form-core
|
|
3
3
|
*
|
|
4
|
-
* Lo que comparten
|
|
5
|
-
* no depende de ningun framework: el tema,
|
|
6
|
-
*
|
|
4
|
+
* Lo que comparten los paquetes de interfaz innoboxrr —los componentes de Vue
|
|
5
|
+
* y de React y los dos datatables— y no depende de ningun framework: el tema,
|
|
6
|
+
* los iconos, los avisos y confirmaciones, la validacion de archivos y la lista
|
|
7
|
+
* de zonas horarias.
|
|
7
8
|
*
|
|
8
|
-
* Estaba duplicado en los
|
|
9
|
+
* Estaba duplicado en los paquetes, que es exactamente como dos copias
|
|
9
10
|
* empiezan a divergir.
|
|
10
11
|
*/
|
|
11
12
|
|
|
@@ -27,6 +28,21 @@ export {
|
|
|
27
28
|
setIcons,
|
|
28
29
|
} from './src/icons.js'
|
|
29
30
|
|
|
31
|
+
export {
|
|
32
|
+
confirmAction,
|
|
33
|
+
dismiss,
|
|
34
|
+
getConfirmation,
|
|
35
|
+
getToasts,
|
|
36
|
+
notify,
|
|
37
|
+
notifyError,
|
|
38
|
+
notifySuccess,
|
|
39
|
+
onConfirmationChange,
|
|
40
|
+
onToastsChange,
|
|
41
|
+
resetConfirmation,
|
|
42
|
+
resetToasts,
|
|
43
|
+
resolveConfirmation,
|
|
44
|
+
} from './src/feedback.js'
|
|
45
|
+
|
|
30
46
|
export {
|
|
31
47
|
FILE_ICON,
|
|
32
48
|
describeFiles,
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "innoboxrr-form-core",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "El nucleo agnostico de
|
|
3
|
+
"version": "2.5.0",
|
|
4
|
+
"description": "El nucleo agnostico de la interfaz innoboxrr: tema, iconos, estilos, archivos y zonas horarias.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./index.js",
|
|
9
9
|
"./theme": "./src/theme.js",
|
|
10
10
|
"./icons": "./src/icons.js",
|
|
11
|
+
"./feedback": "./src/feedback.js",
|
|
11
12
|
"./files": "./src/files.js",
|
|
12
13
|
"./timezone": "./src/timezone.js",
|
|
13
14
|
"./styles": "./styles.css",
|