@bildvitta/quasar-ui-asteroid 3.20.0-beta.2 → 3.20.0-beta.21

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 (102) hide show
  1. package/package.json +3 -3
  2. package/src/asteroid.js +8 -1
  3. package/src/components/actions/QasActions.vue +12 -2
  4. package/src/components/actions-menu/QasActionsMenu.vue +18 -5
  5. package/src/components/alert/QasAlert.vue +89 -64
  6. package/src/components/app-user/QasAppUser.vue +2 -1
  7. package/src/components/board-generator/QasBoardGenerator.vue +883 -162
  8. package/src/components/board-generator/QasBoardGenerator.yml +83 -2
  9. package/src/components/board-generator/private/PvBoardGeneratorCardsContainer.vue +25 -0
  10. package/src/components/box/QasBox.vue +16 -3
  11. package/src/components/box/QasBox.yml +10 -0
  12. package/src/components/btn/QasBtn.vue +27 -5
  13. package/src/components/btn/QasBtn.yml +10 -1
  14. package/src/components/btn-dropdown/QasBtnDropdown.vue +13 -1
  15. package/src/components/card/QasCard.vue +97 -25
  16. package/src/components/card/QasCard.yml +10 -0
  17. package/src/components/card-image/QasCardImage.vue +10 -1
  18. package/src/components/card-image/QasCardImage.yml +5 -0
  19. package/src/components/chart-view/QasChartView.vue +4 -3
  20. package/src/components/chart-view/QasChartView.yml +5 -0
  21. package/src/components/checkbox/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  22. package/src/components/copy/QasCopy.vue +6 -1
  23. package/src/components/copy/QasCopy.yml +5 -0
  24. package/src/components/date-time-input/QasDateTimeInput.vue +30 -6
  25. package/src/components/dialog/QasDialog.vue +308 -91
  26. package/src/components/dialog/QasDialog.yml +51 -23
  27. package/src/components/dialog/composables/use-cancel.js +1 -1
  28. package/src/components/dialog/composables/use-dynamic-components.js +2 -2
  29. package/src/components/dialog/composables/use-ok.js +1 -0
  30. package/src/components/dialog-router/QasDialogRouter.vue +1 -1
  31. package/src/components/drawer/QasDrawer.vue +76 -26
  32. package/src/components/drawer/QasDrawer.yml +10 -0
  33. package/src/components/expansion-item/QasExpansionItem.yml +5 -0
  34. package/src/components/filters/QasFilters.vue +2 -1
  35. package/src/components/filters/private/PvFiltersActions.vue +79 -13
  36. package/src/components/form-generator/QasFormGenerator.vue +8 -1
  37. package/src/components/form-generator/QasFormGenerator.yml +10 -0
  38. package/src/components/form-view/QasFormView.vue +20 -11
  39. package/src/components/form-view/QasFormView.yml +6 -0
  40. package/src/components/gallery/composables/use-delete.js +2 -3
  41. package/src/components/gallery/private/PvGalleryCarouselDialog.vue +8 -7
  42. package/src/components/grid-item/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  43. package/src/components/header/QasHeader.vue +66 -11
  44. package/src/components/header/QasHeader.yml +16 -1
  45. package/src/components/infinite-scroll/QasInfiniteScroll.vue +1 -1
  46. package/src/components/label/QasLabel.vue +3 -1
  47. package/src/components/layout/QasLayout.vue +16 -1
  48. package/src/components/layout/private/PvLayoutNotificationsDrawer.vue +2 -1
  49. package/src/components/layout/private/PvLayoutOverlayDrawer.vue +4 -2
  50. package/src/components/lazy-loading-components/QasLazyLoadingComponents.vue +262 -0
  51. package/src/components/lazy-loading-components/QasLazyLoadingComponents.yml +49 -0
  52. package/src/components/list-view/QasListView.vue +12 -4
  53. package/src/components/list-view/QasListView.yml +12 -0
  54. package/src/components/page-header/QasPageHeader.vue +49 -3
  55. package/src/components/page-header/QasPageHeader.yml +5 -0
  56. package/src/components/router-link/QasRouterLink.vue +72 -0
  57. package/src/components/router-link/QasRouterLink.yml +24 -0
  58. package/src/components/search-box/QasSearchBox.vue +1 -1
  59. package/src/components/select/QasSelect.vue +8 -1
  60. package/src/components/select-list-dialog/QasSelectListDialog.vue +40 -20
  61. package/src/components/select-list-dialog/QasSelectListDialog.yml +14 -2
  62. package/src/components/signature-uploader/QasSignatureUploader.vue +5 -18
  63. package/src/components/single-view/QasSingleView.vue +2 -2
  64. package/src/components/skeleton/QasSkeleton.vue +139 -0
  65. package/src/components/skeleton/QasSkeleton.yml +48 -0
  66. package/src/components/sortable/QasSortable.vue +1 -1
  67. package/src/components/stepper/QasStepper.vue +24 -2
  68. package/src/components/table-generator/QasTableGenerator.vue +186 -35
  69. package/src/components/table-generator/QasTableGenerator.yml +6 -1
  70. package/src/components/tabs-generator/QasTabsGenerator.vue +14 -3
  71. package/src/components/tabs-generator/QasTabsGenerator.yml +5 -1
  72. package/src/components/text-truncate/QasTextTruncate.vue +61 -12
  73. package/src/components/text-truncate/QasTextTruncate.yml +5 -0
  74. package/src/components/toggle-visibility/QasToggleVisibility.vue +2 -1
  75. package/src/components/tooltip/QasTooltip.vue +6 -1
  76. package/src/components/tree-generator/QasTreeGenerator.vue +4 -6
  77. package/src/components/uploader/QasUploader.vue +12 -2
  78. package/src/composables/private/use-view.js +1 -1
  79. package/src/composables/use-overlay-navigation.js +116 -10
  80. package/src/composables/use-screen.js +17 -1
  81. package/src/css/components/button.scss +82 -3
  82. package/src/css/components/item.scss +6 -0
  83. package/src/css/utils/background.scss +5 -0
  84. package/src/css/utils/border.scss +6 -0
  85. package/src/css/utils/container.scss +4 -3
  86. package/src/css/utils/text.scss +9 -0
  87. package/src/helpers/copy-to-clipboard.js +2 -1
  88. package/src/helpers/filters.js +1 -1
  89. package/src/helpers/promise-handler.js +2 -1
  90. package/src/helpers/set-scroll-gradient.js +31 -8
  91. package/src/helpers/set-scroll-on-grab.js +10 -3
  92. package/src/index.scss +1 -0
  93. package/src/mixins/search-filter.js +7 -1
  94. package/src/plugins/delete/Delete.js +7 -9
  95. package/src/plugins/delete/Delete.yml +1 -1
  96. package/src/plugins/dialog/Dialog.yml +1 -1
  97. package/src/plugins/notify-error/NotifyError.yml +1 -1
  98. package/src/plugins/notify-success/NotifySuccess.yml +1 -1
  99. package/src/plugins/screen/Screen.js +17 -1
  100. package/src/plugins/screen/Screen.yml +5 -1
  101. package/src/vue-plugin.js +5 -7
  102. package/src/plugins/index.js +0 -5
@@ -52,6 +52,11 @@ props:
52
52
  default: {}
53
53
  type: Object
54
54
 
55
+ skeleton:
56
+ desc: Exibe um esqueleto de carregamento no lugar do conteúdo.
57
+ default: false
58
+ type: Boolean
59
+
55
60
  subtitle:
56
61
  desc: Define um subtítulo para o gráfico.
57
62
  type: String
@@ -0,0 +1 @@
1
+ {"version":"4.0.18","results":[[":QasCheckbox.test.js",{"duration":0,"failed":true}]]}
@@ -7,7 +7,7 @@
7
7
  </slot>
8
8
  </span>
9
9
 
10
- <qas-btn class="q-ml-xs" color="primary" :icon="props.icon" :loading="isLoading" variant="tertiary" @click.stop.prevent="copy">
10
+ <qas-btn class="q-ml-xs" color="primary" :icon="props.icon" :loading="isLoading" variant="tertiary" v-bind="props.buttonProps" @click.stop.prevent="copy">
11
11
  <qas-tooltip text="Copiar" />
12
12
  </qas-btn>
13
13
  </span>
@@ -41,6 +41,11 @@ const props = defineProps({
41
41
  rawText: {
42
42
  default: '',
43
43
  type: String
44
+ },
45
+
46
+ buttonProps: {
47
+ type: Object,
48
+ default: () => ({})
44
49
  }
45
50
  })
46
51
 
@@ -21,3 +21,8 @@ props:
21
21
  raw-text:
22
22
  desc: Caso o texto a ser copiado precise ser diferente do texto a ser exibido, utilize esta propriedade.
23
23
  type: String
24
+
25
+ button-props:
26
+ desc: Propriedades adicionais que serão repassadas ao botão.
27
+ type: Object
28
+ default: () => ({})
@@ -165,6 +165,12 @@ const hasDatePicker = computed(() => !props.useTimeOnly && !props.readonly)
165
165
  const hasTimePicker = computed(() => !props.useDateOnly && !props.readonly)
166
166
 
167
167
  watch(() => props.modelValue, (current, original) => {
168
+ /**
169
+ * No caso de ser adicionado uma data incompleta ou inválida, vamos limpar o model,
170
+ * mas não vamos limpar o "currentValue", para não limpar o campo, somente o model.
171
+ */
172
+ if (!current && original && error.value) return
173
+
168
174
  if (!current || props.useTimeOnly) {
169
175
  currentValue.value = current
170
176
  return
@@ -217,6 +223,9 @@ function updateModelValue (value) {
217
223
  if (error.value) {
218
224
  hasInvalidDate.value = true
219
225
  errorMessage.value = 'Data inválida.'
226
+
227
+ emit('update:modelValue', '')
228
+
220
229
  return
221
230
  }
222
231
 
@@ -262,18 +271,33 @@ function validateDateAndTime (value) {
262
271
  function validateDateTimeOnBlur () {
263
272
  const valueLength = currentValue.value?.replace?.(/_/g, '')?.length
264
273
 
274
+ // Caso for datetime
275
+ if (!props.useDateOnly && !props.useTimeOnly) {
276
+ const [date, time] = (currentValue.value || '').split(' ') || []
277
+ const isValidDate = date?.replace?.(/_/g, '')?.length === props.dateMask.length
278
+
279
+ /**
280
+ * Caso tenha preenchido a data, a data seja válida e não tenha preenchido o horário,
281
+ * preenche o horário com 00:00, ou de acordo com a mask.
282
+ */
283
+ if (isValidDate && !validateDateOnly(date) && !time?.length) {
284
+ // Horario setado deve seguir a mascara.
285
+ const defaultTimeByMask = props.timeMask.replace(/[HhMmSs]/g, '0')
286
+ const newValue = `${date} ${defaultTimeByMask}`
287
+
288
+ currentValue.value = newValue
289
+ updateModelValue(newValue)
290
+
291
+ return
292
+ }
293
+ }
294
+
265
295
  // valida se o tamanho digitado é o tamanho que a mascara espera receber
266
296
  error.value = !!((valueLength < mask.value.length || error.value) && valueLength)
267
297
 
268
298
  if (error.value && !hasInvalidDate.value) {
269
299
  errorMessage.value = 'Data incompleta.'
270
- }
271
-
272
- if (hasInvalidDate.value) {
273
- currentValue.value = ''
274
- }
275
300
 
276
- if (error.value || hasInvalidDate.value) {
277
301
  emit('update:modelValue', '')
278
302
  }
279
303
  }
@@ -1,35 +1,29 @@
1
1
  <template>
2
- <q-dialog ref="dialogRef" class="qas-dialog" :class="classes" data-cy="dialog" v-bind="dialogProps" :persistent="props.persistent" @update:model-value="updateModelValue">
3
- <div class="bg-white q-pa-md" :style="style">
4
- <header v-if="hasHeader" class="q-mb-md">
5
- <slot name="header">
6
- <div class="items-center justify-between row">
7
- <qas-label data-cy="dialog-title" :label="props.card.title" margin="none" />
8
-
9
- <qas-btn v-if="isInfoDialog" v-close-popup color="grey-10" data-cy="dialog-close-btn" icon="sym_r_close" variant="tertiary" />
10
- </div>
11
- </slot>
2
+ <q-dialog ref="dialogRef" v-model="model" class="qas-dialog" :class="classes" data-cy="dialog" v-bind="dialogProps">
3
+ <div class="bg-white full-width q-pa-md qas-dialog__container">
4
+ <header v-if="hasHeaderSlot" class="q-mb-md">
5
+ <slot name="header" />
12
6
  </header>
13
7
 
8
+ <qas-header v-else-if="props.title" v-bind="headerProps">
9
+ <template v-if="hasTitleSlot" #label>
10
+ <qas-label>
11
+ <slot name="title" />
12
+ </qas-label>
13
+ </template>
14
+ </qas-header>
15
+
14
16
  <section class="relative-position text-body1 text-grey-8">
15
17
  <component :is="mainComponent.is" ref="form" v-bind="mainComponent.props">
16
18
  <slot name="description">
17
- <component :is="descriptionComponent" data-cy="dialog-description">{{ props.card.description }}</component>
19
+ <div v-if="props.useHtmlDescription" data-cy="dialog-description" v-html="props.description" />
20
+
21
+ <component :is="descriptionComponent" v-else data-cy="dialog-description">
22
+ {{ props.description }}
23
+ </component>
18
24
  </slot>
19
25
 
20
- <div v-if="!isInfoDialog">
21
- <slot name="actions">
22
- <qas-actions v-bind="defaultActionsProps">
23
- <template v-if="hasOk" #primary>
24
- <qas-btn v-close-popup="!props.useForm" class="full-width" data-cy="dialog-ok-btn" size="lg" variant="primary" v-bind="defaultOk" />
25
- </template>
26
-
27
- <template v-if="hasCancel" #secondary>
28
- <qas-btn v-close-popup class="full-width" data-cy="dialog-cancel-btn" size="lg" v-bind="defaultCancel" variant="secondary" />
29
- </template>
30
- </qas-actions>
31
- </slot>
32
- </div>
26
+ <qas-actions v-if="hasActions" class="qas-dialog__actions" v-bind="defaultActionsProps" />
33
27
  </component>
34
28
  </section>
35
29
  </div>
@@ -37,24 +31,19 @@
37
31
  </template>
38
32
 
39
33
  <script setup>
40
- import QasActions from '../actions/QasActions.vue'
41
- import QasBtn from '../btn/QasBtn.vue'
42
34
  import QasLabel from '../label/QasLabel.vue'
35
+ import QasActions from '../actions/QasActions.vue'
36
+ import QasHeader from '../header/QasHeader.vue'
43
37
 
44
- import useCancel from './composables/use-cancel'
45
- import useDynamicComponents from './composables/use-dynamic-components'
46
- import useOk from './composables/use-ok'
47
- import { useScreen } from '../../composables'
48
-
49
- import { computed, ref, useAttrs, useSlots, provide } from 'vue'
50
- import { useDialogPluginComponent } from 'quasar'
38
+ import { computed, ref, useAttrs, provide, useSlots, inject } from 'vue'
39
+ import { useDialogPluginComponent, QForm } from 'quasar'
51
40
 
52
- defineOptions({ name: 'QasDialog' })
41
+ defineOptions({ name: 'QasDialog', inheritAttrs: false })
53
42
 
54
43
  const props = defineProps({
55
- actionsProps: {
56
- default: () => ({}),
57
- type: Object
44
+ badges: {
45
+ default: () => [],
46
+ type: [Array, Object]
58
47
  },
59
48
 
60
49
  cancel: {
@@ -62,19 +51,13 @@ const props = defineProps({
62
51
  type: [Object, Boolean]
63
52
  },
64
53
 
65
- card: {
66
- default: () => ({}),
67
- type: Object
68
- },
69
-
70
- maxWidth: {
71
- default: '',
72
- type: String
54
+ description: {
55
+ type: [String, Object],
56
+ default: ''
73
57
  },
74
58
 
75
- minWidth: {
76
- default: '',
77
- type: String
59
+ disableCloseButton: {
60
+ type: Boolean
78
61
  },
79
62
 
80
63
  ok: {
@@ -82,16 +65,23 @@ const props = defineProps({
82
65
  type: [Object, Boolean]
83
66
  },
84
67
 
85
- persistent: {
86
- default: true,
87
- type: Boolean
68
+ size: {
69
+ type: String,
70
+ default: 'sm',
71
+ validator: value => ['sm', 'md', 'lg', 'xl'].includes(value)
88
72
  },
89
73
 
90
- useForm: {
91
- type: Boolean
74
+ title: {
75
+ type: String,
76
+ required: true
92
77
  },
93
78
 
94
- modelValue: {
79
+ tertiary: {
80
+ default: () => ({}),
81
+ type: Object
82
+ },
83
+
84
+ useForm: {
95
85
  type: Boolean
96
86
  },
97
87
 
@@ -99,7 +89,22 @@ const props = defineProps({
99
89
  type: Boolean
100
90
  },
101
91
 
102
- useFullMaxWidth: {
92
+ useAutoCloseOnCancel: {
93
+ type: Boolean,
94
+ default: true
95
+ },
96
+
97
+ useAutoCloseOnOk: {
98
+ type: Boolean,
99
+ default: true
100
+ },
101
+
102
+ useCloseButton: {
103
+ type: Boolean,
104
+ default: true
105
+ },
106
+
107
+ useHtmlDescription: {
103
108
  type: Boolean
104
109
  },
105
110
 
@@ -108,10 +113,8 @@ const props = defineProps({
108
113
  }
109
114
  })
110
115
 
116
+ // emtis
111
117
  const emit = defineEmits([
112
- // model
113
- 'update:modelValue',
114
-
115
118
  // actions
116
119
  'cancel',
117
120
  'ok',
@@ -121,24 +124,28 @@ const emit = defineEmits([
121
124
  ...useDialogPluginComponent.emits
122
125
  ])
123
126
 
124
- provide('isDialog', true)
127
+ // models
128
+ const model = defineModel({ type: Boolean })
125
129
 
126
- const attrs = useAttrs()
127
- const screen = useScreen()
128
- const slots = useSlots()
130
+ // globals
131
+ const drawerProps = inject('drawerProps', null)
129
132
 
130
- // usado para o plugin
131
- const { dialogRef, onDialogHide } = useDialogPluginComponent()
133
+ provide('isDialog', true)
134
+ provide('btnPropsDefaults', { size: 'md' }) // define o tamanho padrão para os botões dentro do dialog
135
+ provide('drawerProps', null) // quebra a cadeia para dialogs filhos usarem hasActions normalmente
132
136
 
133
- // QForm template
137
+ // refs
134
138
  const form = ref(null)
135
139
 
136
- const composablesParams = { emit, form, props, screen, slots }
137
-
138
- const { defaultCancel, hasCancel } = useCancel(composablesParams)
139
- const { defaultOk, hasOk, onOk } = useOk(composablesParams)
140
- const { descriptionComponent, mainComponent } = useDynamicComponents({ ...composablesParams, onOk, hasOk })
140
+ // composables
141
+ const slots = useSlots()
142
+ const attrs = useAttrs()
143
+ const { dialogRef, onDialogHide } = useDialogPluginComponent() // usado para o plugin
144
+ const { defaultCancel, hasCancel } = useCancel()
145
+ const { defaultOk, hasOk, onOk } = useOk()
146
+ const { descriptionComponent, mainComponent } = useDynamicComponents()
141
147
 
148
+ // computeds
142
149
  /**
143
150
  * Classes criadas para serem utilizadas quando usado com a prop "position", pois
144
151
  * o comportamento do dialog muda, e não é possível usar em conjunto com a prop
@@ -148,60 +155,236 @@ const classes = computed(() => {
148
155
  const isRightPosition = attrs.position === 'right'
149
156
  const isLeftPosition = attrs.position === 'left'
150
157
 
151
- return {
152
- 'qas-dialog--right': isRightPosition,
153
- 'qas-dialog--left': isLeftPosition
158
+ const sizes = {
159
+ sm: 'qas-dialog--sm', // 450px
160
+ md: 'qas-dialog--md', // 550px
161
+ lg: 'qas-dialog--lg', // 800px
162
+ xl: 'qas-dialog--xl' // 1100px
154
163
  }
164
+
165
+ return [
166
+ sizes[props.size],
167
+
168
+ {
169
+ 'qas-dialog--right': isRightPosition,
170
+ 'qas-dialog--left': isLeftPosition
171
+ }
172
+ ]
155
173
  })
156
174
 
157
175
  const dialogProps = computed(() => {
176
+ const { title, ...attributes } = attrs
177
+
158
178
  return {
159
179
  ...(!props.usePlugin && { modelValue: props.modelValue }),
160
- ...attrs,
180
+ ...attributes,
181
+
182
+ /**
183
+ * valida se a prop "persistent" foi passada para o drawer, caso tenha passado,
184
+ * ele respeita a prop, caso contrário é validado se tem ações para ser persistente ou não.
185
+ */
186
+ persistent: drawerProps?.value ? drawerProps?.value.persistent : hasActions.value,
161
187
 
162
188
  onHide: onDialogHide
163
189
  }
164
190
  })
165
191
 
166
- const style = computed(() => {
192
+ const hasActions = computed(() => hasOk.value || hasCancel.value || !!Object.keys(props.tertiary).length)
193
+
194
+ const headerProps = computed(() => {
167
195
  return {
168
- ...(props.useFullMaxWidth && { width: '100%' }),
196
+ labelProps: {
197
+ label: props.title
198
+ },
199
+
200
+ badges: props.badges,
201
+
202
+ buttonProps: {
203
+ ...(props.useCloseButton && {
204
+ color: 'grey-10',
205
+ disable: props.disableCloseButton,
206
+ icon: 'sym_r_close',
207
+ variant: 'tertiary',
208
+ 'data-cy': 'dialog-close-btn',
209
+ onClick: () => updateModelValue(false)
210
+ })
211
+ }
212
+ }
213
+ })
169
214
 
170
- maxWidth: props.maxWidth || '470px',
171
- minWidth: props.minWidth || (screen.isSmall ? '' : '366px')
215
+ const defaultActionsProps = computed(() => {
216
+ return {
217
+ ...(hasOk.value && { primaryButtonProps: defaultOk.value }),
218
+ ...(hasCancel.value && { secondaryButtonProps: defaultCancel.value }),
219
+
220
+ tertiaryButtonProps: {
221
+ ...props.tertiary,
222
+ 'data-cy': 'dialog-tertiary-btn'
223
+ },
224
+
225
+ spacingTop: 'lg',
226
+ gutter: 'md'
172
227
  }
173
228
  })
174
229
 
175
- const hasHeader = computed(() => !!slots.header || props.card.title)
176
- const isInfoDialog = computed(() => !hasOk.value && !hasCancel.value)
230
+ const hasHeaderSlot = computed(() => !!slots.header)
231
+ const hasTitleSlot = computed(() => !!slots.title)
177
232
 
178
- const defaultActionsProps = computed(() => {
179
- const { useFullWidth, useEqualWidth } = props.actionsProps
233
+ // functions
234
+ function updateModelValue (value) {
235
+ model.value = value
236
+ }
180
237
 
181
- if (useFullWidth || useEqualWidth) return props.actionsProps
238
+ // composable definitions
239
+ function useOk () {
240
+ // computeds
241
+ const defaultOk = computed(() => {
242
+ const { onClick, ...attrs } = props.ok
243
+
244
+ return {
245
+ label: 'Ok',
246
+ type: (props.ok?.type || props.useForm) ? 'submit' : 'button',
247
+ 'data-cy': 'dialog-ok-btn',
248
+
249
+ ...attrs,
250
+
251
+ // adiciona somente se não estiver usando useForm pois o controle ficará no submit.
252
+ ...(!props.useForm && { onClick: onOk })
253
+ }
254
+ })
255
+
256
+ const hasOk = computed(() => typeof props.ok === 'boolean' ? props.ok : !!Object.keys(props.ok))
257
+
258
+ // functions
259
+ function onOk () {
260
+ if (!props.useForm && props.useAutoCloseOnOk) {
261
+ updateModelValue(false)
262
+ }
182
263
 
183
- const hasAllActions = hasOk.value && hasCancel.value
184
- const hasSingleAction = (hasOk.value && !hasCancel.value) || (!hasOk.value && hasCancel.value)
264
+ props.ok.onClick?.()
265
+
266
+ emit('ok')
267
+ }
185
268
 
186
269
  return {
187
- useFullWidth: hasSingleAction,
188
- useEqualWidth: hasAllActions,
270
+ defaultOk,
271
+ hasOk,
272
+ onOk
273
+ }
274
+ }
275
+
276
+ function useCancel () {
277
+ // computeds
278
+ const defaultCancel = computed(() => {
279
+ return {
280
+ label: 'Cancelar',
281
+ 'data-cy': 'dialog-cancel-btn',
282
+
283
+ ...props.cancel,
284
+
285
+ onClick: onCancel
286
+ }
287
+ })
189
288
 
190
- ...props.actionsProps
289
+ const hasCancel = computed(() => typeof props.cancel === 'boolean' ? props.cancel : !!Object.keys(props.cancel))
290
+
291
+ // functions
292
+ function onCancel () {
293
+ props.cancel.onClick?.()
294
+
295
+ if (props.useAutoCloseOnAction || props.useAutoCloseOnCancel) {
296
+ updateModelValue(false)
297
+ }
298
+
299
+ emit('cancel')
191
300
  }
192
- })
193
301
 
194
- function updateModelValue (value) {
195
- emit('update:modelValue', value)
302
+ return {
303
+ defaultCancel,
304
+ hasCancel
305
+ }
306
+ }
307
+
308
+ function useDynamicComponents () {
309
+ // computeds
310
+ const mainComponent = computed(() => {
311
+ return {
312
+ is: props.useForm ? QForm : 'div',
313
+
314
+ /**
315
+ * adiciona evento de submit caso useForm seja true,
316
+ * uma vez que somente o q-form possui este evento.
317
+ */
318
+ props: {
319
+ ...(props.useForm && { onSubmit })
320
+ }
321
+ }
322
+ })
323
+
324
+ const hasRenderFunction = computed(() => {
325
+ const description = props.description
326
+
327
+ return typeof description === 'object' && description !== null && !Array.isArray(description)
328
+ })
329
+
330
+ const descriptionComponent = computed(() => hasRenderFunction.value ? props.description : 'div')
331
+
332
+ // functions
333
+ function submitHandler () {
334
+ if (!props.useForm) return
335
+
336
+ if (props.useValidationAllAtOnce) {
337
+ let isAllComponentValid = true
338
+ const components = form.value.getValidationComponents() || []
339
+
340
+ for (const component of components) {
341
+ const isValid = component?.validate?.()
342
+
343
+ if (!isValid) {
344
+ isAllComponentValid = false
345
+ }
346
+ }
347
+
348
+ emit('validate', isAllComponentValid)
349
+
350
+ return
351
+ }
352
+
353
+ emit('validate', form.value.validate())
354
+ }
355
+
356
+ /**
357
+ * Sem este método, ao clicar enter com a prop useForm ativada a tela era recarregada,
358
+ * e a ação de click do botão não era chamada pois ele não esta dentro do form.
359
+ */
360
+ function onSubmit (event) {
361
+ event.preventDefault()
362
+
363
+ if (hasOk.value) {
364
+ onOk()
365
+ submitHandler()
366
+ }
367
+ }
368
+
369
+ return {
370
+ mainComponent,
371
+ descriptionComponent
372
+ }
196
373
  }
197
374
  </script>
198
375
 
199
376
  <style lang="scss">
200
377
  .qas-dialog {
378
+ $root: &;
379
+
201
380
  .q-dialog__inner > div {
202
381
  box-shadow: $shadow-2;
203
382
  }
204
383
 
384
+ .q-dialog__inner--minimized {
385
+ padding: var(--qas-spacing-md);
386
+ }
387
+
205
388
  &--right {
206
389
  .q-dialog__inner {
207
390
  width: 100%;
@@ -214,5 +397,39 @@ function updateModelValue (value) {
214
397
  width: 100%;
215
398
  }
216
399
  }
400
+
401
+ // tamanhos
402
+ &--sm {
403
+ #{$root}__container {
404
+ max-width: 450px !important;
405
+ }
406
+ }
407
+
408
+ &--md {
409
+ #{$root}__container {
410
+ max-width: 550px !important;
411
+ }
412
+ }
413
+
414
+ &--lg {
415
+ #{$root}__container {
416
+ max-width: 800px !important;
417
+ }
418
+ }
419
+
420
+ &--xl {
421
+ #{$root}__container {
422
+ max-width: 1100px !important;
423
+ }
424
+ }
425
+
426
+ // tamanho mínimo dos botões de ação (primário e secundário)
427
+ &__actions {
428
+ .qas-btn--primary,
429
+ .qas-btn--secondary {
430
+ min-width: 120px;
431
+ width: 100%;
432
+ }
433
+ }
217
434
  }
218
435
  </style>