@nexdom/uimed-vue 2.0.0-beta.8 → 2.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/README.md +1 -1
- package/dist/_virtual/_rolldown/runtime.js +7 -0
- package/dist/components/app-bar/app-bar.js +5 -0
- package/dist/components/app-bar/app-bar.vue_vue_type_script_setup_true_lang.js +286 -0
- package/dist/components/app-bar/types.d.ts +96 -0
- package/dist/components/button/button.js +5 -0
- package/dist/components/button/button.vue.d.ts +31 -0
- package/dist/components/button/button.vue_vue_type_script_setup_true_lang.js +97 -0
- package/dist/components/button/types.d.ts +65 -0
- package/dist/components/data-sets/data-set/data-set.js +5 -0
- package/dist/components/data-sets/data-set/data-set.vue.d.ts +47 -0
- package/dist/components/data-sets/data-set/data-set.vue_vue_type_script_setup_true_lang.js +157 -0
- package/dist/components/data-sets/data-set/types.d.ts +93 -0
- package/dist/components/data-sets/data-set-bar.js +5 -0
- package/dist/components/data-sets/data-set-bar.vue_vue_type_script_setup_true_lang.js +99 -0
- package/dist/components/data-sets/data-set-item/data-set-item.js +5 -0
- package/dist/components/data-sets/data-set-item/data-set-item.vue.d.ts +35 -0
- package/dist/components/data-sets/data-set-item/data-set-item.vue_vue_type_script_setup_true_lang.js +57 -0
- package/dist/components/data-sets/data-set-item/types.d.ts +42 -0
- package/dist/components/details/details.js +5 -0
- package/dist/components/details/details.vue.d.ts +28 -0
- package/dist/components/details/details.vue_vue_type_script_setup_true_lang.js +56 -0
- package/dist/components/details/types.d.ts +29 -0
- package/dist/components/dialogs/dialog/dialog-host-key.js +10 -0
- package/dist/components/dialogs/dialog/dialog.js +5 -0
- package/dist/components/dialogs/dialog/dialog.vue.d.ts +36 -0
- package/dist/components/dialogs/dialog/dialog.vue_vue_type_script_setup_true_lang.js +112 -0
- package/dist/components/dialogs/dialog/types.d.ts +47 -0
- package/dist/components/dialogs/dialog-host.js +5 -0
- package/dist/components/dialogs/dialog-host.vue_vue_type_script_setup_true_lang.js +81 -0
- package/dist/components/dialogs/toast.js +5 -0
- package/dist/components/dialogs/toast.vue_vue_type_script_setup_true_lang.js +35 -0
- package/dist/components/footer/footer.js +5 -0
- package/dist/components/footer/footer.vue_vue_type_script_setup_true_lang.js +31 -0
- package/dist/components/footer/types.d.ts +16 -0
- package/dist/components/form/form.js +5 -0
- package/dist/components/form/form.vue.d.ts +32 -0
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js +37 -0
- package/dist/components/form/types.d.ts +15 -0
- package/dist/components/grid/column/column.js +5 -0
- package/dist/components/grid/column/column.vue.d.ts +33 -0
- package/dist/components/grid/column/column.vue_vue_type_script_setup_true_lang.js +45 -0
- package/dist/components/grid/column/types.d.ts +27 -0
- package/dist/components/grid/container/container.js +5 -0
- package/dist/components/grid/container/container.vue.d.ts +27 -0
- package/dist/components/grid/container/container.vue_vue_type_script_setup_true_lang.js +33 -0
- package/dist/components/grid/container/types.d.ts +17 -0
- package/dist/components/grid/row/row.js +5 -0
- package/dist/components/grid/row/row.vue.d.ts +29 -0
- package/dist/components/grid/row/row.vue_vue_type_script_setup_true_lang.js +61 -0
- package/dist/components/grid/row/types.d.ts +63 -0
- package/dist/components/icon-button/icon-button.js +5 -0
- package/dist/components/icon-button/icon-button.vue.d.ts +23 -0
- package/dist/components/icon-button/icon-button.vue_vue_type_script_setup_true_lang.js +51 -0
- package/dist/components/icon-button/types.d.ts +32 -0
- package/dist/components/img/img.js +5 -0
- package/dist/components/img/img.vue.d.ts +23 -0
- package/dist/components/img/img.vue_vue_type_script_setup_true_lang.js +61 -0
- package/dist/components/img/types.d.ts +43 -0
- package/dist/components/inputs/autocomplete-field/autocomplete-field.js +5 -0
- package/dist/components/inputs/autocomplete-field/autocomplete-field.vue.d.ts +33 -0
- package/dist/components/inputs/autocomplete-field/autocomplete-field.vue_vue_type_script_setup_true_lang.js +161 -0
- package/dist/components/inputs/autocomplete-field/types.d.ts +84 -0
- package/dist/components/inputs/checkbox/checkbox.js +5 -0
- package/dist/components/inputs/checkbox/checkbox.vue.d.ts +33 -0
- package/dist/components/inputs/checkbox/checkbox.vue_vue_type_script_setup_true_lang.js +71 -0
- package/dist/components/inputs/checkbox/types.d.ts +35 -0
- package/dist/components/inputs/date-time-field/date-time-field.js +5 -0
- package/dist/components/inputs/date-time-field/date-time-field.vue.d.ts +32 -0
- package/dist/components/inputs/date-time-field/date-time-field.vue_vue_type_script_setup_true_lang.js +205 -0
- package/dist/components/inputs/date-time-field/types.d.ts +84 -0
- package/dist/components/inputs/field-loader.js +5 -0
- package/dist/components/inputs/field-loader.vue_vue_type_script_setup_true_lang.js +30 -0
- package/dist/components/inputs/mask-field/mask-field.js +5 -0
- package/dist/components/inputs/mask-field/mask-field.vue.d.ts +32 -0
- package/dist/components/inputs/mask-field/mask-field.vue_vue_type_script_setup_true_lang.js +120 -0
- package/dist/components/inputs/mask-field/types.d.ts +118 -0
- package/dist/components/inputs/text-field/text-field.js +5 -0
- package/dist/components/inputs/text-field/text-field.vue.d.ts +30 -0
- package/dist/components/inputs/text-field/text-field.vue_vue_type_script_setup_true_lang.js +119 -0
- package/dist/components/inputs/text-field/types.d.ts +70 -0
- package/dist/components/link/link.js +5 -0
- package/dist/components/link/link.vue.d.ts +27 -0
- package/dist/components/link/link.vue_vue_type_script_setup_true_lang.js +32 -0
- package/dist/components/link/types.d.ts +18 -0
- package/dist/components/main/main.js +5 -0
- package/dist/components/main/main.vue.d.ts +33 -0
- package/dist/components/main/main.vue_vue_type_script_setup_true_lang.js +104 -0
- package/dist/components/main/types.d.ts +75 -0
- package/dist/components/navigation-menu/navigation-menu.js +5 -0
- package/dist/components/navigation-menu/navigation-menu.vue_vue_type_script_setup_true_lang.js +207 -0
- package/dist/components/navigation-menu/types.d.ts +62 -0
- package/dist/components/page-transition/page-transition.js +5 -0
- package/dist/components/page-transition/page-transition.vue.d.ts +40 -0
- package/dist/components/page-transition/page-transition.vue_vue_type_script_setup_true_lang.js +27 -0
- package/dist/components/page-transition/types.d.ts +18 -0
- package/dist/components/sections/section/section.js +5 -0
- package/dist/components/sections/section/section.vue.d.ts +28 -0
- package/dist/components/sections/section/section.vue_vue_type_script_setup_true_lang.js +108 -0
- package/dist/components/sections/section/types.d.ts +80 -0
- package/dist/components/sections/section-content/section-content.js +5 -0
- package/dist/components/sections/section-content/section-content.vue.d.ts +27 -0
- package/dist/components/sections/section-content/section-content.vue_vue_type_script_setup_true_lang.js +16 -0
- package/dist/components/skeleton-loader/skeleton-loader.js +5 -0
- package/dist/components/skeleton-loader/skeleton-loader.vue_vue_type_script_setup_true_lang.js +65 -0
- package/dist/components/table/table.js +5 -0
- package/dist/components/table/table.vue.d.ts +19 -0
- package/dist/components/table/table.vue_vue_type_script_setup_true_lang.js +84 -0
- package/dist/components/table/types.d.ts +51 -0
- package/dist/components.d.ts +23 -940
- package/dist/components.js +23 -1254
- package/dist/composables/alignment/alignment.js +41 -0
- package/dist/composables/alignment/types.d.ts +12 -0
- package/dist/composables/button/button.js +54 -0
- package/dist/composables/colors/constants.js +27 -0
- package/dist/composables/colors/types.d.ts +4 -0
- package/dist/composables/colors/use-vuetify-background-color.js +16 -0
- package/dist/composables/colors/use-vuetify-color.js +11 -0
- package/dist/composables/colors/use-vuetify-text-color.js +12 -0
- package/dist/composables/data-set/data-set.js +128 -0
- package/dist/composables/dialogs/types.d.ts +88 -0
- package/dist/composables/dialogs/use-confirm.d.ts +21 -0
- package/dist/composables/dialogs/use-confirm.js +55 -0
- package/dist/composables/dialogs/use-decorative-timer.js +25 -0
- package/dist/composables/dialogs/use-dialog-focus.js +64 -0
- package/dist/composables/dialogs/use-dialog-loading.js +13 -0
- package/dist/composables/dialogs/use-dialog.d.ts +36 -0
- package/dist/composables/dialogs/use-dialog.js +73 -0
- package/dist/composables/dialogs/use-run-or-toast.d.ts +27 -0
- package/dist/composables/dialogs/use-run-or-toast.js +65 -0
- package/dist/composables/dialogs/use-toast.d.ts +25 -0
- package/dist/composables/dialogs/use-toast.js +39 -0
- package/dist/composables/dimensions/dimensions.js +18 -0
- package/dist/composables/inputs/autocomplete-field.js +39 -0
- package/dist/composables/inputs/date-time-field.js +109 -0
- package/dist/composables/inputs/fields.js +28 -0
- package/dist/composables/inputs/mask-field.js +133 -0
- package/dist/composables/inputs/rules.js +16 -0
- package/dist/composables/inputs/text-field.js +81 -0
- package/dist/composables/navigation/types.d.ts +54 -0
- package/dist/composables/navigation/use-navigation-rail.js +163 -0
- package/dist/composables/navigation/use-navigation-search-shortcut.js +96 -0
- package/dist/composables/navigation/use-route-props.js +21 -0
- package/dist/composables/navigation/use-unsaved-changes.d.ts +35 -0
- package/dist/composables/navigation/use-unsaved-changes.js +88 -0
- package/dist/composables/section/section.js +34 -0
- package/dist/composables.d.ts +6 -67
- package/dist/composables.js +6 -65
- package/dist/consts/icons.d.ts +67 -0
- package/dist/consts/icons.js +69 -0
- package/dist/consts/locale.js +12 -0
- package/dist/consts/types.d.ts +12 -0
- package/dist/index.d.ts +1 -13
- package/dist/index.js +39 -14
- package/dist/plugins.d.ts +15 -4
- package/dist/plugins.js +54 -3
- package/dist/styles/fonts/UnimedSlab-Regular.woff2 +0 -0
- package/dist/styles/fonts/fonts.css +5 -0
- package/dist/styles/settings.scss +155 -0
- package/dist/unit-test.js +11 -7
- package/package.json +11 -11
- package/skills/uimed-vue/SKILL.md +113 -0
- package/skills/uimed-vue/references/api/components/autocomplete-field.md +45 -0
- package/skills/uimed-vue/references/api/components/button.md +48 -0
- package/skills/uimed-vue/references/api/components/checkbox.md +36 -0
- package/skills/uimed-vue/references/api/components/data-sets/data-set-item.md +61 -0
- package/skills/uimed-vue/references/api/components/data-sets/data-set.md +67 -0
- package/skills/uimed-vue/references/api/components/date-time-field.md +44 -0
- package/skills/uimed-vue/references/api/components/details.md +33 -0
- package/skills/uimed-vue/references/api/components/dialog.md +70 -0
- package/skills/uimed-vue/references/api/components/form.md +43 -0
- package/skills/uimed-vue/references/api/components/grid/column.md +41 -0
- package/skills/uimed-vue/references/api/components/grid/container.md +32 -0
- package/skills/uimed-vue/references/api/components/grid/row.md +37 -0
- package/skills/uimed-vue/references/api/components/icon-button.md +37 -0
- package/skills/uimed-vue/references/api/components/img.md +34 -0
- package/skills/uimed-vue/references/api/components/link.md +31 -0
- package/skills/uimed-vue/references/api/components/main.md +174 -0
- package/skills/uimed-vue/references/api/components/mask-field.md +60 -0
- package/skills/uimed-vue/references/api/components/page-transition.md +37 -0
- package/skills/uimed-vue/references/api/components/sections/section-content.md +23 -0
- package/skills/uimed-vue/references/api/components/sections/section.md +61 -0
- package/skills/uimed-vue/references/api/components/table.md +35 -0
- package/skills/uimed-vue/references/api/components/text-field.md +42 -0
- package/skills/uimed-vue/references/api/composables/use-confirm.md +96 -0
- package/skills/uimed-vue/references/api/composables/use-dialog.md +95 -0
- package/skills/uimed-vue/references/api/composables/use-run-or-toast.md +58 -0
- package/skills/uimed-vue/references/api/composables/use-toast.md +48 -0
- package/skills/uimed-vue/references/api/composables/use-unsaved-changes.md +106 -0
- package/skills/uimed-vue/references/api/index.md +1 -0
- package/skills/uimed-vue/references/guide/components/autocomplete-field.md +256 -0
- package/skills/uimed-vue/references/guide/components/button.md +155 -0
- package/skills/uimed-vue/references/guide/components/checkbox.md +113 -0
- package/skills/uimed-vue/references/guide/components/data-set.md +370 -0
- package/skills/uimed-vue/references/guide/components/date-time-field.md +202 -0
- package/skills/uimed-vue/references/guide/components/details.md +76 -0
- package/skills/uimed-vue/references/guide/components/dialog.md +269 -0
- package/skills/uimed-vue/references/guide/components/form.md +96 -0
- package/skills/uimed-vue/references/guide/components/icon-button.md +76 -0
- package/skills/uimed-vue/references/guide/components/img.md +128 -0
- package/skills/uimed-vue/references/guide/components/layout.md +323 -0
- package/skills/uimed-vue/references/guide/components/link.md +47 -0
- package/skills/uimed-vue/references/guide/components/main.md +435 -0
- package/skills/uimed-vue/references/guide/components/mask-field.md +256 -0
- package/skills/uimed-vue/references/guide/components/page-transition.md +111 -0
- package/skills/uimed-vue/references/guide/components/section.md +232 -0
- package/skills/uimed-vue/references/guide/components/table.md +102 -0
- package/skills/uimed-vue/references/guide/components/text-field.md +172 -0
- package/skills/uimed-vue/references/guide/composables/use-confirm.md +123 -0
- package/skills/uimed-vue/references/guide/composables/use-dialog.md +102 -0
- package/skills/uimed-vue/references/guide/composables/use-run-or-toast.md +55 -0
- package/skills/uimed-vue/references/guide/composables/use-toast.md +57 -0
- package/skills/uimed-vue/references/guide/composables/use-unsaved-changes.md +129 -0
- package/skills/uimed-vue/references/guide/getting-started.md +135 -0
- package/skills/uimed-vue/references/guide/icons.md +71 -0
- package/skills/uimed-vue/references/guide/index.md +51 -0
- package/skills/uimed-vue/references/guide/migration-v1-to-v2.md +191 -0
- package/skills/uimed-vue/references/guide/unit-testing.md +85 -0
- package/AGENTS.md +0 -160
- package/CLAUDE.md +0 -1
- package/dist/types-BPXXtbmW.d.ts +0 -5
- package/dist/use-toast-CACuYhK_.js +0 -53
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Confirmações
|
|
2
|
+
|
|
3
|
+
Uma vez que carregamos o [Componente base](../components/main.md), podemos estar tirando proveito da nossa composable para pedir a confirmação do usuário antes de executar uma ação.
|
|
4
|
+
|
|
5
|
+
A ação só é executada depois que o usuário clica no botão de confirmação. Enquanto ela executa, o botão de confirmação apresenta um indicador de carregamento, o botão de cancelamento fica desabilitado e o diálogo não pode ser fechado. Ao terminar, o diálogo fecha e `confirm` devolve o retorno da ação.
|
|
6
|
+
|
|
7
|
+
Se o usuário cancelar, ou se a ação falhar, `confirm` devolve `false`. Em caso de falha, a mensagem do erro é apresentada em um [toast](./use-toast.md), assim como no [Run or toast](./use-run-or-toast.md).
|
|
8
|
+
|
|
9
|
+
## Uso
|
|
10
|
+
|
|
11
|
+
### Confirmação
|
|
12
|
+
|
|
13
|
+
O diálogo apresenta os botões "Cancelar" e "Confirmar", com o foco inicial em "Cancelar".
|
|
14
|
+
|
|
15
|
+
A partir do terceiro parâmetro, `confirm` repassa os parâmetros para a ação, assim como o `run` do [Run or toast](./use-run-or-toast.md). O `isRunning` indica se a ação está em execução.
|
|
16
|
+
|
|
17
|
+
```vue
|
|
18
|
+
<template>
|
|
19
|
+
<u-main>
|
|
20
|
+
<u-button :loading="isRunning" @click="save">Salvar alterações</u-button>
|
|
21
|
+
<p>Resultado: {{ result }}</p>
|
|
22
|
+
</u-main>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script lang="ts" setup>
|
|
26
|
+
import { ref } from "vue";
|
|
27
|
+
import { UMain, UButton } from "@nexdom/uimed-vue/components";
|
|
28
|
+
import { useConfirm } from "@nexdom/uimed-vue/composables";
|
|
29
|
+
|
|
30
|
+
const { confirm, isRunning } = useConfirm();
|
|
31
|
+
const result = ref<string | false>();
|
|
32
|
+
|
|
33
|
+
function saveChanges(changes: string): Promise<string> {
|
|
34
|
+
return new Promise((resolve) => {
|
|
35
|
+
setTimeout(() => resolve(`${changes} salvas`), 1500);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function save() {
|
|
40
|
+
result.value = await confirm(
|
|
41
|
+
{ title: "Salvar alterações", message: "Deseja salvar as alterações feitas no cadastro?" },
|
|
42
|
+
saveChanges,
|
|
43
|
+
"Alterações",
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Ação destrutiva
|
|
50
|
+
|
|
51
|
+
Personalize os textos dos botões com `confirmText` e `cancelText`, e a cor do botão de confirmação com `color`.
|
|
52
|
+
|
|
53
|
+
```vue
|
|
54
|
+
<template>
|
|
55
|
+
<u-main>
|
|
56
|
+
<u-button :loading="isRunning" color="danger" @click="remove">Excluir paciente</u-button>
|
|
57
|
+
</u-main>
|
|
58
|
+
</template>
|
|
59
|
+
|
|
60
|
+
<script lang="ts" setup>
|
|
61
|
+
import { UMain, UButton } from "@nexdom/uimed-vue/components";
|
|
62
|
+
import { useConfirm } from "@nexdom/uimed-vue/composables";
|
|
63
|
+
|
|
64
|
+
const { confirm, isRunning } = useConfirm();
|
|
65
|
+
|
|
66
|
+
async function remove() {
|
|
67
|
+
await confirm(
|
|
68
|
+
{
|
|
69
|
+
title: "Excluir paciente",
|
|
70
|
+
message: "Esta ação não pode ser desfeita.",
|
|
71
|
+
confirmText: "Excluir",
|
|
72
|
+
cancelText: "Manter",
|
|
73
|
+
color: "danger",
|
|
74
|
+
},
|
|
75
|
+
() => new Promise((resolve) => setTimeout(() => resolve("Paciente excluído"), 1500)),
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
</script>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Falha na ação
|
|
82
|
+
|
|
83
|
+
```vue
|
|
84
|
+
<template>
|
|
85
|
+
<u-main>
|
|
86
|
+
<u-button :loading="isRunning" color="danger" variant="secondary" @click="fail">
|
|
87
|
+
Excluir com falha
|
|
88
|
+
</u-button>
|
|
89
|
+
</u-main>
|
|
90
|
+
</template>
|
|
91
|
+
|
|
92
|
+
<script lang="ts" setup>
|
|
93
|
+
import { UMain, UButton } from "@nexdom/uimed-vue/components";
|
|
94
|
+
import { useConfirm } from "@nexdom/uimed-vue/composables";
|
|
95
|
+
|
|
96
|
+
const { confirm, isRunning } = useConfirm();
|
|
97
|
+
|
|
98
|
+
async function fail() {
|
|
99
|
+
await confirm(
|
|
100
|
+
{ title: "Excluir paciente", message: "Esta ação não pode ser desfeita.", color: "danger" },
|
|
101
|
+
() =>
|
|
102
|
+
new Promise((_, reject) => {
|
|
103
|
+
const error = new Error("Não foi possível excluir o paciente.");
|
|
104
|
+
setTimeout(() => reject(error), 1500);
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
</script>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Fechando o diálogo
|
|
112
|
+
|
|
113
|
+
Além do botão de cancelamento, o usuário pode fechar o diálogo pela tecla `Esc` ou clicando fora dele. Nesses casos, `confirm` devolve `false` ao fim da animação de fechamento.
|
|
114
|
+
|
|
115
|
+
O botão "voltar" do navegador também fecha o diálogo, sem sair da página, em aplicações que usam o [Vue Router](https://router.vuejs.org/). A exceção é quando o "voltar" leva a uma página aberta com `router.replace`, como a página pela qual o usuário entrou na aplicação: nesse caso, a navegação acontece e o diálogo continua aberto.
|
|
116
|
+
|
|
117
|
+
Enquanto a ação estiver em execução, o diálogo não fecha por nenhum desses meios e, exceto no caso do `router.replace` acima, o "voltar" também não sai da página.
|
|
118
|
+
|
|
119
|
+
## Ver também
|
|
120
|
+
|
|
121
|
+
- Consulte a referência de [API do useConfirm](../../api/composables/use-confirm.md) para mais informações.
|
|
122
|
+
- Para apresentar mensagens ou perguntas sem executar uma ação, use a composable [useDialog](./use-dialog.md).
|
|
123
|
+
- Para apresentar conteúdo próprio, como um formulário, em uma janela modal, use o componente [Dialog](../components/dialog.md).
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Diálogos
|
|
2
|
+
|
|
3
|
+
Uma vez que carregamos o [Componente base](../components/main.md), podemos estar tirando proveito da nossa composable para apresentação de diálogos, que interrompem o usuário com uma mensagem e aguardam sua resposta.
|
|
4
|
+
|
|
5
|
+
Os diálogos são apresentados um de cada vez, na ordem em que foram solicitados. Se um diálogo for solicitado enquanto outro estiver aberto, ele será apresentado assim que o atual for fechado.
|
|
6
|
+
|
|
7
|
+
## Uso
|
|
8
|
+
|
|
9
|
+
### Diálogo simples
|
|
10
|
+
|
|
11
|
+
Sem a opção `actions`, o diálogo apresenta apenas o botão "Fechar" e resolve `undefined`.
|
|
12
|
+
|
|
13
|
+
```vue
|
|
14
|
+
<template>
|
|
15
|
+
<u-main>
|
|
16
|
+
<u-button @click="openSimple">Diálogo simples</u-button>
|
|
17
|
+
</u-main>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script lang="ts" setup>
|
|
21
|
+
import { UMain, UButton } from "@nexdom/uimed-vue/components";
|
|
22
|
+
import { useDialog } from "@nexdom/uimed-vue/composables";
|
|
23
|
+
|
|
24
|
+
const { dialog } = useDialog();
|
|
25
|
+
|
|
26
|
+
async function openSimple() {
|
|
27
|
+
await dialog({
|
|
28
|
+
title: "Cadastro enviado",
|
|
29
|
+
message: "Seu cadastro foi enviado para análise.",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Ações personalizadas
|
|
36
|
+
|
|
37
|
+
Cada ação da opção `actions` vira um botão, na ordem informada e alinhado à direita. O diálogo resolve o `value` da ação clicada.
|
|
38
|
+
|
|
39
|
+
Por padrão, a última ação usa a variante `primary` e as demais, a variante `ghost`.
|
|
40
|
+
|
|
41
|
+
```vue
|
|
42
|
+
<template>
|
|
43
|
+
<u-main>
|
|
44
|
+
<u-button @click="openWithActions">Ações personalizadas</u-button>
|
|
45
|
+
<p>Resposta: {{ answer ?? "nenhuma" }}</p>
|
|
46
|
+
</u-main>
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
|
+
<script lang="ts" setup>
|
|
50
|
+
import { ref } from "vue";
|
|
51
|
+
import { UMain, UButton } from "@nexdom/uimed-vue/components";
|
|
52
|
+
import { useDialog } from "@nexdom/uimed-vue/composables";
|
|
53
|
+
|
|
54
|
+
const { dialog } = useDialog();
|
|
55
|
+
const answer = ref<string>();
|
|
56
|
+
|
|
57
|
+
async function openWithActions() {
|
|
58
|
+
answer.value = await dialog({
|
|
59
|
+
title: "Sessão expirando",
|
|
60
|
+
message: "Sua sessão irá expirar em breve. Deseja continuar conectado?",
|
|
61
|
+
actions: [
|
|
62
|
+
{ text: "Sair", value: "sair" },
|
|
63
|
+
{ text: "Continuar conectado", value: "continuar" },
|
|
64
|
+
],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
</script>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Fechando o diálogo
|
|
71
|
+
|
|
72
|
+
Além dos botões, o usuário pode fechar o diálogo pela tecla `Esc` ou clicando fora dele. Nesses casos, o diálogo resolve `undefined` ao fim da animação de fechamento.
|
|
73
|
+
|
|
74
|
+
O botão "voltar" do navegador também fecha o diálogo, sem sair da página, em aplicações que usam o [Vue Router](https://router.vuejs.org/). A exceção é quando o "voltar" leva a uma página aberta com `router.replace`, como a página pela qual o usuário entrou na aplicação: nesse caso, a navegação acontece e o diálogo continua aberto.
|
|
75
|
+
|
|
76
|
+
### Fila de diálogos
|
|
77
|
+
|
|
78
|
+
```vue
|
|
79
|
+
<template>
|
|
80
|
+
<u-main>
|
|
81
|
+
<u-button variant="secondary" @click="openQueue">Dois diálogos seguidos</u-button>
|
|
82
|
+
</u-main>
|
|
83
|
+
</template>
|
|
84
|
+
|
|
85
|
+
<script lang="ts" setup>
|
|
86
|
+
import { UMain, UButton } from "@nexdom/uimed-vue/components";
|
|
87
|
+
import { useDialog } from "@nexdom/uimed-vue/composables";
|
|
88
|
+
|
|
89
|
+
const { dialog } = useDialog();
|
|
90
|
+
|
|
91
|
+
function openQueue() {
|
|
92
|
+
dialog({ title: "Primeiro diálogo", message: "Este diálogo é apresentado primeiro." });
|
|
93
|
+
dialog({ title: "Segundo diálogo", message: "Este diálogo aguardou o primeiro ser fechado." });
|
|
94
|
+
}
|
|
95
|
+
</script>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Ver também
|
|
99
|
+
|
|
100
|
+
- Consulte a referência de [API do useDialog](../../api/composables/use-dialog.md) para mais informações.
|
|
101
|
+
- Para confirmar uma ação antes de executá-la, use a composable [useConfirm](./use-confirm.md).
|
|
102
|
+
- Para apresentar conteúdo próprio, como um formulário, em uma janela modal, use o componente [Dialog](../components/dialog.md).
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Run or toast
|
|
2
|
+
|
|
3
|
+
Uma vez que carregamos o [Componente base](../components/main.md), podemos estar tirando proveito da nossa composable para execução de métodos assíncronos e apresentação de mensagens _toast_ em caso de exceções.
|
|
4
|
+
|
|
5
|
+
## Uso
|
|
6
|
+
|
|
7
|
+
```vue
|
|
8
|
+
<template>
|
|
9
|
+
<u-main>
|
|
10
|
+
<u-row>
|
|
11
|
+
<u-column cols="auto">
|
|
12
|
+
<u-button :loading="isRunningSuccessfully" color="positive" @click="runSuccessfully">
|
|
13
|
+
Executar com sucesso
|
|
14
|
+
</u-button>
|
|
15
|
+
</u-column>
|
|
16
|
+
<u-column cols="auto">
|
|
17
|
+
<u-button :loading="isRunningUnsuccessfully" color="danger" @click="runUnsuccessfully">
|
|
18
|
+
Executar com falha
|
|
19
|
+
</u-button>
|
|
20
|
+
</u-column>
|
|
21
|
+
</u-row>
|
|
22
|
+
</u-main>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script lang="ts" setup>
|
|
26
|
+
import { UMain, URow, UColumn, UButton } from "@nexdom/uimed-vue/components";
|
|
27
|
+
import { useRunOrToast } from "@nexdom/uimed-vue/composables";
|
|
28
|
+
|
|
29
|
+
const { run: runSucceeding, isRunning: isRunningSuccessfully } = useRunOrToast();
|
|
30
|
+
const { run: runFailing, isRunning: isRunningUnsuccessfully } = useRunOrToast();
|
|
31
|
+
|
|
32
|
+
function runSuccessfully() {
|
|
33
|
+
runSucceeding(
|
|
34
|
+
() =>
|
|
35
|
+
new Promise((resolve) => {
|
|
36
|
+
setTimeout(resolve, 1500);
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function runUnsuccessfully() {
|
|
42
|
+
runFailing(
|
|
43
|
+
() =>
|
|
44
|
+
new Promise((_, reject) => {
|
|
45
|
+
const error = new Error("Ops! Algo deu errado.");
|
|
46
|
+
setTimeout(() => reject(error), 1500);
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
</script>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Ver também
|
|
54
|
+
|
|
55
|
+
Consulte a referência de [API do useRunOrToast](../../api/composables/use-run-or-toast.md) para mais informações.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Toasts
|
|
2
|
+
|
|
3
|
+
Uma vez que carregamos o [Componente base](../components/main.md), podemos estar tirando proveito da nossa composable para apresentação de mensagens _toast_.
|
|
4
|
+
|
|
5
|
+
## Uso
|
|
6
|
+
|
|
7
|
+
```vue
|
|
8
|
+
<template>
|
|
9
|
+
<u-main>
|
|
10
|
+
<u-row>
|
|
11
|
+
<u-column cols="auto">
|
|
12
|
+
<u-button
|
|
13
|
+
color="positive"
|
|
14
|
+
@click="toast({ message: 'Mensagem positiva.', color: 'positive' })"
|
|
15
|
+
>
|
|
16
|
+
Positive
|
|
17
|
+
</u-button>
|
|
18
|
+
</u-column>
|
|
19
|
+
<u-column cols="auto">
|
|
20
|
+
<u-button
|
|
21
|
+
color="informative"
|
|
22
|
+
@click="toast({ message: 'Mensagem informativa.', color: 'informative' })"
|
|
23
|
+
>
|
|
24
|
+
Informative
|
|
25
|
+
</u-button>
|
|
26
|
+
</u-column>
|
|
27
|
+
<u-column cols="auto">
|
|
28
|
+
<u-button
|
|
29
|
+
color="caution"
|
|
30
|
+
@click="toast({ message: 'Mensagem de atenção.', color: 'caution' })"
|
|
31
|
+
>
|
|
32
|
+
Caution
|
|
33
|
+
</u-button>
|
|
34
|
+
</u-column>
|
|
35
|
+
<u-column cols="auto">
|
|
36
|
+
<u-button
|
|
37
|
+
color="danger"
|
|
38
|
+
@click="toast({ message: 'Mensagem de perigo.', color: 'danger' })"
|
|
39
|
+
>
|
|
40
|
+
Danger
|
|
41
|
+
</u-button>
|
|
42
|
+
</u-column>
|
|
43
|
+
</u-row>
|
|
44
|
+
</u-main>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<script lang="ts" setup>
|
|
48
|
+
import { UMain, URow, UColumn, UButton } from "@nexdom/uimed-vue/components";
|
|
49
|
+
import { useToast } from "@nexdom/uimed-vue/composables";
|
|
50
|
+
|
|
51
|
+
const { toast } = useToast();
|
|
52
|
+
</script>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Ver também
|
|
56
|
+
|
|
57
|
+
Consulte a referência de [API do useToast](../../api/composables/use-toast.md) para mais informações.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Alterações não salvas
|
|
2
|
+
|
|
3
|
+
Uma vez que carregamos o [Componente base](../components/main.md), podemos estar tirando proveito da nossa composable para evitar que o usuário perca as alterações de um formulário ao sair da página sem salvar.
|
|
4
|
+
|
|
5
|
+
A composable compara o valor original do formulário (`previous`) com o valor atual (`current`) e informa, por meio de `hasChanges`, se existem alterações. Enquanto existirem alterações:
|
|
6
|
+
|
|
7
|
+
- sair da página pelo [Vue Router](https://router.vuejs.org/) apresenta um diálogo de [confirmação](./use-confirm.md);
|
|
8
|
+
- recarregar a página, fechar a aba ou sair da aplicação por um link externo apresenta o aviso do próprio navegador.
|
|
9
|
+
|
|
10
|
+
## Uso
|
|
11
|
+
|
|
12
|
+
Edite o nome do paciente e tente ir para a lista.
|
|
13
|
+
|
|
14
|
+
A demonstração tem duas páginas, "Cadastro do paciente" e "Pacientes", com um roteador próprio. Por isso, a navegação entre elas não altera o endereço do navegador.
|
|
15
|
+
|
|
16
|
+
```vue
|
|
17
|
+
<!-- PatientForm.vue, página renderizada pelo <RouterView> -->
|
|
18
|
+
<template>
|
|
19
|
+
<u-section title="Cadastro do paciente" :actions="actions">
|
|
20
|
+
<u-section-content>
|
|
21
|
+
<u-text-field v-model="form.name" label="Nome" />
|
|
22
|
+
<p>Alterações não salvas: {{ hasChanges ? "sim" : "não" }}</p>
|
|
23
|
+
</u-section-content>
|
|
24
|
+
</u-section>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script lang="ts" setup>
|
|
28
|
+
import { computed, ref, toRaw } from "vue";
|
|
29
|
+
import { useRouter } from "vue-router";
|
|
30
|
+
import type { ComponentProps } from "vue-component-type-helpers";
|
|
31
|
+
import { USection, USectionContent, UTextField } from "@nexdom/uimed-vue/components";
|
|
32
|
+
import { useUnsavedChanges } from "@nexdom/uimed-vue/composables";
|
|
33
|
+
|
|
34
|
+
const router = useRouter();
|
|
35
|
+
const saved = ref({ name: "Maria Silva" });
|
|
36
|
+
const form = ref(structuredClone(toRaw(saved.value)));
|
|
37
|
+
const { hasChanges } = useUnsavedChanges({ previous: saved, current: form });
|
|
38
|
+
|
|
39
|
+
function save() {
|
|
40
|
+
// Marca o formulário como salvo
|
|
41
|
+
saved.value = structuredClone(toRaw(form.value));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function saveAndLeave() {
|
|
45
|
+
save();
|
|
46
|
+
await router.push("/pacientes");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const actions = computed<ComponentProps<typeof USection>["actions"]>(() => [
|
|
50
|
+
{ label: "Ir para a lista", variant: "ghost", onClick: () => router.push("/pacientes") },
|
|
51
|
+
{ label: "Salvar", variant: "secondary", disabled: !hasChanges.value, onClick: save },
|
|
52
|
+
{ label: "Salvar e ir para a lista", onClick: saveAndLeave },
|
|
53
|
+
]);
|
|
54
|
+
</script>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Comparação dos valores
|
|
58
|
+
|
|
59
|
+
`previous` e `current` aceitam uma `ref`, um getter (`() => valor`) ou um objeto `reactive`. A comparação é feita em profundidade:
|
|
60
|
+
|
|
61
|
+
- a ordem das propriedades não importa;
|
|
62
|
+
- uma propriedade com `undefined` é igual a uma propriedade ausente;
|
|
63
|
+
- datas (`Date`) são comparadas pelo horário;
|
|
64
|
+
- listas são comparadas item a item, na mesma ordem;
|
|
65
|
+
- `null`, `""` e `undefined` são diferentes entre si, então limpar um campo que era `null` conta como alteração;
|
|
66
|
+
- objetos simples (como `{ nome: "Maria" }`) são comparados propriedade a propriedade;
|
|
67
|
+
- os demais objetos, como `File`, `Blob`, `Map`, `Set` e instâncias de classes, são comparados por referência: trocar um anexo por outro `File` conta como alteração, mesmo que o conteúdo seja igual;
|
|
68
|
+
- os demais valores são comparados com [`Object.is`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Object/is), então `NaN` é igual a `NaN`.
|
|
69
|
+
|
|
70
|
+
### Saindo da página
|
|
71
|
+
|
|
72
|
+
Com alterações, sair da página pelo Vue Router apresenta o diálogo "Alterações não salvas", com o foco inicial em "Continuar editando":
|
|
73
|
+
|
|
74
|
+
- "Sair sem salvar" continua a navegação;
|
|
75
|
+
- "Continuar editando", a tecla `Esc` ou um clique fora do diálogo cancelam a navegação, e o usuário continua na página com as suas alterações.
|
|
76
|
+
|
|
77
|
+
Sem alterações, a navegação acontece sem diálogo. Em aplicações com Vue Router e histórico do navegador (`createWebHistory` ou `createWebHashHistory`), o botão "voltar" do navegador também passa pela mesma verificação: ao cancelar, o endereço volta a ser o da página atual.
|
|
78
|
+
|
|
79
|
+
Enquanto o diálogo estiver aberto, novas navegações não abrem outro diálogo: a resposta vale para a navegação mais recente. Por exemplo, em aplicações com Vue Router e histórico do navegador (`createWebHistory` ou `createWebHashHistory`), se o usuário usar o botão "voltar" do navegador com o diálogo aberto, o diálogo continua aberto; "Sair sem salvar" leva à página anterior e "Continuar editando" mantém o usuário na página. Esse comportamento difere do [`confirm`](./use-confirm.md), cujo diálogo fecha com o "voltar".
|
|
80
|
+
|
|
81
|
+
Se a página tiver mais de um componente usando `useUnsavedChanges` com alterações, cada um apresenta o seu diálogo, um depois do outro.
|
|
82
|
+
|
|
83
|
+
### Depois de salvar
|
|
84
|
+
|
|
85
|
+
Para marcar o formulário como salvo, atribua a `previous` uma cópia do valor atual, como no `save` do exemplo. A partir daí, `hasChanges` volta a ser `false` e a navegação seguinte acontece sem diálogo, mesmo que ela seja feita logo em seguida, como no "Salvar e ir para a lista".
|
|
86
|
+
|
|
87
|
+
Use uma cópia (por exemplo, com `structuredClone(toRaw(valor))`). Se `previous` e `current` apontarem para o mesmo objeto, as alterações de um também aparecem no outro e `hasChanges` fica sempre `false`.
|
|
88
|
+
|
|
89
|
+
### Recarregando ou fechando a aba
|
|
90
|
+
|
|
91
|
+
Com alterações, recarregar a página (F5), fechar a aba ou sair da aplicação por um link externo apresenta o aviso do próprio navegador. O texto desse aviso é definido pelo navegador e não pode ser personalizado, e ele só aparece se o usuário já interagiu com a página (por exemplo, digitando em um campo).
|
|
92
|
+
|
|
93
|
+
O aviso só é registrado enquanto houver alterações. Para desligá-lo, use a opção `beforeUnload: false`.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const { hasChanges } = useUnsavedChanges(
|
|
97
|
+
{ previous: saved, current: form },
|
|
98
|
+
{ beforeUnload: false },
|
|
99
|
+
);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Personalizando o diálogo
|
|
103
|
+
|
|
104
|
+
Os textos e a cor do botão de confirmação aceitam as mesmas opções do [`confirm`](./use-confirm.md).
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
const { hasChanges } = useUnsavedChanges(
|
|
108
|
+
{ previous: saved, current: form },
|
|
109
|
+
{
|
|
110
|
+
title: "Descartar cadastro",
|
|
111
|
+
message: "O cadastro do paciente ainda não foi salvo. Deseja descartá-lo?",
|
|
112
|
+
confirmText: "Descartar",
|
|
113
|
+
cancelText: "Voltar ao cadastro",
|
|
114
|
+
color: "caution",
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Limitações
|
|
120
|
+
|
|
121
|
+
- O diálogo depende do [Componente base](../components/main.md): sem ele, o diálogo não aparece e a navegação fica pendente.
|
|
122
|
+
- A navegação só é verificada quando `useUnsavedChanges` é chamada em uma página renderizada pelo `<RouterView>` (ou em um componente dentro dela). Em outros lugares, ou em aplicações sem Vue Router, apenas `hasChanges` e o aviso do navegador funcionam.
|
|
123
|
+
- Mudanças apenas nos parâmetros (`params`) ou na consulta (`query`) da mesma rota não são verificadas.
|
|
124
|
+
- Uma [janela modal](../components/dialog.md) com uma ação em carregamento (`loading`) não fecha pelo botão "voltar" do navegador, mas a verificação desta composable acontece antes: com alterações, o "voltar" apresenta o diálogo "Alterações não salvas" sobre a janela, e "Sair sem salvar" sai da página mesmo com a ação ainda em carregamento.
|
|
125
|
+
|
|
126
|
+
## Ver também
|
|
127
|
+
|
|
128
|
+
- Consulte a referência de [API do useUnsavedChanges](../../api/composables/use-unsaved-changes.md) para mais informações.
|
|
129
|
+
- Para pedir a confirmação do usuário antes de executar uma ação, use a composable [useConfirm](./use-confirm.md).
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Iniciando
|
|
2
|
+
|
|
3
|
+
## Instação
|
|
4
|
+
|
|
5
|
+
### Pré-requisitos
|
|
6
|
+
|
|
7
|
+
- [Node.js](https://nodejs.org/) na versão 22 ou superior.
|
|
8
|
+
- [Vue.js](https://vuejs.org/) na versão 3 ou superior.
|
|
9
|
+
- [@nexdom/shared](https://nexdom-healthtech.github.io/shared/) na versão 2.1.1 ou superior.
|
|
10
|
+
- [vue-component-type-helpers](https://www.npmjs.com/package/vue-component-type-helpers) para tipagem de props.
|
|
11
|
+
- Editor de texto com suporte a sintaxe [Markdown](https://en.wikipedia.org/wiki/Markdown).
|
|
12
|
+
- [VSCode](https://code.visualstudio.com/) é recomendado, junto com a [extensão oficial Vue](https://marketplace.visualstudio.com/items?itemName=Vue.volar).
|
|
13
|
+
|
|
14
|
+
Para instalar no seu projeto, execute:
|
|
15
|
+
|
|
16
|
+
```sh [Vite+]
|
|
17
|
+
$ vp add @nexdom/uimed-vue
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```sh [npm]
|
|
21
|
+
$ npm install @nexdom/uimed-vue
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```sh [pnpm]
|
|
25
|
+
$ pnpm add @nexdom/uimed-vue
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```sh [yarn]
|
|
29
|
+
$ yarn add @nexdom/uimed-vue
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Configuração
|
|
33
|
+
|
|
34
|
+
Adicione o plugin ao arquivo de configurações do Vite. Ele compila os estilos dos componentes com a fonte e os ajustes visuais da biblioteca. Sem ele, os componentes perdem a fonte Unimed Slab:
|
|
35
|
+
|
|
36
|
+
```js [vite.config.ts]
|
|
37
|
+
import { defineConfig } from 'vite'
|
|
38
|
+
import vue from "@vitejs/plugin-vue";
|
|
39
|
+
import { vitePluginUimed } from "@nexdom/uimed-vue/plugins"; // [!code ++]
|
|
40
|
+
|
|
41
|
+
export default defineConfig({
|
|
42
|
+
plugins: [
|
|
43
|
+
vue(),
|
|
44
|
+
vitePluginUimed() // [!code ++]
|
|
45
|
+
];
|
|
46
|
+
// ...
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Após atualizar as configurações do Vite, instale o plugin no seu app:
|
|
51
|
+
|
|
52
|
+
```ts [main.ts]
|
|
53
|
+
import { createApp } from "vue";
|
|
54
|
+
import { createUimed } from "@nexdom/uimed-vue"; // [!code ++]
|
|
55
|
+
|
|
56
|
+
import App from "./App.vue";
|
|
57
|
+
|
|
58
|
+
const uimed = createUimed(); // [!code ++]
|
|
59
|
+
|
|
60
|
+
createApp(App)
|
|
61
|
+
.use(uimed) // [!code ++]
|
|
62
|
+
.mount("#app");
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Os textos que os componentes geram por conta própria, como os anúncios para leitores de tela (por exemplo, `Carregando...`) e os rótulos da paginação, ficam em português.
|
|
66
|
+
|
|
67
|
+
## Tipagem de props
|
|
68
|
+
|
|
69
|
+
A biblioteca não exporta tipos de props diretamente. A forma recomendada é utilizar `ComponentProps` do pacote `vue-component-type-helpers`, instalado como dependência de pares (_peer dependency_) da biblioteca.
|
|
70
|
+
|
|
71
|
+
```vue [App.vue]
|
|
72
|
+
<template>
|
|
73
|
+
<u-main :app-bar="appBar" :navigation-menu="navigationMenu">
|
|
74
|
+
<u-section :actions="sectionActions">
|
|
75
|
+
<!-- ... -->
|
|
76
|
+
</u-section>
|
|
77
|
+
</u-main>
|
|
78
|
+
</template>
|
|
79
|
+
|
|
80
|
+
<script lang="ts" setup>
|
|
81
|
+
import type { ComponentProps } from "vue-component-type-helpers";
|
|
82
|
+
import { UMain, USection } from "@nexdom/uimed-vue/components";
|
|
83
|
+
|
|
84
|
+
type MainProps = ComponentProps<typeof UMain>;
|
|
85
|
+
type AppBar = NonNullable<MainProps["appBar"]>;
|
|
86
|
+
type NavigationMenu = NonNullable<MainProps["navigationMenu"]>;
|
|
87
|
+
type SectionAction = NonNullable<ComponentProps<typeof USection>["actions"]>[number];
|
|
88
|
+
|
|
89
|
+
const appBar: AppBar = {
|
|
90
|
+
title: "Meu App",
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const navigationMenu: NavigationMenu = {
|
|
94
|
+
items: [{ description: "Home", route: "/", icon: "home" }],
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const sectionActions: SectionAction[] = [{ type: "submit", label: "Salvar" }];
|
|
98
|
+
</script>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`NonNullable` é necessário porque as props são opcionais: sem ele, o tipo também aceitaria `undefined`, impedindo o acesso a propriedades aninhadas (como `AppBar["user"]`) e o uso com `reactive<...>()` ou `computed<...>()`.
|
|
102
|
+
|
|
103
|
+
## Agentes de IA
|
|
104
|
+
|
|
105
|
+
O pacote traz um guia de uso para agentes de IA (como Claude Code, Codex, Cursor ou Copilot), no formato aberto de Agent Skills, em `node_modules/@nexdom/uimed-vue/skills/uimed-vue/SKILL.md`. Ele reúne a instalação, a configuração, as regras de uso, os pontos de entrada, as mudanças incompatíveis e esta documentação, todos na versão instalada no projeto: a cada atualização da biblioteca, o guia é atualizado junto.
|
|
106
|
+
|
|
107
|
+
Para que o agente do seu projeto use o guia, referencie-o uma vez nas instruções dele:
|
|
108
|
+
|
|
109
|
+
```md [CLAUDE.md]
|
|
110
|
+
@node_modules/@nexdom/uimed-vue/skills/uimed-vue/SKILL.md
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```md [AGENTS.md]
|
|
114
|
+
Para usar a biblioteca `@nexdom/uimed-vue`, siga `node_modules/@nexdom/uimed-vue/skills/uimed-vue/SKILL.md`.
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
O guia trata só do uso da biblioteca: as regras do seu projeto, como o fluxo de Git e os agentes, continuam nas instruções dele.
|
|
118
|
+
|
|
119
|
+
## E agora?
|
|
120
|
+
|
|
121
|
+
Importe o componente [`Main`](../api/components/main.md) para dentro do seu `App.vue`, conforme o exemplo a seguir e então você poderá utilizar todos os recursos do `@nexdom/uimed-vue` a vontade.
|
|
122
|
+
|
|
123
|
+
```vue [App.vue]
|
|
124
|
+
<template>
|
|
125
|
+
<u-main>
|
|
126
|
+
<!-- ... -->
|
|
127
|
+
</u-main>
|
|
128
|
+
</template>
|
|
129
|
+
|
|
130
|
+
<script lang="ts" setup>
|
|
131
|
+
import { UMain } from "@nexdom/uimed-vue/components";
|
|
132
|
+
</script>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Acesse as [APIs](../api/index.md) e saiba mais dos recursos que este framework dispõe.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Ícones
|
|
2
|
+
|
|
3
|
+
Os componentes que aceitam um ícone, como o [botão de ícone](./components/icon-button.md) e os itens e grupos do primeiro nível do [menu de navegação](./components/main.md#menu-de-navegacao), recebem o nome de um dos ícones listados nesta página na propriedade `icon`.
|
|
4
|
+
|
|
5
|
+
Os ícones são desenhados como imagens vetoriais (SVG) na própria página, sem carregar uma fonte de ícones. Por isso, classes de fontes de ícones (como `mdi-home`) não exibem ícones: use os nomes desta página.
|
|
6
|
+
|
|
7
|
+
## Uso
|
|
8
|
+
|
|
9
|
+
Informe o nome do ícone em `icon`. No [botão de ícone](./components/icon-button.md), o ícone é todo o conteúdo do botão, e a propriedade `label` define o nome que os leitores de tela anunciam no lugar dele:
|
|
10
|
+
|
|
11
|
+
```vue
|
|
12
|
+
<template>
|
|
13
|
+
<u-icon-button icon="cog" label="Configurações" />
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script lang="ts" setup>
|
|
17
|
+
import { UIconButton } from "@nexdom/uimed-vue/components";
|
|
18
|
+
</script>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Nos itens e grupos do menu de navegação, o ícone aparece antes da descrição:
|
|
22
|
+
|
|
23
|
+
```vue
|
|
24
|
+
<template>
|
|
25
|
+
<u-main :appBar :navigationMenu>
|
|
26
|
+
<h2>O conteúdo da página vai aqui...</h2>
|
|
27
|
+
</u-main>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script lang="ts" setup>
|
|
31
|
+
import type { ComponentProps } from "vue-component-type-helpers";
|
|
32
|
+
import { UMain } from "@nexdom/uimed-vue/components";
|
|
33
|
+
|
|
34
|
+
type MainProps = ComponentProps<typeof UMain>;
|
|
35
|
+
|
|
36
|
+
const appBar: NonNullable<MainProps["appBar"]> = {
|
|
37
|
+
title: "Menu superior",
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const navigationMenu: NonNullable<MainProps["navigationMenu"]> = {
|
|
41
|
+
items: [
|
|
42
|
+
{ description: "Início", route: "/", icon: "home" },
|
|
43
|
+
{ description: "Agenda", route: "/agenda", icon: "calendar" },
|
|
44
|
+
{ description: "Configurações", route: "/configuracoes", icon: "cog" },
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
</script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
No menu, o ícone usa a cor do texto do menu. Ele é decorativo: leitores de tela anunciam apenas a descrição.
|
|
51
|
+
|
|
52
|
+
O ícone é obrigatório nos itens e grupos do primeiro nível do menu, porque, em telas largas, o menu fica recolhido e mostra apenas os ícones. Os itens dentro de um grupo não exibem ícones.
|
|
53
|
+
|
|
54
|
+
## Ícones disponíveis
|
|
55
|
+
|
|
56
|
+
A lista começa pelos ícones de conteúdo, como `home` e `calendar`, cujos nomes descrevem o desenho do ícone, e não onde ele deve ser usado. Quase todos eles têm uma versão alternativa do mesmo desenho (atualmente, contornada), com o sufixo `Alternative` no nome. Prefira usar a mesma versão (a original ou a alternativa) em todos os itens do menu.
|
|
57
|
+
|
|
58
|
+
Em seguida vêm os ícones que os próprios componentes exibem, cujos nomes descrevem a função com que os componentes os usam:
|
|
59
|
+
|
|
60
|
+
- Ações, como `help`, `search`, `showPassword` e `close`.
|
|
61
|
+
- Expansão de menus e grupos, como `dropdown`, `expand` e `collapse`, e navegação entre páginas, com `prev` e `next`.
|
|
62
|
+
- Marcações da caixa de seleção: `checkboxOn` e `checkboxOff`.
|
|
63
|
+
- Retorno ao usuário, nas cores das mensagens: `success`, `info`, `warning` e `error`.
|
|
64
|
+
|
|
65
|
+
Use-os com a mesma função, para que o significado de cada ícone seja o mesmo em toda a aplicação.
|
|
66
|
+
|
|
67
|
+
Busque um ícone pelo nome, sem diferenciar maiúsculas, minúsculas ou acentos, e clique no ícone para copiar o seu nome.
|
|
68
|
+
|
|
69
|
+
## Ver também
|
|
70
|
+
|
|
71
|
+
Consulte o [botão de ícone](./components/icon-button.md) e o [Componente base](./components/main.md#menu-de-navegacao) para mais detalhes sobre os componentes que exibem ícones.
|