@groupteknology/vuno 0.6.0 → 1.0.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/LICENSE +21 -21
- package/README.md +160 -37
- package/dist/module.d.cts +2 -0
- package/dist/module.d.mts +2 -10
- package/dist/module.json +1 -1
- package/dist/module.mjs +14 -24
- package/dist/types.d.mts +11 -3
- package/package.json +49 -44
- package/dist/runtime/app/assets/css/main.css +0 -1
- package/dist/runtime/app/components/Cell/CellBadge.d.vue.ts +0 -5
- package/dist/runtime/app/components/Cell/CellBadge.vue +0 -24
- package/dist/runtime/app/components/Cell/CellBadge.vue.d.ts +0 -5
- package/dist/runtime/app/components/Cell/CellBoolean.d.vue.ts +0 -5
- package/dist/runtime/app/components/Cell/CellBoolean.vue +0 -21
- package/dist/runtime/app/components/Cell/CellBoolean.vue.d.ts +0 -5
- package/dist/runtime/app/components/Cell/CellCurrency.d.vue.ts +0 -5
- package/dist/runtime/app/components/Cell/CellCurrency.vue +0 -14
- package/dist/runtime/app/components/Cell/CellCurrency.vue.d.ts +0 -5
- package/dist/runtime/app/components/Cell/CellDate.d.vue.ts +0 -5
- package/dist/runtime/app/components/Cell/CellDate.vue +0 -19
- package/dist/runtime/app/components/Cell/CellDate.vue.d.ts +0 -5
- package/dist/runtime/app/components/Cell/CellImage.d.vue.ts +0 -5
- package/dist/runtime/app/components/Cell/CellImage.vue +0 -22
- package/dist/runtime/app/components/Cell/CellImage.vue.d.ts +0 -5
- package/dist/runtime/app/components/Cell/CellNumber.d.vue.ts +0 -5
- package/dist/runtime/app/components/Cell/CellNumber.vue +0 -15
- package/dist/runtime/app/components/Cell/CellNumber.vue.d.ts +0 -5
- package/dist/runtime/app/components/Cell/CellText.d.vue.ts +0 -5
- package/dist/runtime/app/components/Cell/CellText.vue +0 -13
- package/dist/runtime/app/components/Cell/CellText.vue.d.ts +0 -5
- package/dist/runtime/app/components/Confirm/Confirm.d.vue.ts +0 -35
- package/dist/runtime/app/components/Confirm/Confirm.vue +0 -68
- package/dist/runtime/app/components/Confirm/Confirm.vue.d.ts +0 -35
- package/dist/runtime/app/components/Field/FieldArray.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldArray.vue +0 -128
- package/dist/runtime/app/components/Field/FieldArray.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldCheckbox.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldCheckbox.vue +0 -30
- package/dist/runtime/app/components/Field/FieldCheckbox.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldColor.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldColor.vue +0 -57
- package/dist/runtime/app/components/Field/FieldColor.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldEmail.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldEmail.vue +0 -37
- package/dist/runtime/app/components/Field/FieldEmail.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldFile.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldFile.vue +0 -93
- package/dist/runtime/app/components/Field/FieldFile.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldNumber.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldNumber.vue +0 -38
- package/dist/runtime/app/components/Field/FieldNumber.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldPassword.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldPassword.vue +0 -35
- package/dist/runtime/app/components/Field/FieldPassword.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldRadio.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldRadio.vue +0 -33
- package/dist/runtime/app/components/Field/FieldRadio.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldSelect.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldSelect.vue +0 -38
- package/dist/runtime/app/components/Field/FieldSelect.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldSlug.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldSlug.vue +0 -92
- package/dist/runtime/app/components/Field/FieldSlug.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldSwitch.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldSwitch.vue +0 -27
- package/dist/runtime/app/components/Field/FieldSwitch.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldText.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldText.vue +0 -38
- package/dist/runtime/app/components/Field/FieldText.vue.d.ts +0 -5
- package/dist/runtime/app/components/Field/FieldTextarea.d.vue.ts +0 -5
- package/dist/runtime/app/components/Field/FieldTextarea.vue +0 -36
- package/dist/runtime/app/components/Field/FieldTextarea.vue.d.ts +0 -5
- package/dist/runtime/app/components/Form/Form.d.vue.ts +0 -48
- package/dist/runtime/app/components/Form/Form.vue +0 -138
- package/dist/runtime/app/components/Form/Form.vue.d.ts +0 -48
- package/dist/runtime/app/components/Form/FormField.d.vue.ts +0 -7
- package/dist/runtime/app/components/Form/FormField.vue +0 -63
- package/dist/runtime/app/components/Form/FormField.vue.d.ts +0 -7
- package/dist/runtime/app/components/Form/FormModal.d.vue.ts +0 -60
- package/dist/runtime/app/components/Form/FormModal.vue +0 -83
- package/dist/runtime/app/components/Form/FormModal.vue.d.ts +0 -60
- package/dist/runtime/app/components/Form/FormSection.d.vue.ts +0 -12
- package/dist/runtime/app/components/Form/FormSection.vue +0 -43
- package/dist/runtime/app/components/Form/FormSection.vue.d.ts +0 -12
- package/dist/runtime/app/components/Page/Page.d.vue.ts +0 -24
- package/dist/runtime/app/components/Page/Page.vue +0 -63
- package/dist/runtime/app/components/Page/Page.vue.d.ts +0 -24
- package/dist/runtime/app/components/State/EmptyState.d.vue.ts +0 -20
- package/dist/runtime/app/components/State/EmptyState.vue +0 -36
- package/dist/runtime/app/components/State/EmptyState.vue.d.ts +0 -20
- package/dist/runtime/app/components/State/FailureState.d.vue.ts +0 -10
- package/dist/runtime/app/components/State/FailureState.vue +0 -34
- package/dist/runtime/app/components/State/FailureState.vue.d.ts +0 -10
- package/dist/runtime/app/components/Table/Table.d.vue.ts +0 -70
- package/dist/runtime/app/components/Table/Table.vue +0 -441
- package/dist/runtime/app/components/Table/Table.vue.d.ts +0 -70
- package/dist/runtime/app/components/Table/TableCell.d.vue.ts +0 -8
- package/dist/runtime/app/components/Table/TableCell.vue +0 -35
- package/dist/runtime/app/components/Table/TableCell.vue.d.ts +0 -8
- package/dist/runtime/app/composables/useVunoCrud.d.ts +0 -23
- package/dist/runtime/app/composables/useVunoCrud.js +0 -139
- package/dist/runtime/app/composables/useVunoField.d.ts +0 -10
- package/dist/runtime/app/composables/useVunoField.js +0 -34
- package/dist/runtime/app/composables/useVunoForm.d.ts +0 -2
- package/dist/runtime/app/composables/useVunoForm.js +0 -9
- package/dist/runtime/app/composables/useVunoTableQuery.d.ts +0 -51
- package/dist/runtime/app/composables/useVunoTableQuery.js +0 -110
- package/dist/runtime/app/composables/useVunoTheme.d.ts +0 -12
- package/dist/runtime/app/composables/useVunoTheme.js +0 -35
- package/dist/runtime/app/theme/index.d.ts +0 -14
- package/dist/runtime/app/theme/index.js +0 -228
- package/dist/runtime/app/types/app-config.d.ts +0 -8
- package/dist/runtime/app/types/app-config.js +0 -1
- package/dist/runtime/app/types/confirm.d.ts +0 -11
- package/dist/runtime/app/types/confirm.js +0 -0
- package/dist/runtime/app/types/crud.d.ts +0 -108
- package/dist/runtime/app/types/crud.js +0 -0
- package/dist/runtime/app/types/field.d.ts +0 -128
- package/dist/runtime/app/types/field.js +0 -0
- package/dist/runtime/app/types/form.d.ts +0 -39
- package/dist/runtime/app/types/form.js +0 -1
- package/dist/runtime/app/types/index.d.ts +0 -9
- package/dist/runtime/app/types/index.js +0 -1
- package/dist/runtime/app/types/page.d.ts +0 -6
- package/dist/runtime/app/types/page.js +0 -0
- package/dist/runtime/app/types/responsive.d.ts +0 -8
- package/dist/runtime/app/types/responsive.js +0 -0
- package/dist/runtime/app/types/table.d.ts +0 -197
- package/dist/runtime/app/types/table.js +0 -0
- package/dist/runtime/app/types/theme.d.ts +0 -83
- package/dist/runtime/app/types/theme.js +0 -0
- package/dist/runtime/app/utils/column.d.ts +0 -9
- package/dist/runtime/app/utils/column.js +0 -5
- package/dist/runtime/app/utils/format.d.ts +0 -9
- package/dist/runtime/app/utils/format.js +0 -30
- package/dist/runtime/app/utils/grid.d.ts +0 -9
- package/dist/runtime/app/utils/grid.js +0 -91
- package/dist/runtime/app/utils/path.d.ts +0 -16
- package/dist/runtime/app/utils/path.js +0 -74
- package/dist/runtime/app/utils/query-key.d.ts +0 -20
- package/dist/runtime/app/utils/query-key.js +0 -7
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Diego Otayza
|
|
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.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Diego Otayza
|
|
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
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# @groupteknology/vuno
|
|
2
2
|
|
|
3
|
-
Formularios, tablas y diálogos declarativos para Nuxt 4,
|
|
3
|
+
Formularios, tablas y diálogos declarativos para Nuxt 4, con componentes propios y sin librería de interfaz por debajo.
|
|
4
4
|
|
|
5
|
-
El módulo **
|
|
5
|
+
El módulo **trae su propia estética, y se sobreescribe entera desde el proyecto**. Todo lo que pinta se deriva de un puñado de variables CSS —los tokens `--vuno-*`—, así que redefinir una cambia vuno entero sin tocar un solo componente. Lo que necesita comportamiento difícil —combobox, menú, pestañas, tooltip, campo numérico— lleva su patrón ARIA y su teclado escritos aquí, con [Floating UI](https://floating-ui.com) para colocar lo que flota y nada más; el resto son elementos nativos.
|
|
6
|
+
|
|
7
|
+
Un color o un radio escrito a mano dentro de un componente es un error: si algo no se puede cambiar desde los tokens, falta un token.
|
|
8
|
+
|
|
9
|
+
## Documentación
|
|
10
|
+
|
|
11
|
+
El catálogo vive en **<https://groupteknology.github.io/vuno/>**: una ficha por componente, con la vista viva, los controles que la mueven, el código que produce cada combinación y las tablas de props, slots y emits al pie.
|
|
12
|
+
|
|
13
|
+
Lo que hay aquí abajo es la referencia corta, para leerla sin salir del editor.
|
|
6
14
|
|
|
7
15
|
## Instalación
|
|
8
16
|
|
|
@@ -13,7 +21,24 @@ pnpm add @groupteknology/vuno
|
|
|
13
21
|
```ts
|
|
14
22
|
// nuxt.config.ts
|
|
15
23
|
export default defineNuxtConfig({
|
|
16
|
-
modules: ['@
|
|
24
|
+
modules: ['@groupteknology/vuno'],
|
|
25
|
+
})
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Eso es todo: el módulo registra sus componentes, su hoja de estilos, el compilador de Tailwind y `@nuxt/icon`, que es quien pinta los iconos.
|
|
29
|
+
|
|
30
|
+
¿Vienes de la `0.6.1`? El [changelog](https://github.com/groupteknology/vuno/blob/main/packages/core/CHANGELOG.md) dice qué se rompe y qué mirar después.
|
|
31
|
+
|
|
32
|
+
### Tailwind
|
|
33
|
+
|
|
34
|
+
**El módulo registra el compilador de Tailwind** (`@tailwindcss/vite`). No es una comodidad: la hoja que empuja vuno empieza por `@import 'tailwindcss'`, y sin nadie que lo compile ese import no hace nada —las variables del tema llegan, porque son CSS normal, y ni una sola utilidad—. La aplicación se sirve, no falla nada y sale sin estilos, que es el peor modo de fallar.
|
|
35
|
+
|
|
36
|
+
Si tu proyecto ya monta Tailwind, se detecta y no se duplica. Y si prefieres llevarlo tú:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
export default defineNuxtConfig({
|
|
40
|
+
modules: ['@groupteknology/vuno'],
|
|
41
|
+
vuno: { tailwind: false },
|
|
17
42
|
})
|
|
18
43
|
```
|
|
19
44
|
|
|
@@ -53,8 +78,8 @@ const definition = {
|
|
|
53
78
|
<template>
|
|
54
79
|
<VForm v-model:state="state" :definition="definition" :schema="schema" @submit="guardar">
|
|
55
80
|
<template #footer="{ dirty, reset }">
|
|
56
|
-
<
|
|
57
|
-
<
|
|
81
|
+
<VButton :disabled="!dirty" label="Descartar" variant="ghost" @click="reset" />
|
|
82
|
+
<VButton label="Guardar" type="submit" />
|
|
58
83
|
</template>
|
|
59
84
|
</VForm>
|
|
60
85
|
</template>
|
|
@@ -68,6 +93,14 @@ const definition = {
|
|
|
68
93
|
|
|
69
94
|
Cada uno declara sus propios props mediante una unión discriminada por `type`, así que el editor te avisa si a un `slug` le falta el `source` o si le pasas un `placeholder` a un `file`.
|
|
70
95
|
|
|
96
|
+
### Campos obligatorios
|
|
97
|
+
|
|
98
|
+
`required: true` hace tres cosas: pinta el asterisco en la etiqueta, pone el atributo `required` en el input —que es lo que anuncia el campo como obligatorio a un lector de pantalla y lo que permite estilar `:invalid`— y nada más. **Quien decide si el valor vale es el esquema.**
|
|
99
|
+
|
|
100
|
+
El `<form>` lleva `novalidate`, así que el navegador no valida por su cuenta. Sin eso convivirían dos validaciones y ganaría la del navegador: cortaría el envío antes de que el esquema llegase a ejecutarse, y el usuario vería un globo del navegador, en su idioma y fuera del tema, en lugar del mensaje que tú escribiste.
|
|
101
|
+
|
|
102
|
+
Conviene saberlo si vienes de otras librerías, donde `required` suele pintar el asterisco y no llegar al control. Aquí llega, a propósito y por accesibilidad, y por eso el `novalidate` es necesario y no una preferencia.
|
|
103
|
+
|
|
71
104
|
### Campos repetibles
|
|
72
105
|
|
|
73
106
|
`type: 'array'` repite un grupo de campos y genera rutas anidadas (`variants.0.sku`) que coinciden con las que produce la validación, de modo que cada campo muestra su propio error. Admite anidamiento.
|
|
@@ -94,8 +127,8 @@ El slot `footer` recibe `formId`, necesario para enviar desde un botón propio:
|
|
|
94
127
|
```vue
|
|
95
128
|
<VFormModal v-model:open="open" v-model:state="state" :definition="definition" :title="title">
|
|
96
129
|
<template #footer="{ close, formId, loading }">
|
|
97
|
-
<
|
|
98
|
-
<
|
|
130
|
+
<VButton label="Cancelar" variant="ghost" @click="close" />
|
|
131
|
+
<VButton :form="formId" :label="editando ? 'Guardar cambios' : 'Crear'" :loading="loading" type="submit" />
|
|
99
132
|
</template>
|
|
100
133
|
</VFormModal>
|
|
101
134
|
```
|
|
@@ -177,7 +210,7 @@ Y la página queda sin saber nada de los campos:
|
|
|
177
210
|
| La fila en edición | Un prop —`product`, `brand`, lo que sea— que vale `null` en el alta. De él salen el título y la etiqueta del botón. |
|
|
178
211
|
| `@submit` | Significa «el usuario confirmó», nada más. Sin datos: ya están en `state`. |
|
|
179
212
|
|
|
180
|
-
No es casualidad que encaje: son exactamente `state`, `formOpen`, `isSaving`, `editing` y `submit` de `
|
|
213
|
+
No es casualidad que encaje: son exactamente `state`, `formOpen`, `isSaving`, `editing` y `submit` de `useCrud`.
|
|
181
214
|
|
|
182
215
|
#### Qué se queda fuera
|
|
183
216
|
|
|
@@ -189,7 +222,7 @@ El estado tampoco se queda dentro. Si el formulario declara su propio `ref` en v
|
|
|
189
222
|
|
|
190
223
|
## Una pantalla de mantenimiento entera
|
|
191
224
|
|
|
192
|
-
`
|
|
225
|
+
`useCrud` resuelve el ciclo completo: listar, dar de alta o editar en un modal, borrar con confirmación, invalidar la caché y avisar. Está construido sobre [TanStack Query](https://tanstack.com/query).
|
|
193
226
|
|
|
194
227
|
```vue
|
|
195
228
|
<script setup lang="ts">
|
|
@@ -197,11 +230,11 @@ El estado tampoco se queda dentro. Si el formulario declara su propio `ref` en v
|
|
|
197
230
|
// responde 401 durante el render. `useRequestFetch()` sí la lleva.
|
|
198
231
|
const request = useRequestFetch()
|
|
199
232
|
|
|
200
|
-
const query =
|
|
233
|
+
const query = useTableQuery({ sort: 'sku', url: true })
|
|
201
234
|
|
|
202
235
|
const { items, total, failure, isPending, isSaving, isDeleting,
|
|
203
236
|
formOpen, editing, state, submit, openCreate, openEdit,
|
|
204
|
-
confirmOpen, deleting, askDelete, confirmDelete } =
|
|
237
|
+
confirmOpen, deleting, askDelete, confirmDelete } = useCrud<Product, ProductForm>({
|
|
205
238
|
key: 'products',
|
|
206
239
|
query,
|
|
207
240
|
emptyForm: () => ({ name: '', sku: '' }),
|
|
@@ -222,7 +255,7 @@ La consulta forma parte de la clave de caché, así que cada página, filtro y o
|
|
|
222
255
|
`key` acepta un getter o un `computed`, no solo un valor fijo. Hace falta en cuanto la pantalla tiene un selector —empresa, tienda, almacén—: con una clave fija, cambiar de empresa seguiría enseñando los datos de la anterior sin dar ninguna señal de error.
|
|
223
256
|
|
|
224
257
|
```ts
|
|
225
|
-
const crud =
|
|
258
|
+
const crud = useCrud({
|
|
226
259
|
key: () => ['products', selectedCompanyId.value],
|
|
227
260
|
// ...
|
|
228
261
|
})
|
|
@@ -247,7 +280,7 @@ Mientras la clave está incompleta, `isPending` sigue en `true`: la pantalla est
|
|
|
247
280
|
Para lo que no se deduce de la clave —un permiso, una pestaña que no está a la vista— está la opción `enabled`, que se suma a la condición anterior.
|
|
248
281
|
|
|
249
282
|
```ts
|
|
250
|
-
|
|
283
|
+
useCrud({ key: () => ['products', companyId.value], enabled: () => canRead.value, /* ... */ })
|
|
251
284
|
```
|
|
252
285
|
|
|
253
286
|
### La clave de invalidación
|
|
@@ -261,7 +294,7 @@ key: () => productKeys.list(filtros) // solo refresca esa combinación de filtro
|
|
|
261
294
|
|
|
262
295
|
### Render en servidor
|
|
263
296
|
|
|
264
|
-
`
|
|
297
|
+
`useCrud` resuelve el listado durante el render en servidor, así que el HTML sale con las filas puestas y no aparecen al hidratar. Nuxt renderiza en servidor por defecto, de modo que esto no hay que activarlo.
|
|
265
298
|
|
|
266
299
|
Para que además viaje en el payload y el cliente no vuelva a pedirlo, el plugin de vue-query del proyecto tiene que deshidratar. Es responsabilidad del consumidor, no del módulo:
|
|
267
300
|
|
|
@@ -286,7 +319,13 @@ Con la clave incompleta no se espera nada: la consulta está suspendida y espera
|
|
|
286
319
|
|
|
287
320
|
Si compruebas esto con un test, **mira el HTML renderizado, no el payload**. El payload lleva la consulta resuelta aunque el prefetch esté apagado, porque la consulta se asienta después del render y el plugin deshidrata lo que encuentra: un assert sobre el payload pasa en las dos direcciones y no mide nada.
|
|
288
321
|
|
|
289
|
-
|
|
322
|
+
**`@tanstack/vue-query` lo instala el proyecto**, y solo hace falta si usas este composable:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
pnpm add @tanstack/vue-query
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
No se declara como dependencia opcional del módulo a propósito. npm instala igualmente los `peerDependencies` marcados como opcionales, y como los de vue-query admiten Vue 2, acababa colocando `vue@2.6.14` en la raíz y chocando con el `vue@^3.5.0` que pide vuno: `npm install @groupteknology/vuno` fallaba con `ERESOLVE` en un proyecto Nuxt que no declarara `vue` por su cuenta. Con pnpm no ocurría, que es por lo que tardó en verse.
|
|
290
329
|
|
|
291
330
|
## Páginas
|
|
292
331
|
|
|
@@ -295,7 +334,7 @@ Si compruebas esto con un test, **mira el HTML renderizado, no el payload**. El
|
|
|
295
334
|
```vue
|
|
296
335
|
<VPage title="Productos" description="Catálogo completo." :breadcrumb="[{ label: 'Inicio', to: '/' }, { label: 'Productos' }]">
|
|
297
336
|
<template #actions>
|
|
298
|
-
<
|
|
337
|
+
<VButton icon="lucide:plus" label="Nuevo producto" @click="openCreate" />
|
|
299
338
|
</template>
|
|
300
339
|
|
|
301
340
|
<VTable ... />
|
|
@@ -306,9 +345,11 @@ Si compruebas esto con un test, **mira el HTML renderizado, no el payload**. El
|
|
|
306
345
|
|
|
307
346
|
`VTable` funciona en modo servidor: emite el estado de consulta y tú devuelves la página.
|
|
308
347
|
|
|
348
|
+
**`query` es obligatorio.** No es un `v-model` opcional: sin él la tabla no compila, y el error de tipos que sale encabeza con el objeto `definition`, así que manda a mirar el sitio equivocado.
|
|
349
|
+
|
|
309
350
|
```vue
|
|
310
351
|
<script setup lang="ts">
|
|
311
|
-
const query =
|
|
352
|
+
const query = useTableQuery({ sort: 'sku', url: true, history: 'push', filterKeys: ['status'] })
|
|
312
353
|
|
|
313
354
|
const { data, status } = await useFetch('/api/products', {
|
|
314
355
|
query: computed(() => ({ page: query.value.page, sort: query.value.sort?.column, ...query.value.filters })),
|
|
@@ -384,10 +425,10 @@ Y un aviso al ordenar: `sortable` ordena **en servidor por `key`**, y el servido
|
|
|
384
425
|
`map` es solo de `badge`. Para traducir en otro tipo de columna, o para componer algo que no es una etiqueta, está `type: 'custom'` con su slot:
|
|
385
426
|
|
|
386
427
|
```vue
|
|
387
|
-
<VTable :definition="definition" :data="rows">
|
|
428
|
+
<VTable v-model:query="query" :definition="definition" :data="rows">
|
|
388
429
|
<template #cell-stock="{ row, value }">
|
|
389
430
|
<span class="tabular-nums">{{ value }} uds.</span>
|
|
390
|
-
<
|
|
431
|
+
<VBadge v-if="row.stock === 0" color="error" label="Agotado" />
|
|
391
432
|
</template>
|
|
392
433
|
</VTable>
|
|
393
434
|
```
|
|
@@ -404,16 +445,20 @@ const failure = computed(() => isError.value
|
|
|
404
445
|
: undefined)
|
|
405
446
|
```
|
|
406
447
|
|
|
448
|
+
Con `useCrud` no hace falta escribirlo: el objeto lo construye él, y el título y la pista se declaran en `messages` con `listFailed` y `listFailedHint`.
|
|
449
|
+
|
|
450
|
+
Si vienes de componerlo a mano, cuenta con un efecto lateral: si tu proyecto tiene un test que sujeta esta invariante buscando el objeto en la pantalla, se pondrá **rojo** al mudar los textos, porque ahí ya no hay ningún `retry:` que encontrar. No es una regresión —la garantía sigue, solo que ahora la sostiene el tipo `VunoTableFailure`, cuyo `retry` es obligatorio y comprueba el typecheck— pero el test tiene que mirar otra cosa.
|
|
451
|
+
|
|
407
452
|
El reintento va **dentro** del objeto para que no se pueda pintar un error sin ofrecer salida. Mientras hay fallo, la tabla no muestra filas ni paginación. El estado vacío se declara en la definición (`empty: { title, hint, icon }`) y tiene un slot `empty-actions` donde encaja el «crear el primero».
|
|
408
453
|
|
|
409
|
-
Los dos estados existen además
|
|
454
|
+
Los dos estados existen además sueltos, para las pantallas que no son una tabla, y son **un solo componente con dos tonos**: `VState`. El tono no es un adjetivo sino el discriminante de una unión, así que `tone="failure"` exige el objeto del fallo y no hay forma de escribir un error sin su salida dentro:
|
|
410
455
|
|
|
411
456
|
```vue
|
|
412
|
-
<
|
|
413
|
-
<template #actions><
|
|
414
|
-
</
|
|
457
|
+
<VState title="Todavía no hay pedidos" hint="Aparecerán aquí en cuanto entre el primero." icon="lucide:inbox">
|
|
458
|
+
<template #actions><VButton label="Crear pedido" /></template>
|
|
459
|
+
</VState>
|
|
415
460
|
|
|
416
|
-
<
|
|
461
|
+
<VState tone="failure" :failure="failure" />
|
|
417
462
|
```
|
|
418
463
|
|
|
419
464
|
Tipos de columna: `text` · `number` · `currency` · `date` · `boolean` · `badge` · `image` · `custom` · `actions`. Trae búsqueda con antirrebote, paginación, selección múltiple, panel lateral de filtros y menú de acciones por fila.
|
|
@@ -425,37 +470,109 @@ Tipos de columna: `text` · `number` · `currency` · `date` · `boolean` · `ba
|
|
|
425
470
|
```vue
|
|
426
471
|
<VConfirm v-model:open="open" :title="`¿Eliminar ${marca.nombre}?`" @confirm="borrar">
|
|
427
472
|
<p>Se eliminará <strong>{{ marca.nombre }}</strong>.</p>
|
|
428
|
-
<p class="text-warning">{{ marca.productos }} productos se quedarán sin marca.</p>
|
|
473
|
+
<p class="text-vuno-warning">{{ marca.productos }} productos se quedarán sin marca.</p>
|
|
429
474
|
</VConfirm>
|
|
430
475
|
```
|
|
431
476
|
|
|
432
477
|
No se cierra solo cuando recibe `loading`: así se espera a que la acción termine contra la API y se cierra desde fuera.
|
|
433
478
|
|
|
479
|
+
## Modales del proyecto
|
|
480
|
+
|
|
481
|
+
Un modal por componente, en `components/modal/`, abierto por su clave:
|
|
482
|
+
|
|
483
|
+
```
|
|
484
|
+
app/components/modal/ModalProduct.vue -> open('product')
|
|
485
|
+
app/components/modal/ModalInvoice.vue -> open('invoice')
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
```ts
|
|
489
|
+
const modal = useModal()
|
|
490
|
+
|
|
491
|
+
const guardado = await modal.open<boolean>('product', { sku: row.sku })
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
No hay que registrarlo ni colocarlo en ninguna plantilla: el módulo marca esa carpeta como global, así que la clave **es** el nombre del componente y un modal que existe se puede abrir.
|
|
495
|
+
|
|
496
|
+
El componente recibe `open` y los props que le pases, y resuelve la promesa emitiendo `close` con su resultado:
|
|
497
|
+
|
|
498
|
+
```vue
|
|
499
|
+
<script setup lang="ts">
|
|
500
|
+
const emit = defineEmits<{ close: [guardado: boolean] }>()
|
|
501
|
+
const open = defineModel<boolean>('open', { default: false })
|
|
502
|
+
|
|
503
|
+
function guardar() {
|
|
504
|
+
open.value = false
|
|
505
|
+
emit('close', true)
|
|
506
|
+
}
|
|
507
|
+
</script>
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
Se pinta en `<VApp>` y no en la pantalla que lo abrió, así que navegar no lo desmonta a medias ni deja la promesa colgada. Cerrarlo con Escape o pulsando fuera resuelve sin valor.
|
|
511
|
+
|
|
434
512
|
## Composables
|
|
435
513
|
|
|
436
514
|
| Composable | Para qué |
|
|
437
515
|
|---|---|
|
|
438
|
-
| `
|
|
439
|
-
| `
|
|
440
|
-
| `
|
|
441
|
-
| `
|
|
442
|
-
| `
|
|
443
|
-
| `
|
|
444
|
-
| `
|
|
516
|
+
| `useCrud` | El ciclo de mantenimiento entero sobre TanStack Query. |
|
|
517
|
+
| `useTableQuery` | Estado de consulta de una tabla, opcionalmente sincronizado con la query string. |
|
|
518
|
+
| `useForm` | Contexto del `VForm` que envuelve al componente: estado, `dirty`, `reset`. |
|
|
519
|
+
| `useField` | Lee y escribe un campo por su ruta; para construir campos propios. |
|
|
520
|
+
| `useTheme` | Resuelve los slots de un componente cruzando tema, `app.config` y prop `ui`. |
|
|
521
|
+
| `useIcons` | Los iconos configurados en `vuno.icons`. |
|
|
522
|
+
| `useMessages` | Los textos configurados en `vuno.messages`. |
|
|
445
523
|
|
|
446
524
|
Los tres últimos existen para que un componente tuyo pueda usar los mismos iconos, textos y reglas de tema que los de vuno sin duplicar la configuración.
|
|
447
525
|
|
|
448
526
|
## Personalización
|
|
449
527
|
|
|
450
|
-
|
|
528
|
+
### Los tokens
|
|
529
|
+
|
|
530
|
+
**Es el primer sitio al que hay que ir, y casi siempre el único.** Todo el color, el radio y la jerarquía de texto de vuno salen de variables CSS que se redefinen desde el proyecto. El caso mínimo, en cualquier hoja que cargue tu aplicación:
|
|
531
|
+
|
|
532
|
+
```css
|
|
533
|
+
:root {
|
|
534
|
+
--vuno-primary: var(--color-indigo-600);
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
Con esa línea cambian los botones sólidos, el anillo de foco de todos los campos, el enlace activo, la casilla marcada y el acento de las insignias: no hay un solo componente que escriba ese azul por su cuenta.
|
|
539
|
+
|
|
540
|
+
Los que hay:
|
|
541
|
+
|
|
542
|
+
| Token | Para qué |
|
|
543
|
+
| --- | --- |
|
|
544
|
+
| `--vuno-primary` · `--vuno-secondary` · `--vuno-neutral` | Los tres acentos de marca. |
|
|
545
|
+
| `--vuno-success` · `--vuno-info` · `--vuno-warning` · `--vuno-error` | Los cuatro de estado. |
|
|
546
|
+
| `--vuno-*-contrast` | El texto que va **encima** de cada acento en su variante sólida. |
|
|
547
|
+
| `--vuno-font-sans` · `--vuno-font-mono` | La tipografía. El módulo **nombra** la familia y no la carga: un `@import` a un servidor de fuentes convertiría cada visita de tu proyecto en una petición a un tercero. Cárgala tú —con `@nuxt/fonts` o con tu propio `@font-face`—; si no está, la pila de respaldo se encarga. |
|
|
548
|
+
| `--vuno-surface` · `--vuno-surface-1` · `--vuno-surface-2` · `--vuno-surface-inverse` | La escala de elevación: **cada cosa sube un escalón sobre lo que la sostiene**. La página es la base —blanco en claro, negro en oscuro—, lo que se levanta de ella es el 1 y lo que se levanta dentro de algo ya levantado es el 2. |
|
|
549
|
+
| `--vuno-text-strong` · `-body` · `-muted` · `-subtle` · `-inverse` | El texto por jerarquía, no por color. |
|
|
550
|
+
| `--vuno-border` · `--vuno-border-strong` | El borde que decora y el que delimita un control. |
|
|
551
|
+
| `--vuno-radius` | La curvatura de todo. |
|
|
552
|
+
| `--vuno-backdrop` | El velo que oscurece detrás de un diálogo. |
|
|
553
|
+
|
|
554
|
+
Dos cosas que ahorran un rato:
|
|
555
|
+
|
|
556
|
+
- **El tema oscuro se redefine aparte**, bajo `.dark`. Si solo cambias `:root`, el modo oscuro se queda con el valor de serie.
|
|
557
|
+
- **Cada acento sólido necesita su contraste.** Un `--vuno-warning` claro con texto blanco no se lee; por eso el ámbar de serie trae texto oscuro.
|
|
558
|
+
|
|
559
|
+
```css
|
|
560
|
+
.dark {
|
|
561
|
+
--vuno-primary: var(--color-indigo-400);
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### Los tres niveles del resto
|
|
566
|
+
|
|
567
|
+
Para lo que no es color: la forma de un componente concreto, sus iconos y sus textos.
|
|
451
568
|
|
|
452
569
|
```ts
|
|
453
570
|
// app.config.ts — para toda la aplicación
|
|
454
571
|
export default defineAppConfig({
|
|
455
|
-
ui: { colors: { primary: 'indigo' } },
|
|
456
572
|
vuno: {
|
|
457
573
|
formSection: { slots: { root: 'border-dashed' } },
|
|
458
574
|
icons: { slugEdit: 'lucide:wand-sparkles' },
|
|
575
|
+
locale: 'es-ES',
|
|
459
576
|
messages: { selectPlaceholder: 'Elige una opción' },
|
|
460
577
|
},
|
|
461
578
|
})
|
|
@@ -466,7 +583,9 @@ export default defineAppConfig({
|
|
|
466
583
|
<VForm :ui="{ sections: 'gap-8' }" ... />
|
|
467
584
|
```
|
|
468
585
|
|
|
469
|
-
|
|
586
|
+
Se funden en orden de especificidad creciente —tema por defecto, `app.config`, prop `ui`— y los conflictos los deshace `tailwind-merge`, así que la última clase gana de verdad y no depende del orden de la hoja.
|
|
587
|
+
|
|
588
|
+
Los textos e iconos están todos en `vuno.messages` y `vuno.icons`: el paquete no impone idioma ni colección de iconos. El formato de fechas, números y monedas sale de `vuno.locale`, que se declara en vez de leerse del navegador —con render en servidor, adivinarlo da un número en el HTML y otro al hidratar—.
|
|
470
589
|
|
|
471
590
|
## Estado
|
|
472
591
|
|
|
@@ -474,9 +593,13 @@ En desarrollo.
|
|
|
474
593
|
|
|
475
594
|
### Nota sobre pruebas automatizadas
|
|
476
595
|
|
|
477
|
-
|
|
596
|
+
Tres trampas, las tres medidas aquí, que hacen que una comprobación afirme lo contrario de lo que pasa.
|
|
597
|
+
|
|
598
|
+
**Una pestaña oculta no pinta.** Con la ventana de fondo, `document.visibilityState` es `hidden`, `requestAnimationFrame` **no dispara nunca** y con él se paran las transiciones: un diálogo puede no llegar a abrirse y una captura caducar. El DOM y las medidas de disposición sí funcionan, así que se puede comprobar casi todo; lo que no se puede es dar por cerrado un componente porque su nodo siga ahí. Mira el estado (`opacity`, `data-state`) y no la existencia del nodo, o haz la prueba con la pestaña delante.
|
|
599
|
+
|
|
600
|
+
**`getComputedStyle` se queda con el valor viejo tras cambiar un token.** Si redefines `--vuno-primary` y vuelves a leer un elemento que ya existía, puede devolverte el color anterior aunque la variable ya valga otra cosa. Se nota porque el valor sale en `oklab` en vez de en `oklch`. Lee sobre un elemento **creado después** del cambio —o sobre un clon del que te interesa— y el valor es el nuevo.
|
|
478
601
|
|
|
479
|
-
|
|
602
|
+
**Un control de Reka no responde a un clic sintético.** Sus botones actúan en `pointerdown`, no en `click`, y las flechas necesitan foco de verdad: un `.click()` o un `.focus()` desde el script no disparan nada y parece que el componente está roto. Los controles nativos —casilla, interruptor, radio— sí responden a `click()`, así que ahí el clic sintético vale.
|
|
480
603
|
|
|
481
604
|
## Licencia
|
|
482
605
|
|
package/dist/module.d.mts
CHANGED
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
interface ModuleOptions {
|
|
5
|
-
prefix?: string;
|
|
6
|
-
}
|
|
7
|
-
declare const module$1: NuxtModule<ModuleOptions>;
|
|
8
|
-
|
|
9
|
-
export { module$1 as default };
|
|
10
|
-
export type { ModuleOptions };
|
|
1
|
+
export * from "/woodpecker/src/github.com/groupteknology/vuno/packages/core/src/module.js";
|
|
2
|
+
export { default } from "/woodpecker/src/github.com/groupteknology/vuno/packages/core/src/module.js";
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,28 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createJiti } from "file:///woodpecker/src/github.com/groupteknology/vuno/node_modules/.pnpm/jiti@2.7.0/node_modules/jiti/lib/jiti.mjs";
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const jiti = createJiti(import.meta.url, {
|
|
4
|
+
"interopDefault": true,
|
|
5
|
+
"alias": {
|
|
6
|
+
"@groupteknology/vuno": "/woodpecker/src/github.com/groupteknology/vuno/packages/core"
|
|
6
7
|
},
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
moduleDependencies: {
|
|
12
|
-
"@nuxt/ui": {}
|
|
13
|
-
},
|
|
14
|
-
setup(options, nuxt) {
|
|
15
|
-
const resolver = createResolver(import.meta.url);
|
|
16
|
-
nuxt.options.alias["#vuno"] = resolver.resolve("./runtime/app");
|
|
17
|
-
addComponentsDir({
|
|
18
|
-
global: true,
|
|
19
|
-
path: resolver.resolve("./runtime/app/components"),
|
|
20
|
-
pathPrefix: false,
|
|
21
|
-
prefix: options.prefix
|
|
22
|
-
});
|
|
23
|
-
addImportsDir(resolver.resolve("./runtime/app/composables"));
|
|
24
|
-
nuxt.options.css.push(resolver.resolve("./runtime/app/assets/css/main.css"));
|
|
8
|
+
"transformOptions": {
|
|
9
|
+
"babel": {
|
|
10
|
+
"plugins": []
|
|
11
|
+
}
|
|
25
12
|
}
|
|
26
|
-
})
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
/** @type {import("/woodpecker/src/github.com/groupteknology/vuno/packages/core/src/module.js")} */
|
|
16
|
+
const _module = await jiti.import("/woodpecker/src/github.com/groupteknology/vuno/packages/core/src/module.ts");
|
|
27
17
|
|
|
28
|
-
export
|
|
18
|
+
export default _module?.default ?? _module;
|
package/dist/types.d.mts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import type { ModuleHooks, ModuleRuntimeHooks, ModuleRuntimeConfig, ModulePublicRuntimeConfig } from './module.mjs'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
declare module '#app' {
|
|
4
|
+
interface RuntimeNuxtHooks extends ModuleRuntimeHooks {}
|
|
5
|
+
}
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
declare module '@nuxt/schema' {
|
|
8
|
+
interface NuxtHooks extends ModuleHooks {}
|
|
9
|
+
interface RuntimeConfig extends ModuleRuntimeConfig {}
|
|
10
|
+
interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export * from "./module.mjs"
|
package/package.json
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@groupteknology/vuno",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Formularios, tablas y diálogos declarativos para Nuxt 4, con componentes propios y tokens sobreescribibles.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"nuxt",
|
|
7
|
+
"nuxt-module",
|
|
8
|
+
"vue",
|
|
9
|
+
"form",
|
|
10
|
+
"table",
|
|
11
|
+
"crud",
|
|
12
|
+
"datatable",
|
|
13
|
+
"typescript"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/groupteknology/vuno#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/groupteknology/vuno/issues"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/groupteknology/vuno.git",
|
|
22
|
+
"directory": "packages/core"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"author": "Diego Otayza <diegootayza@live.com>",
|
|
4
26
|
"type": "module",
|
|
5
27
|
"exports": {
|
|
6
28
|
".": {
|
|
@@ -21,63 +43,46 @@
|
|
|
21
43
|
"dist"
|
|
22
44
|
],
|
|
23
45
|
"dependencies": {
|
|
24
|
-
"@
|
|
25
|
-
"@
|
|
46
|
+
"@floating-ui/dom": "^1.8.0",
|
|
47
|
+
"@vueuse/core": "^15.0.0",
|
|
48
|
+
"@iconify-json/lucide": "^1.2.134",
|
|
49
|
+
"@nuxt/icon": "^2.5.1",
|
|
50
|
+
"@nuxt/kit": "^4.5.2",
|
|
51
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
52
|
+
"gsap": "^3.15.0",
|
|
53
|
+
"tailwind-merge": "^3.7.0",
|
|
54
|
+
"tailwindcss": "^4.3.3"
|
|
26
55
|
},
|
|
27
56
|
"devDependencies": {
|
|
28
57
|
"@nuxt/module-builder": "^1.0.3",
|
|
58
|
+
"@nuxt/schema": "^4.5.2",
|
|
29
59
|
"@tanstack/vue-query": "^5.0.0",
|
|
30
|
-
"@types/node": "^
|
|
60
|
+
"@types/node": "^26.6.2",
|
|
61
|
+
"@vitejs/plugin-vue": "^6.0.9",
|
|
62
|
+
"@vitest/coverage-v8": "^5.0.1",
|
|
63
|
+
"@vue/test-utils": "^2.5.0",
|
|
64
|
+
"happy-dom": "^20.14.5",
|
|
31
65
|
"nuxt": "^4.5.2",
|
|
32
66
|
"typescript": "^6.0.3",
|
|
33
|
-
"vitest": "^
|
|
34
|
-
"vue": "^3.5.
|
|
35
|
-
"vue-tsc": "^3.3.11"
|
|
36
|
-
"zod": "^4.6.2"
|
|
37
|
-
},
|
|
38
|
-
"description": "Formularios, tablas y diálogos declarativos para Nuxt 4, construidos sobre Nuxt UI y sin estilos propios.",
|
|
39
|
-
"keywords": [
|
|
40
|
-
"nuxt",
|
|
41
|
-
"nuxt-module",
|
|
42
|
-
"nuxt-ui",
|
|
43
|
-
"vue",
|
|
44
|
-
"form",
|
|
45
|
-
"table",
|
|
46
|
-
"crud",
|
|
47
|
-
"datatable",
|
|
48
|
-
"typescript"
|
|
49
|
-
],
|
|
50
|
-
"license": "MIT",
|
|
51
|
-
"author": "Diego Otayza <diegootayza@live.com>",
|
|
52
|
-
"repository": {
|
|
53
|
-
"type": "git",
|
|
54
|
-
"url": "git+https://github.com/groupteknology/vuno.git",
|
|
55
|
-
"directory": "packages/core"
|
|
67
|
+
"vitest": "^5.0.1",
|
|
68
|
+
"vue": "^3.5.43",
|
|
69
|
+
"vue-tsc": "^3.3.11"
|
|
56
70
|
},
|
|
57
|
-
"
|
|
58
|
-
"
|
|
71
|
+
"peerDependencies": {
|
|
72
|
+
"nuxt": "^4.5.2",
|
|
73
|
+
"vue": "^3.5.43"
|
|
59
74
|
},
|
|
60
|
-
"homepage": "https://github.com/groupteknology/vuno#readme",
|
|
61
75
|
"publishConfig": {
|
|
62
76
|
"access": "public"
|
|
63
77
|
},
|
|
64
|
-
"peerDependencies": {
|
|
65
|
-
"@nuxt/ui": "^4.0.0",
|
|
66
|
-
"@tanstack/vue-query": "^5.0.0",
|
|
67
|
-
"nuxt": "^4.0.0",
|
|
68
|
-
"vue": "^3.5.0"
|
|
69
|
-
},
|
|
70
|
-
"peerDependenciesMeta": {
|
|
71
|
-
"@tanstack/vue-query": {
|
|
72
|
-
"optional": true
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
78
|
"scripts": {
|
|
76
79
|
"build": "nuxt-module-build build",
|
|
77
|
-
"clean": "
|
|
80
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { force: true, recursive: true })\"",
|
|
78
81
|
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare",
|
|
79
|
-
"
|
|
82
|
+
"dev:watch": "node scripts/watch-build.mjs",
|
|
80
83
|
"test": "vitest run",
|
|
81
|
-
"test:
|
|
84
|
+
"test:coverage": "vitest run --coverage",
|
|
85
|
+
"test:watch": "vitest",
|
|
86
|
+
"typecheck": "pnpm dev:prepare && vue-tsc --noEmit -p tsconfig.json"
|
|
82
87
|
}
|
|
83
88
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@import "tailwindcss";@import "@nuxt/ui";@source "../../**/*";
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { VunoTableCellProps } from '#vuno/types/table';
|
|
2
|
-
type __VLS_Props = VunoTableCellProps<'badge'>;
|
|
3
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
4
|
-
declare const _default: typeof __VLS_export;
|
|
5
|
-
export default _default;
|