v-sistec-features 1.31.13 → 1.32.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.
Files changed (152) hide show
  1. package/dist/DataAgenda/VDataAgenda.vue.d.ts +915 -0
  2. package/dist/DataAgenda/components/AgendaMatrix.vue.d.ts +64 -0
  3. package/dist/DataAgenda/components/AgendaMatrixBase.vue.d.ts +31 -0
  4. package/dist/DataAgenda/components/AgendaMatrixUnico.vue.d.ts +72 -0
  5. package/dist/DataAgenda/components/AgendaTabelaHorario.vue.d.ts +32 -0
  6. package/dist/DataAgenda/components/AgendaVueCal.vue.d.ts +94 -0
  7. package/dist/DataAgenda/components/BlocoArrastavel.vue.d.ts +37 -0
  8. package/dist/DataAgenda/components/HeaderCalendario.vue.d.ts +7 -0
  9. package/dist/DataAgenda/components/HeaderTabela.vue.d.ts +7 -0
  10. package/dist/DataAgenda/components/ModalDetalhesReserva.vue.d.ts +38 -0
  11. package/dist/DataAgenda/components/ModalReserva.vue.d.ts +157 -0
  12. package/dist/DataAgenda/composables/useAgenda.d.ts +24 -0
  13. package/dist/DataAgenda/composables/useCoresAgenda.d.ts +7 -0
  14. package/dist/DataAgenda/composables/useGradeCompartilhada.d.ts +23 -0
  15. package/dist/DataAgenda/composables/useSelecaoArrasto.d.ts +24 -0
  16. package/dist/DataAgenda/index.d.ts +2 -0
  17. package/dist/DataPageVue/components/VDataPage.vue.d.ts +50 -0
  18. package/dist/DataPageVue/index.d.ts +2 -0
  19. package/dist/DataPageVue/types/v-data-page.d.ts +53 -0
  20. package/dist/DatatableVue/components/SearchDatatable.vue.d.ts +28 -0
  21. package/dist/DatatableVue/components/VColumn.vue.d.ts +82 -0
  22. package/dist/DatatableVue/components/VColumnManager.vue.d.ts +21 -0
  23. package/dist/DatatableVue/components/VDataTable.vue.d.ts +57 -0
  24. package/dist/DatatableVue/components/VDataTableLoading.vue.d.ts +17 -0
  25. package/dist/DatatableVue/components/VOrderingIcon.vue.d.ts +10 -0
  26. package/dist/DatatableVue/components/VThDataTable.vue.d.ts +14 -0
  27. package/dist/DatatableVue/composables/useCheckBox.d.ts +11 -0
  28. package/dist/DatatableVue/composables/useDataTableConfig.d.ts +4 -0
  29. package/dist/DatatableVue/composables/useDataTableFetch.d.ts +17 -0
  30. package/dist/DatatableVue/composables/useExpandedItem.d.ts +6 -0
  31. package/dist/DatatableVue/composables/useImagePreview.d.ts +9 -0
  32. package/dist/DatatableVue/config/datatableConfig.d.ts +4 -0
  33. package/dist/DatatableVue/config/datatableDefaults.d.ts +7 -0
  34. package/dist/DatatableVue/index.d.ts +3 -0
  35. package/dist/DatatableVue/keys.d.ts +39 -0
  36. package/dist/DatatableVue/style/svgs.d.ts +20 -0
  37. package/dist/DatatableVue/types/v-data-table.d.ts +161 -0
  38. package/dist/Modals/components/BotaoFechar.vue.d.ts +36 -0
  39. package/dist/Modals/components/ModalAviso.vue.d.ts +184 -0
  40. package/dist/Modals/components/ModalBaseDefault.vue.d.ts +244 -0
  41. package/dist/Modals/components/ModalConfirmacao.vue.d.ts +184 -0
  42. package/dist/Modals/components/ModalConfirmacaoCheckbox.vue.d.ts +195 -0
  43. package/dist/Modals/components/ModalConfirmacaoInput.vue.d.ts +238 -0
  44. package/dist/Modals/components/ModalConfirmacaoSimples.vue.d.ts +187 -0
  45. package/dist/Modals/components/ModalInformacao.vue.d.ts +184 -0
  46. package/dist/Modals/components/ModalPerigo.vue.d.ts +175 -0
  47. package/dist/Modals/components/ModalSucesso.vue.d.ts +175 -0
  48. package/dist/Modals/components/interno/ModalDialogoInterno.vue.d.ts +205 -0
  49. package/dist/Modals/index.d.ts +12 -0
  50. package/dist/Modals.js +1361 -0
  51. package/dist/Pagination/Pagination.vue.d.ts +19 -0
  52. package/dist/Pagination/index.d.ts +2 -0
  53. package/dist/{Pagination-f4FVE5TX.js → Pagination-D96eBRod.js} +25 -25
  54. package/dist/Pagination.js +1 -1
  55. package/dist/{ar-Bg_10XBG.js → ar-CtSPmWrk.js} +0 -5
  56. package/dist/{bg-DyIRbFaU.js → bg-DwW4tkzm.js} +0 -5
  57. package/dist/{bn-DrKXkRvN.js → bn-Df__ccyH.js} +0 -5
  58. package/dist/{bs-BF8upphm.js → bs-j17x02qr.js} +0 -5
  59. package/dist/{ca-CGMnsdII.js → ca-B94lUx7c.js} +0 -5
  60. package/dist/core/index.d.ts +1 -0
  61. package/dist/core/plugin.d.ts +11 -0
  62. package/dist/core.js +1 -1
  63. package/dist/{cs-B-jeNB5o.js → cs-DeDzN7tG.js} +0 -5
  64. package/dist/{da-BoHemyXx.js → da-DMpC5y8O.js} +0 -5
  65. package/dist/datatableConfig-E5_08Ch4.js +4 -0
  66. package/dist/{de-DNAaiTrc.js → de-CCNUZSup.js} +0 -5
  67. package/dist/{el-Cpg3pI7i.js → el-C2kkX76k.js} +0 -5
  68. package/dist/{en-gb-KsKdvLmV.js → en-gb-sbYhvlrM.js} +0 -5
  69. package/dist/{es-COziTcsp.js → es-mNgFJGue.js} +0 -5
  70. package/dist/{et-BdTtu9t_.js → et-D0ro6m_Z.js} +0 -5
  71. package/dist/{fa-B1Ebp36t.js → fa-DYekHC6-.js} +0 -5
  72. package/dist/{fi-b4XodxNE.js → fi-CNexLCO_.js} +0 -5
  73. package/dist/{fr-BIx4sO6s.js → fr-CUXtdWLj.js} +0 -5
  74. package/dist/{he-rf_Y5d64.js → he-D4BblsAD.js} +0 -5
  75. package/dist/{hr-DOuJJGF3.js → hr-1MNJjxDo.js} +0 -5
  76. package/dist/{hu-DMc8kv_1.js → hu-BiG8mSvH.js} +0 -5
  77. package/dist/{id-DclBfDY0.js → id-CABEuSQB.js} +0 -5
  78. package/dist/iframeCommunicator/index.d.ts +2 -0
  79. package/dist/iframeCommunicator/useIframeCommunicator.d.ts +8 -0
  80. package/dist/iframeCommunicator/useThemeFromParent.d.ts +9 -0
  81. package/dist/index.d.ts +3 -140
  82. package/dist/index.js +1 -1
  83. package/dist/{is-hPcr999q.js → is-DBUkoxb1.js} +0 -5
  84. package/dist/{it-Dfz57Ogc.js → it-Am_Oo5d5.js} +0 -5
  85. package/dist/{ja-Da6Dbgu8.js → ja-C4aaunra.js} +0 -5
  86. package/dist/{ka-DK-BKZD4.js → ka-CkzS4fNj.js} +0 -5
  87. package/dist/{kaa-BVd8dKz3.js → kaa-GTw11GU-.js} +0 -5
  88. package/dist/{kk-eE3-SI4R.js → kk-BRFq2Ctd.js} +0 -5
  89. package/dist/{ko-CUMtwCHy.js → ko-BbgS6BMk.js} +0 -5
  90. package/dist/{ky-CCU0MYbD.js → ky-ClK6HL0m.js} +0 -5
  91. package/dist/{lt-CpbQmiiW.js → lt-BE0ahgri.js} +0 -5
  92. package/dist/{mn-YYwo93uK.js → mn-C-Ktk8ht.js} +0 -5
  93. package/dist/{nl-WqtgByJL.js → nl-BiG9OH1y.js} +0 -5
  94. package/dist/{no-BOG8-aOm.js → no-DVdX7xTS.js} +0 -5
  95. package/dist/{pl-BH4AyCMF.js → pl-y_N8wVAF.js} +0 -5
  96. package/dist/plugin-BZB7f-c3.js +3444 -0
  97. package/dist/{pt-br-siyrXjdv.js → pt-br-Cx8Akpcu.js} +0 -5
  98. package/dist/{pt-pt-siyrXjdv.js → pt-pt-Cx8Akpcu.js} +0 -5
  99. package/dist/{ro-C9fU41Qi.js → ro-FfAZHwo1.js} +0 -5
  100. package/dist/{ru-_d_rl3a5.js → ru-BCE9k5uo.js} +0 -5
  101. package/dist/{sk-ZT421l3d.js → sk-D-7bEf3b.js} +0 -5
  102. package/dist/{sl-Ct8Gi5v1.js → sl-DoVrM4Ht.js} +0 -5
  103. package/dist/{sq-Cw7PWK-V.js → sq-Du8jVeq7.js} +0 -5
  104. package/dist/{sr-DO-S1wn3.js → sr-DP3yke6-.js} +0 -5
  105. package/dist/{sv-NXMCPui2.js → sv-C2iGWFqL.js} +0 -5
  106. package/dist/toast/components/ToastComponent.vue.d.ts +6 -0
  107. package/dist/toast/index.d.ts +1 -0
  108. package/dist/toast/useToastStore.d.ts +11 -0
  109. package/dist/toast.js +2 -2
  110. package/dist/{tr-BpieMIth.js → tr-CvlANdCR.js} +0 -5
  111. package/dist/{uk-CqVU4EoZ.js → uk-CxFb8w2s.js} +0 -5
  112. package/dist/utils/svgFactory.d.ts +8 -0
  113. package/dist/{uz-CmcB22-w.js → uz-DmJPqTjK.js} +0 -5
  114. package/dist/{uz-cryl-C_GBVdXl.js → uz-cryl-Dt065WNc.js} +0 -5
  115. package/dist/v-sistec-features.css +1 -11
  116. package/dist/vDataAgenda.js +1877 -1885
  117. package/dist/vDataPage.js +31 -41
  118. package/dist/vDataTable.js +43 -43
  119. package/dist/{vi-C9wTd3fG.js → vi-B8R5Ozvj.js} +0 -5
  120. package/dist/{zh-cn-DY7nkJwf.js → zh-cn-DnUuIcqx.js} +0 -5
  121. package/dist/{zh-hk-KkazoDdS.js → zh-hk-mDkIkhi9.js} +0 -5
  122. package/package.json +5 -1
  123. package/src/DataAgenda/VDataAgenda.vue +233 -77
  124. package/src/DataAgenda/components/AgendaMatrix.vue +1 -0
  125. package/src/DataAgenda/components/AgendaMatrixBase.vue +357 -140
  126. package/src/DataAgenda/components/AgendaMatrixUnico.vue +1 -0
  127. package/src/DataAgenda/components/AgendaTabelaHorario.vue +489 -316
  128. package/src/DataAgenda/components/AgendaVueCal.vue +1 -0
  129. package/src/DataAgenda/index.ts +2 -1
  130. package/src/Modals/components/BotaoFechar.vue +74 -0
  131. package/src/Modals/components/ModalAviso.vue +129 -0
  132. package/src/Modals/components/ModalBaseDefault.vue +374 -0
  133. package/src/Modals/components/ModalConfirmacao.vue +129 -0
  134. package/src/Modals/components/ModalConfirmacaoCheckbox.vue +155 -0
  135. package/src/Modals/components/ModalConfirmacaoInput.vue +200 -0
  136. package/src/Modals/components/ModalConfirmacaoSimples.vue +306 -0
  137. package/src/Modals/components/ModalInformacao.vue +129 -0
  138. package/src/Modals/components/ModalPerigo.vue +123 -0
  139. package/src/Modals/components/ModalSucesso.vue +123 -0
  140. package/src/Modals/components/interno/ModalDialogoInterno.vue +365 -0
  141. package/src/Modals/index.ts +32 -0
  142. package/src/core/plugin.ts +34 -41
  143. package/src/types/global.d.ts +7 -1
  144. package/dist/Pagination.d.ts +0 -27
  145. package/dist/core.d.ts +0 -117
  146. package/dist/datatableConfig-BMFlKtgh.js +0 -4
  147. package/dist/iframeCommunicator.d.ts +0 -22
  148. package/dist/plugin-BwqrOSD_.js +0 -2097
  149. package/dist/toast.d.ts +0 -19
  150. package/dist/vDataAgenda.d.ts +0 -929
  151. package/dist/vDataPage.d.ts +0 -117
  152. package/dist/vDataTable.d.ts +0 -294
@@ -7,6 +7,7 @@ da lista contendo o recurso atualmente em exibição.
7
7
  ========
8
8
  -->
9
9
  <script setup lang="ts">
10
+ defineSlots<{ [key: string]: any }>();
10
11
  import { ref, computed, inject } from 'vue';
11
12
  import { VueCal } from 'vue-cal';
12
13
  import 'vue-cal/style.css';
@@ -1,2 +1,3 @@
1
1
  import VDataAgenda from "./VDataAgenda.vue";
2
- export default VDataAgenda;
2
+ export default VDataAgenda;
3
+
@@ -0,0 +1,74 @@
1
+ <!--
2
+ ========
3
+ Componente de botão de fechar padronizado seguindo a identidade visual do ModalReserva.
4
+ Pode ser utilizado dentro de cabeçalhos de modais ou posicionado de forma flutuante no canto
5
+ superior direito, emitindo o evento de clique quando não estiver desabilitado.
6
+ ========
7
+ -->
8
+ <template>
9
+ <button
10
+ type="button"
11
+ class="btn-fechar"
12
+ :class="{ 'btn-fechar-flutuante': flutuante }"
13
+ :title="titulo"
14
+ :aria-label="titulo"
15
+ :disabled="desabilitado"
16
+ @click="aoClicar"
17
+ >
18
+ ×
19
+ </button>
20
+ </template>
21
+
22
+ <script setup lang="ts">
23
+ // Propriedades de configuração visual e estado do botão de fechar
24
+ const props = defineProps({
25
+ titulo: { type: String, default: "Fechar" },
26
+ desabilitado: { type: Boolean, default: false },
27
+ flutuante: { type: Boolean, default: false }
28
+ });
29
+
30
+ // Evento emitido ao acionar o botão
31
+ const emit = defineEmits<{
32
+ (e: "click", evento: MouseEvent): void;
33
+ }>();
34
+
35
+ // Recebe o evento de clique do mouse, não devolve valor e repassa o evento caso o botão esteja ativo
36
+ function aoClicar(evento: MouseEvent) {
37
+ if (props.desabilitado) return;
38
+ emit("click", evento);
39
+ }
40
+ </script>
41
+
42
+ <style scoped>
43
+ .btn-fechar {
44
+ background: transparent;
45
+ border: none;
46
+ font-size: 24px;
47
+ color: var(--text-secondary, var(--tblr-secondary, #64748b));
48
+ cursor: pointer;
49
+ line-height: 1;
50
+ padding: 4px 8px;
51
+ border-radius: 6px;
52
+ display: inline-flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ transition: color 0.2s ease, background-color 0.2s ease;
56
+ }
57
+
58
+ .btn-fechar:hover:not(:disabled) {
59
+ color: var(--text-primary, var(--tblr-body-color, #1e293b));
60
+ background-color: var(--bg-hover, rgba(0, 0, 0, 0.05));
61
+ }
62
+
63
+ .btn-fechar:disabled {
64
+ opacity: 0.5;
65
+ cursor: not-allowed;
66
+ }
67
+
68
+ .btn-fechar-flutuante {
69
+ position: absolute;
70
+ top: 12px;
71
+ right: 12px;
72
+ z-index: 10;
73
+ }
74
+ </style>
@@ -0,0 +1,129 @@
1
+ <!--
2
+ ========
3
+ Modal especializado para avisos, alertas preventivos ou comunicados da marca.
4
+ Permite alternar entre o amarelo de atenção (Warning) e a cor institucional.
5
+ ========
6
+ -->
7
+ <template>
8
+ <ModalDialogoInterno
9
+ v-model="exibirModal"
10
+ :tamanho="tamanho"
11
+ :cor-topo="usarCorBrand ? 'brand' : 'warning'"
12
+ :cor-botao-confirmar="usarCorBrand ? 'brand' : 'warning'"
13
+ :titulo="titulo"
14
+ :descricao="descricao"
15
+ :texto-cancelar="textoCancelar"
16
+ :texto-confirmar="textoConfirmar"
17
+ :mostrar-botao-cancelar="mostrarBotaoCancelar"
18
+ :mostrar-botao-confirmar="mostrarBotaoConfirmar"
19
+ :mostrar-botao-fechar="mostrarBotaoFechar"
20
+ :fechar-ao-clicar-fora="fecharAoClicarFora"
21
+ :fechar-com-esc="fecharComEsc"
22
+ :fechar-ao-confirmar="fecharAoConfirmar"
23
+ :desabilitar-confirmar="desabilitarConfirmar"
24
+ :carregando="carregando"
25
+ @confirmar="emit('confirmar')"
26
+ @cancelar="emit('cancelar')"
27
+ @fechar="emit('fechar')"
28
+ >
29
+ <template #icone>
30
+ <slot name="icone">
31
+ <IconAlertCircle
32
+ class="icon mb-2 icone-destaque"
33
+ :class="usarCorBrand ? '' : 'text-warning'"
34
+ :style="usarCorBrand ? { color: 'var(--color-brand, var(--tblr-primary))' } : {}"
35
+ stroke-width="1.5"
36
+ />
37
+ </slot>
38
+ </template>
39
+
40
+ <template v-if="slots.titulo" #titulo>
41
+ <slot name="titulo"></slot>
42
+ </template>
43
+
44
+ <template v-if="slots.default" #default>
45
+ <slot></slot>
46
+ </template>
47
+
48
+ <template v-if="slots.conteudo" #conteudo>
49
+ <slot name="conteudo"></slot>
50
+ </template>
51
+
52
+ <template v-if="slots.extra" #extra>
53
+ <slot name="extra"></slot>
54
+ </template>
55
+
56
+ <template v-if="slots['botoes-esquerda']" #botoes-esquerda="escopo">
57
+ <slot name="botoes-esquerda" v-bind="escopo"></slot>
58
+ </template>
59
+
60
+ <template v-if="slots['botoes-meio']" #botoes-meio="escopo">
61
+ <slot name="botoes-meio" v-bind="escopo"></slot>
62
+ </template>
63
+
64
+ <template v-if="slots['botoes-direita']" #botoes-direita="escopo">
65
+ <slot name="botoes-direita" v-bind="escopo"></slot>
66
+ </template>
67
+
68
+ <template v-if="slots.footer" #footer="escopo">
69
+ <slot name="footer" v-bind="escopo"></slot>
70
+ </template>
71
+ </ModalDialogoInterno>
72
+ </template>
73
+
74
+ <script setup lang="ts">
75
+ import { computed, useSlots } from "vue";
76
+ import { IconAlertCircle } from "@tabler/icons-vue";
77
+ import ModalDialogoInterno, { type EscopoRodapeModal } from "./interno/ModalDialogoInterno.vue";
78
+
79
+ // Tipagem dos slots aceitos pelo componente
80
+ defineSlots<{
81
+ default?: (props: {}) => any;
82
+ icone?: (props: {}) => any;
83
+ titulo?: (props: {}) => any;
84
+ conteudo?: (props: {}) => any;
85
+ extra?: (props: {}) => any;
86
+ "botoes-esquerda"?: (props: EscopoRodapeModal) => any;
87
+ "botoes-meio"?: (props: EscopoRodapeModal) => any;
88
+ "botoes-direita"?: (props: EscopoRodapeModal) => any;
89
+ footer?: (props: EscopoRodapeModal) => any;
90
+ }>();
91
+
92
+ // Instância de slots para verificação segura no template
93
+ const slots = useSlots();
94
+
95
+ // Propriedades de configuração do modal de aviso
96
+ const props = defineProps({
97
+ modelValue: { type: Boolean, default: false },
98
+ tamanho: { type: String as () => "sm" | "md" | "lg", default: "sm" },
99
+ usarCorBrand: { type: Boolean, default: false },
100
+ titulo: { type: String, default: "Atenção" },
101
+ descricao: { type: String, default: "" },
102
+ textoCancelar: { type: String, default: "Cancelar" },
103
+ textoConfirmar: { type: String, default: "Entendi" },
104
+ mostrarBotaoCancelar: { type: Boolean, default: true },
105
+ mostrarBotaoConfirmar: { type: Boolean, default: true },
106
+ mostrarBotaoFechar: { type: Boolean, default: true },
107
+ fecharAoClicarFora: { type: Boolean, default: true },
108
+ fecharComEsc: { type: Boolean, default: true },
109
+ fecharAoConfirmar: { type: Boolean, default: false },
110
+ desabilitarConfirmar: { type: Boolean, default: false },
111
+ carregando: { type: Boolean, default: false }
112
+ });
113
+
114
+ // Eventos emitidos para o componente pai
115
+ const emit = defineEmits(["update:modelValue", "confirmar", "cancelar", "fechar"]);
116
+
117
+ // Sincroniza o estado de abertura do modal
118
+ const exibirModal = computed({
119
+ get: () => props.modelValue,
120
+ set: (valor: boolean) => emit("update:modelValue", valor)
121
+ });
122
+ </script>
123
+
124
+ <style scoped>
125
+ .icone-destaque {
126
+ width: 3.5rem;
127
+ height: 3.5rem;
128
+ }
129
+ </style>
@@ -0,0 +1,374 @@
1
+ <!--
2
+ ========
3
+ Componente de modal base padrão para formulários, tabelas e conteúdos extensos.
4
+ Segue a arquitetura e estilização do ModalReserva utilizando Vue e Tabler, com cabeçalho,
5
+ botão de fechar padronizado, barra de status superior e rodapé customizável.
6
+ ========
7
+ -->
8
+ <template>
9
+ <Teleport to="body">
10
+ <div
11
+ v-if="exibirModal"
12
+ :id="id ? String(id) : undefined"
13
+ class="modal-overlay"
14
+ @mousedown.self="aoClicarFora"
15
+ >
16
+ <div
17
+ class="modal-card"
18
+ :class="`modal-tamanho-${tamanhoCalculado}`"
19
+ role="dialog"
20
+ aria-modal="true"
21
+ >
22
+ <div
23
+ v-if="corBarraTopo"
24
+ class="modal-status-topo"
25
+ :class="classeStatusTopo"
26
+ :style="estiloStatusTopo"
27
+ ></div>
28
+ <slot name="barrinha-header"></slot>
29
+
30
+ <div v-if="!ocultarCabecalho" class="modal-header">
31
+ <h3 class="modal-title">
32
+ <slot name="title-header">{{ titulo }}</slot>
33
+ </h3>
34
+ <BotaoFechar
35
+ v-if="mostrarBotaoFechar"
36
+ :desabilitado="carregando"
37
+ @click="cancelarAcao"
38
+ />
39
+ </div>
40
+
41
+ <div class="modal-body" :class="classeCorpo">
42
+ <slot></slot>
43
+ <slot name="conteudo"></slot>
44
+ <slot name="content"></slot>
45
+ </div>
46
+
47
+ <div v-if="!ocultarRodape" class="modal-footer">
48
+ <slot name="footer" :fechar="cancelarAcao" :confirmar="confirmarAcao">
49
+ <button
50
+ v-if="mostrarBotaoCancelar"
51
+ type="button"
52
+ class="btn-cancelar-base"
53
+ :disabled="carregando"
54
+ @click="cancelarAcao"
55
+ >
56
+ {{ textoCancelar }}
57
+ </button>
58
+
59
+ <div class="acoes-direita-base">
60
+ <slot name="botoes-esquerda" :fechar="cancelarAcao" :confirmar="confirmarAcao"></slot>
61
+
62
+ <button
63
+ v-if="mostrarBotaoConfirmar"
64
+ type="button"
65
+ class="btn"
66
+ :class="classeBotaoConfirmar"
67
+ :style="estiloBotaoConfirmar"
68
+ :disabled="desabilitarConfirmar || carregando"
69
+ @click="confirmarAcao"
70
+ >
71
+ <span
72
+ v-if="carregando"
73
+ class="spinner-border spinner-border-sm me-2"
74
+ role="status"
75
+ ></span>
76
+ {{ textoConfirmar }}
77
+ </button>
78
+
79
+ <slot name="botoes-direita" :fechar="cancelarAcao" :confirmar="confirmarAcao"></slot>
80
+ </div>
81
+ </slot>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </Teleport>
86
+ </template>
87
+
88
+ <script setup lang="ts">
89
+ import { computed, watch, onUnmounted } from "vue";
90
+ import BotaoFechar from "./BotaoFechar.vue";
91
+
92
+ // Tipagem explícita dos slots do ModalBaseDefault
93
+ defineSlots<{
94
+ default?: (props: {}) => any;
95
+ "barrinha-header"?: (props: {}) => any;
96
+ "title-header"?: (props: {}) => any;
97
+ conteudo?: (props: {}) => any;
98
+ content?: (props: {}) => any;
99
+ "botoes-esquerda"?: (props: { fechar: () => void; confirmar: () => void }) => any;
100
+ "botoes-direita"?: (props: { fechar: () => void; confirmar: () => void }) => any;
101
+ footer?: (props: { fechar: () => void; confirmar: () => void }) => any;
102
+ }>();
103
+
104
+ // Propriedades de configuração do modal padrão
105
+ const props = defineProps({
106
+ id: { type: [String, Number], default: undefined },
107
+ modelValue: { type: Boolean, default: false },
108
+ size: { type: String as () => "sm" | "md" | "lg" | "xl", default: "lg" },
109
+ tamanho: { type: String as () => "sm" | "md" | "lg" | "xl", default: undefined },
110
+ titulo: { type: String, default: "" },
111
+ corBarraTopo: {
112
+ type: String as () => "brand" | "danger" | "success" | "warning" | "info" | "primary" | "",
113
+ default: "brand"
114
+ },
115
+ textoCancelar: { type: String, default: "Fechar" },
116
+ textoConfirmar: { type: String, default: "Salvar alterações" },
117
+ corBotaoConfirmar: {
118
+ type: String as () => "brand" | "primary" | "danger" | "success" | "warning",
119
+ default: "brand"
120
+ },
121
+ mostrarBotaoCancelar: { type: Boolean, default: true },
122
+ mostrarBotaoConfirmar: { type: Boolean, default: true },
123
+ mostrarBotaoFechar: { type: Boolean, default: true },
124
+ ocultarCabecalho: { type: Boolean, default: false },
125
+ ocultarRodape: { type: Boolean, default: false },
126
+ fecharAoClicarFora: { type: Boolean, default: true },
127
+ fecharComEsc: { type: Boolean, default: true },
128
+ fecharAoConfirmar: { type: Boolean, default: false },
129
+ desabilitarConfirmar: { type: Boolean, default: false },
130
+ carregando: { type: Boolean, default: false },
131
+ classeCorpo: { type: String, default: "" }
132
+ });
133
+
134
+ // Emissores de eventos para controle externo
135
+ const emit = defineEmits(["update:modelValue", "confirmar", "cancelar", "fechar"]);
136
+
137
+ // Resolve o tamanho priorizando a propriedade em português
138
+ const tamanhoCalculado = computed(() => props.tamanho || props.size);
139
+
140
+ // Sincroniza o estado de abertura do modal com o componente pai
141
+ const exibirModal = computed({
142
+ get: () => props.modelValue,
143
+ set: (valor: boolean) => emit("update:modelValue", valor)
144
+ });
145
+
146
+ // Calcula o bloqueio de clique fora do modal
147
+ const bloquearCliqueFora = computed(() => !props.fecharAoClicarFora || props.carregando);
148
+
149
+ // Calcula o bloqueio da tecla ESC
150
+ const bloquearEsc = computed(() => !props.fecharComEsc || props.carregando);
151
+
152
+ // Retorna a classe da barra de topo caso não seja brand
153
+ const classeStatusTopo = computed(() => {
154
+ if (!props.corBarraTopo || props.corBarraTopo === "brand") return "";
155
+ return `bg-${props.corBarraTopo}`;
156
+ });
157
+
158
+ // Retorna o estilo inline para barra de topo com var(--color-brand)
159
+ const estiloStatusTopo = computed(() => {
160
+ if (props.corBarraTopo === "brand") {
161
+ return { backgroundColor: "var(--color-brand, var(--tblr-primary, #206bc4))" };
162
+ }
163
+ return {};
164
+ });
165
+
166
+ // Retorna a classe do botão de confirmação
167
+ const classeBotaoConfirmar = computed(() => {
168
+ if (props.corBotaoConfirmar === "brand") return "btn-salvar-base";
169
+ return `btn-${props.corBotaoConfirmar}`;
170
+ });
171
+
172
+ // Retorna o estilo inline do botão de confirmação quando configurado como brand
173
+ const estiloBotaoConfirmar = computed(() => {
174
+ if (props.corBotaoConfirmar === "brand") {
175
+ return {
176
+ backgroundColor: "var(--color-brand, var(--tblr-primary, #206bc4))",
177
+ color: "var(--text-inverse, #ffffff)"
178
+ };
179
+ }
180
+ return {};
181
+ });
182
+
183
+ // Recebe o evento de teclado, não devolve valor e fecha o modal se a tecla for ESC
184
+ function aoPressionarTecla(evento: KeyboardEvent) {
185
+ if (evento.key === "Escape" && exibirModal.value && !bloquearEsc.value) {
186
+ cancelarAcao();
187
+ }
188
+ }
189
+
190
+ // Monitora o estado de abertura para ativar ou remover o evento de teclado
191
+ watch(
192
+ exibirModal,
193
+ (aberto) => {
194
+ if (typeof window === "undefined") return;
195
+ if (aberto) {
196
+ window.addEventListener("keydown", aoPressionarTecla);
197
+ } else {
198
+ window.removeEventListener("keydown", aoPressionarTecla);
199
+ }
200
+ },
201
+ { immediate: true }
202
+ );
203
+
204
+ onUnmounted(() => {
205
+ if (typeof window !== "undefined") {
206
+ window.removeEventListener("keydown", aoPressionarTecla);
207
+ }
208
+ });
209
+
210
+ // Não recebe parâmetros, não devolve valor e trata o clique no fundo escuro do modal
211
+ function aoClicarFora() {
212
+ if (bloquearCliqueFora.value) return;
213
+ cancelarAcao();
214
+ }
215
+
216
+ // Não recebe parâmetros, não devolve valor e fecha o modal emitindo os eventos de cancelamento e fechamento
217
+ function cancelarAcao() {
218
+ if (props.carregando) return;
219
+ exibirModal.value = false;
220
+ emit("cancelar");
221
+ emit("fechar");
222
+ }
223
+
224
+ // Não recebe parâmetros, não devolve valor e emite o evento de confirmação do modal
225
+ function confirmarAcao() {
226
+ if (props.desabilitarConfirmar || props.carregando) return;
227
+ emit("confirmar");
228
+ if (props.fecharAoConfirmar) {
229
+ exibirModal.value = false;
230
+ }
231
+ }
232
+ </script>
233
+
234
+ <style scoped>
235
+ .modal-overlay {
236
+ position: fixed;
237
+ top: 0;
238
+ left: 0;
239
+ width: 100vw;
240
+ height: 100vh;
241
+ padding: 16px;
242
+ box-sizing: border-box;
243
+ background: rgba(0, 0, 0, 0.4);
244
+ display: flex;
245
+ align-items: center;
246
+ justify-content: center;
247
+ z-index: 1050;
248
+ backdrop-filter: blur(2px);
249
+ }
250
+
251
+ .modal-card {
252
+ background: var(--bg-modal, var(--bg-primary, var(--tblr-bg-surface, #ffffff)));
253
+ color: var(--text-primary, var(--tblr-body-color, #1e293b));
254
+ width: 100%;
255
+ max-height: calc(100vh - 32px);
256
+ border-radius: 12px;
257
+ box-shadow: var(--shadow-float, 0 10px 25px rgba(0, 0, 0, 0.15));
258
+ border: 1px solid var(--border-light, var(--tblr-border-color, rgba(0, 0, 0, 0.08)));
259
+ display: flex;
260
+ flex-direction: column;
261
+ overflow: hidden;
262
+ position: relative;
263
+ }
264
+
265
+ .modal-tamanho-sm {
266
+ max-width: 400px;
267
+ }
268
+
269
+ .modal-tamanho-md {
270
+ max-width: 540px;
271
+ }
272
+
273
+ .modal-tamanho-lg {
274
+ max-width: 720px;
275
+ }
276
+
277
+ .modal-tamanho-xl {
278
+ max-width: 1140px;
279
+ }
280
+
281
+ .modal-status-topo {
282
+ height: 4px;
283
+ width: 100%;
284
+ flex-shrink: 0;
285
+ }
286
+
287
+ .modal-header {
288
+ display: flex;
289
+ justify-content: space-between;
290
+ align-items: center;
291
+ padding: 16px 20px;
292
+ border-bottom: 1px solid var(--border-light, var(--tblr-border-color, #e6e7e9));
293
+ background: var(--bg-primary, var(--tblr-bg-surface, #ffffff));
294
+ flex-shrink: 0;
295
+ }
296
+
297
+ .modal-title {
298
+ margin: 0;
299
+ font-size: 16px;
300
+ color: var(--text-primary, var(--tblr-body-color, #1e293b));
301
+ font-weight: 600;
302
+ }
303
+
304
+ .modal-body {
305
+ padding: 20px;
306
+ display: flex;
307
+ flex-direction: column;
308
+ gap: 14px;
309
+ background: var(--bg-primary, var(--tblr-bg-surface, #ffffff));
310
+ flex: 1 1 auto;
311
+ min-height: 0;
312
+ overflow-y: auto;
313
+ }
314
+
315
+ .modal-footer {
316
+ display: flex;
317
+ justify-content: space-between;
318
+ align-items: center;
319
+ flex-wrap: wrap;
320
+ gap: 12px;
321
+ padding: 16px 20px;
322
+ border-top: 1px solid var(--border-light, var(--tblr-border-color, #e6e7e9));
323
+ background: var(--bg-secondary, var(--tblr-bg-surface-secondary, #f8fafc));
324
+ flex-shrink: 0;
325
+ }
326
+
327
+ .acoes-direita-base {
328
+ display: flex;
329
+ align-items: center;
330
+ flex-wrap: wrap;
331
+ gap: 12px;
332
+ margin-left: auto;
333
+ }
334
+
335
+ .btn-cancelar-base {
336
+ background: transparent;
337
+ border: none;
338
+ color: var(--color-brand, var(--tblr-primary, #206bc4));
339
+ font-weight: 600;
340
+ font-size: 14px;
341
+ cursor: pointer;
342
+ padding: 8px 16px;
343
+ border-radius: 6px;
344
+ transition: background 0.2s;
345
+ }
346
+
347
+ .btn-cancelar-base:hover:not(:disabled) {
348
+ background: var(--color-brand-light, rgba(32, 107, 196, 0.1));
349
+ }
350
+
351
+ .btn-cancelar-base:disabled {
352
+ opacity: 0.6;
353
+ cursor: not-allowed;
354
+ }
355
+
356
+ .btn-salvar-base {
357
+ border: none;
358
+ font-weight: 600;
359
+ font-size: 14px;
360
+ cursor: pointer;
361
+ padding: 8px 24px;
362
+ border-radius: 6px;
363
+ transition: filter 0.2s;
364
+ }
365
+
366
+ .btn-salvar-base:hover:not(:disabled) {
367
+ filter: brightness(0.9);
368
+ }
369
+
370
+ .btn-salvar-base:disabled {
371
+ opacity: 0.6;
372
+ cursor: not-allowed;
373
+ }
374
+ </style>