@bildvitta/quasar-ui-asteroid 3.18.0-beta.1 → 3.18.0-beta.2

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bildvitta/quasar-ui-asteroid",
3
3
  "description": "Asteroid",
4
- "version": "3.18.0-beta.1",
4
+ "version": "3.18.0-beta.2",
5
5
  "author": "Bild & Vitta <systemteam@bild.com.br>",
6
6
  "license": "MIT",
7
7
  "main": "dist/asteroid.cjs.min.js",
@@ -1,5 +1,6 @@
1
1
  <template>
2
- <component :is="component.is" v-bind="component.props" class="q-px-sm qas-badge text-body2">
2
+ <!-- "data-table-ignore-hover" é para não habilitar hover no texto no QasTableGenerator -->
3
+ <component :is="component.is" v-bind="component.props" class="q-px-sm qas-badge text-body2" data-table-ignore-hover>
3
4
  <slot />
4
5
  </component>
5
6
  </template>
@@ -1,5 +1,6 @@
1
1
  <template>
2
- <q-btn ref="button" class="qas-btn" v-bind="attributes">
2
+ <!-- "data-table-ignore-tr-hover" é para desabilitar o hover do tr no QasTableGenerator -->
3
+ <q-btn ref="button" class="qas-btn" data-table-ignore-tr-hover v-bind="attributes">
3
4
  <slot />
4
5
 
5
6
  <template v-for="(_, name) in nonDefaultSlots" #[name]="context">
@@ -1,6 +1,11 @@
1
1
  <template>
2
2
  <span>
3
- <slot v-if="props.useText">{{ props.text }}</slot>
3
+ <!-- "data-table-hover" é para habilitar hover no texto no QasTableGenerator -->
4
+ <span data-table-hover>
5
+ <slot v-if="props.useText">
6
+ {{ props.text }}
7
+ </slot>
8
+ </span>
4
9
 
5
10
  <qas-btn class="q-ml-xs" color="primary" :icon="props.icon" :loading="isLoading" variant="tertiary" @click.stop.prevent="copy">
6
11
  <q-tooltip>Copiar</q-tooltip>
@@ -58,11 +58,16 @@ export default {
58
58
  type: Object
59
59
  },
60
60
 
61
- height: {
61
+ maxHeight: {
62
62
  default: '300px',
63
63
  type: String
64
64
  },
65
65
 
66
+ height: {
67
+ default: '',
68
+ type: String
69
+ },
70
+
66
71
  list: {
67
72
  default: () => [],
68
73
  type: Array
@@ -120,7 +125,11 @@ export default {
120
125
  },
121
126
 
122
127
  containerStyle () {
123
- return { maxHeight: this.containerHeight }
128
+ return {
129
+ // Caso tenha height, deverá ter um tamanho fixo com base no height, portanto não terá max-height.
130
+ maxHeight: this.height ? 'auto' : this.containerHeight,
131
+ ...(this.height && { height: this.height })
132
+ }
124
133
  },
125
134
 
126
135
  hasNoOptionsOnFirstFetch () {
@@ -130,7 +139,7 @@ export default {
130
139
  containerHeight () {
131
140
  const hasEmptyList = (!this.list.length && !this.useLazyLoading) || this.hasNoOptionsOnFirstFetch
132
141
 
133
- return hasEmptyList ? this.emptyListHeight : this.height
142
+ return hasEmptyList ? this.emptyListHeight : this.maxHeight
134
143
  },
135
144
 
136
145
  component () {
@@ -33,7 +33,12 @@ props:
33
33
 
34
34
  height:
35
35
  desc: Define altura do box quando a lista não está vazia.
36
- default: 300px
36
+ default: auto
37
+ type: String
38
+
39
+ maxHeight:
40
+ desc: Define altura máxima do box quando a lista não está vazia.
41
+ default: auto
37
42
  type: String
38
43
 
39
44
  lazy-loading-props:
@@ -1,19 +1,33 @@
1
1
  <template>
2
- <component :is="parentComponent.is">
2
+ <component :is="parentComponent.is" class="qas-table-generator" :class="tableClasses">
3
3
  <slot name="parent-header">
4
4
  <qas-header v-if="hasHeaderProps" v-bind="headerProps" />
5
5
  </slot>
6
6
 
7
- <q-table v-show="hasResults" ref="table" class="bg-white qas-table-generator text-grey-8" v-bind="attributes">
7
+ <q-table v-show="hasResults" ref="table" class="bg-white text-grey-8" v-bind="attributes">
8
8
  <template v-for="(_, name) in slots" #[name]="context">
9
9
  <slot :name="name" v-bind="context" />
10
10
  </template>
11
11
 
12
+ <template #header-cell="context">
13
+ <q-th v-if="context.col.label" :class="[context.col.headerClasses, context.col.__thClass]">
14
+ <qas-btn v-if="context.col.sortable" color="grey-10" icon-right="sym_r_swap_vert" :label="context.col.label" @click="$refs.table.sort(context.col)" />
15
+
16
+ <span v-else>
17
+ {{ context.col.label }}
18
+ </span>
19
+ </q-th>
20
+ </template>
21
+
12
22
  <template v-for="(fieldName, index) in bodyCellNameSlots" :key="index" #[`body-cell-${fieldName}`]="context">
13
- <q-td>
14
- <component :is="tdChildComponent" v-bind="getTdChildComponentProps(context.row)">
23
+ <q-td :class="getTdClasses(context.row)">
24
+ <component :is="tdChildComponent" class="qas-table-generator__td-item" v-bind="getTdChildComponentProps(context.row)">
15
25
  <slot :name="`body-cell-${fieldName}`" v-bind="context || {}">
16
- {{ context.row?.[fieldName] }}
26
+ <pv-table-generator-td v-if="getFieldsProps(context.row, context.rowIndex)[fieldName]" :component-data="getFieldsProps(context.row, context.rowIndex)[fieldName]" :label="fields[fieldName]?.label" :name="fieldName" :row="context.row" />
27
+
28
+ <template v-else>
29
+ {{ context.row?.[fieldName] }}
30
+ </template>
17
31
  </slot>
18
32
  </component>
19
33
  </q-td>
@@ -25,13 +39,24 @@
25
39
  </template>
26
40
 
27
41
  <script>
42
+ import PvTableGeneratorTd from './_components/PvTableGeneratorTd.vue'
43
+
28
44
  import { extend } from 'quasar'
29
- import { isEmpty, humanize, setScrollOnGrab } from '../../helpers'
45
+ import { isEmpty, humanize, setScrollOnGrab, setScrollGradient } from '../../helpers'
30
46
 
31
47
  export default {
32
48
  name: 'QasTableGenerator',
33
49
 
50
+ components: {
51
+ PvTableGeneratorTd
52
+ },
53
+
34
54
  props: {
55
+ actionsMenuProps: {
56
+ default: undefined,
57
+ type: Function
58
+ },
59
+
35
60
  columns: {
36
61
  default: () => [],
37
62
  type: Array
@@ -47,6 +72,11 @@ export default {
47
72
  type: [Array, Object]
48
73
  },
49
74
 
75
+ fieldsProps: {
76
+ default: () => ({}),
77
+ type: [Object, Function]
78
+ },
79
+
50
80
  headerProps: {
51
81
  default: () => ({}),
52
82
  type: Object
@@ -101,7 +131,8 @@ export default {
101
131
  scrollableElement: null,
102
132
  scrollOnGrab: {},
103
133
  elementToObserve: null,
104
- resizeObserver: null
134
+ resizeObserver: null,
135
+ scrollGradientX: setScrollGradient({ orientation: 'x' })
105
136
  }
106
137
  },
107
138
 
@@ -115,8 +146,8 @@ export default {
115
146
  bodyCellNameSlots () {
116
147
  if (this.hasBodyCellSlot) return []
117
148
 
118
- return this.columns.length
119
- ? this.columns.map(column => typeof column === 'object' ? column.name : column)
149
+ return this.normalizedColumns.length
150
+ ? this.normalizedColumns.map(column => typeof column === 'object' ? column.name : column)
120
151
  : Object.keys(this.fields)
121
152
  },
122
153
 
@@ -145,7 +176,6 @@ export default {
145
176
  tableClass: {
146
177
  'overflow-hidden-y': !this.useStickyHeader && !this.useVirtualScroll
147
178
  },
148
- class: this.tableClass,
149
179
  columns: this.columnsByFields,
150
180
  flat: true,
151
181
  hideBottom: true,
@@ -164,25 +194,28 @@ export default {
164
194
 
165
195
  columnsByFields () {
166
196
  if (!this.hasFields) {
167
- return this.columns.filter(column => column instanceof Object)
197
+ return this.normalizedColumns.filter(column => column instanceof Object)
168
198
  }
169
199
 
170
200
  const columns = []
171
201
 
172
202
  function columnByField (field) {
173
- const { align, label, name } = field
203
+ const { label, name, sortable, sort, rawSort } = field
174
204
 
175
205
  columns.push({
176
- align: align || 'left',
206
+ align: 'left',
177
207
  field: name,
178
208
  label,
179
209
  name,
180
- headerClasses: 'text-grey-10'
210
+ headerClasses: 'text-grey-10',
211
+ sortable: sortable ?? true,
212
+ sort,
213
+ rawSort
181
214
  })
182
215
  }
183
216
 
184
217
  // Automatic columns.
185
- if (!this.columns.length) {
218
+ if (!this.normalizedColumns.length) {
186
219
  for (const index in this.fields) {
187
220
  columnByField(this.fields[index])
188
221
  }
@@ -191,9 +224,10 @@ export default {
191
224
  }
192
225
 
193
226
  // Sorting from the column list.
194
- this.columns.forEach(column => {
227
+ this.normalizedColumns.forEach(column => {
195
228
  if (column instanceof Object) {
196
- columnByField(column)
229
+ // repassa as props e mergeia com as do field
230
+ columnByField({ ...column, ...this.fields[column.name] })
197
231
  } else if (this.fields[column]) {
198
232
  columnByField(this.fields[column])
199
233
  }
@@ -202,6 +236,17 @@ export default {
202
236
  return columns
203
237
  },
204
238
 
239
+ hasActionsMenu () {
240
+ return typeof this.actionsMenuProps === 'function'
241
+ },
242
+
243
+ /**
244
+ * caso tenha a prop "actionsMenuProps" é adicionado automaticamente a coluna "actions" como ultimo item
245
+ */
246
+ normalizedColumns () {
247
+ return this.hasActionsMenu ? [...this.columns, { name: 'actions' }] : this.columns
248
+ },
249
+
205
250
  hasFields () {
206
251
  return Object.keys(this.fields).length
207
252
  },
@@ -230,10 +275,11 @@ export default {
230
275
  return this.results.length
231
276
  },
232
277
 
233
- tableClass () {
278
+ tableClasses () {
234
279
  return {
235
280
  'qas-table-generator--mobile': this.$qas.screen.isSmall,
236
- 'qas-table-generator--sticky-header': this.useStickyHeader
281
+ 'qas-table-generator--sticky-header': this.useStickyHeader,
282
+ 'qas-table-generator--has-actions': this.hasActionsMenu
237
283
  }
238
284
  },
239
285
 
@@ -255,10 +301,24 @@ export default {
255
301
 
256
302
  hasHeaderProps () {
257
303
  return !!Object.keys(this.headerProps).length
304
+ },
305
+
306
+ hasAutoScrollY () {
307
+ return this.useStickyHeader || this.useVirtualScroll
308
+ },
309
+
310
+ hasRowClick () {
311
+ return typeof this.$attrs.onRowClick === 'function'
258
312
  }
259
313
  },
260
314
 
261
315
  mounted () {
316
+ if (!this.hasAutoScrollY) {
317
+ const scrollElement = this.getScrollElement()
318
+
319
+ this.scrollGradientX.initializeScrollGradient(scrollElement)
320
+ }
321
+
262
322
  if (!this.useScrollOnGrab) return
263
323
 
264
324
  this.setObserver()
@@ -266,6 +326,12 @@ export default {
266
326
  },
267
327
 
268
328
  onUnmounted () {
329
+ if (!this.hasAutoScrollY) {
330
+ const scrollElement = this.getScrollElement()
331
+
332
+ this.scrollGradientX.removeScrollGradient(scrollElement)
333
+ }
334
+
269
335
  if (!this.hasScrollOnGrab) return
270
336
 
271
337
  this.destroyObserver()
@@ -277,7 +343,7 @@ export default {
277
343
  initializeScrollOnGrab () {
278
344
  if (this.hasScrollOnGrab) return
279
345
 
280
- const element = this.getTableElementComponent().querySelector('.q-table__middle.scroll')
346
+ const element = this.getScrollElement()
281
347
 
282
348
  this.scrollOnGrab = setScrollOnGrab(element)
283
349
  },
@@ -286,6 +352,10 @@ export default {
286
352
  return this.$refs?.table?.$el
287
353
  },
288
354
 
355
+ getScrollElement () {
356
+ return this.getTableElementComponent().querySelector('.q-table__middle.scroll')
357
+ },
358
+
289
359
  getTableElement () {
290
360
  return this.getTableElementComponent()?.querySelector('table')
291
361
  },
@@ -327,11 +397,29 @@ export default {
327
397
  this.resizeObserver.unobserve(this.elementToObserve)
328
398
  },
329
399
 
400
+ getTdClasses (row) {
401
+ const routePayload = this.rowRouteFn?.(row)
402
+ const isRoutePayloadObject = typeof routePayload === 'object'
403
+ const hasRoutePayload = isRoutePayloadObject ? !!Object.keys(routePayload).length : !!routePayload
404
+
405
+ return {
406
+ 'qas-table-generator__td--has-action': this.hasRowClick || hasRoutePayload
407
+ }
408
+ },
409
+
330
410
  getTdChildComponentProps (row) {
331
411
  if (!this.rowRouteFn) return
332
412
 
333
413
  return {
334
- class: 'text-no-decoration text-grey-8 flex full-width items-center full-height',
414
+ class: [
415
+ 'text-no-decoration',
416
+ 'text-grey-8',
417
+ 'flex',
418
+ 'full-width',
419
+ 'items-center',
420
+ 'full-height'
421
+ ],
422
+
335
423
  [this.useExternalLink ? 'href' : 'to']: this.rowRouteFn(row),
336
424
  ...(this.useExternalLink && { target: '_blank' })
337
425
  }
@@ -339,6 +427,25 @@ export default {
339
427
 
340
428
  onRowClick () {
341
429
  this.$attrs.onRowClick(...arguments)
430
+ },
431
+
432
+ getFieldsProps (row, index) {
433
+ const isFieldsPropsFunction = typeof this.fieldsProps === 'function'
434
+
435
+ return {
436
+ ...(isFieldsPropsFunction ? this.fieldsProps(row, index) : this.fieldsProps),
437
+
438
+ /**
439
+ * caso tenha a prop "actionsMenuProps" é adicionado automaticamente a prop "actionsMenuProps"
440
+ * dentro de "fieldsProps".
441
+ */
442
+ ...(this.hasActionsMenu && {
443
+ actions: {
444
+ component: 'QasActionsMenu',
445
+ props: this.actionsMenuProps?.(row, index)
446
+ }
447
+ })
448
+ }
342
449
  }
343
450
  }
344
451
  }
@@ -346,6 +453,8 @@ export default {
346
453
 
347
454
  <style lang="scss">
348
455
  .qas-table-generator {
456
+ $root: &;
457
+
349
458
  .q-table {
350
459
  thead tr {
351
460
  height: 24px;
@@ -354,8 +463,29 @@ export default {
354
463
  th {
355
464
  @include set-typography($subtitle1);
356
465
 
466
+ // altera o tamanho do ícone força o botão não quebrar.
467
+ .qas-btn {
468
+ .q-icon {
469
+ font-size: 18px !important;
470
+ }
471
+
472
+ .q-btn__content {
473
+ flex-wrap: nowrap;
474
+ }
475
+ }
476
+
357
477
  border: 0 !important;
358
- padding: 0 calc(var(--qas-spacing-lg) / 2);
478
+ padding-bottom: 0;
479
+ padding-left: 0;
480
+ padding-top: 0;
481
+
482
+ &:not(:last-child) {
483
+ padding-right: var(--qas-spacing-md);
484
+ }
485
+
486
+ &:last-child {
487
+ padding-right: 0;
488
+ }
359
489
  }
360
490
 
361
491
  td,
@@ -369,28 +499,84 @@ export default {
369
499
  @include set-typography($body1);
370
500
 
371
501
  height: 40px;
372
- padding-left: calc(var(--qas-spacing-lg) / 2);
373
- padding-right: calc(var(--qas-spacing-lg) / 2);
502
+ padding-bottom: var(--qas-spacing-sm);
503
+ padding-left: 0;
504
+ padding-top: var(--qas-spacing-sm);
374
505
 
375
- &:before {
376
- transition: background-color var(--qas-generic-transition);
506
+ &:not(:last-child) {
507
+ padding-right: var(--qas-spacing-md);
508
+ }
509
+
510
+ &:last-child {
511
+ padding-right: 0;
512
+ }
513
+
514
+ &::before {
515
+ display: none;
377
516
  }
378
517
  }
379
518
 
519
+ &__middle {
520
+ padding-left: var(--qas-spacing-md);
521
+ padding-right: var(--qas-spacing-md);
522
+ }
523
+
380
524
  tr {
381
- &:hover {
382
- td:before {
383
- background-color: var(--qas-background-color);
384
- }
525
+ position: relative;
526
+
527
+ &::before {
528
+ background-color: transparent;
529
+ bottom: 0;
530
+ content: '';
531
+ left: calc(var(--qas-spacing-md) * -1);
532
+ pointer-events: none;
533
+ position: absolute;
534
+ right: calc(var(--qas-spacing-md) * -1);
535
+ top: 0;
536
+ transition: background-color var(--qas-generic-transition);
537
+ }
538
+ }
539
+
540
+ tbody tr {
541
+ &::before {
542
+ display: block;
385
543
  }
386
544
 
387
- &:last-child td {
388
- padding-bottom: 0;
545
+ &:hover::before {
546
+ background-color: var(--qas-background-color);
547
+ }
548
+
549
+ /*
550
+ A regra só é aplicada se nenhum elemento filho com o atributo "data-table-ignore-tr-hover"
551
+ estiver também em estado de hover, impedindo que estilos conflitantes sejam aplicados.
552
+ Especificamente, dentro da célula:
553
+ - Elementos que não possuem filhos com "data-table-ignore-tr-hover" ou "data-table-ignore-hover"
554
+ receberão a cor definida pela variável CSS "--q-primary-contrast".
555
+ - Elementos dentro de células marcadas como tendo ações ("qas-table-generator__td--has-action")
556
+ e também com o atributo "data-table-hover" serão estilizados da mesma maneira.
557
+ */
558
+ &:hover:not(:has(td *[data-table-ignore-tr-hover]:hover)) {
559
+ td:not(:has(*[data-table-ignore-tr-hover])):not(:has(*[data-table-ignore-hover])).qas-table-generator__td--has-action *,
560
+ td.qas-table-generator__td--has-action *[data-table-hover] {
561
+ color: var(--q-primary-contrast) !important;
562
+ }
389
563
  }
390
564
  }
391
565
 
392
566
  thead tr:hover {
393
- background-color: white;
567
+ background-color: white !important;
568
+ }
569
+ }
570
+
571
+ .q-table__container {
572
+ margin-left: calc(var(--qas-spacing-md) * -1);
573
+ margin-right: calc(var(--qas-spacing-md) * -1);
574
+ }
575
+
576
+ &--has-actions {
577
+ td:last-child #{$root}__td-item {
578
+ display: flex;
579
+ justify-content: flex-end;
394
580
  }
395
581
  }
396
582
 
@@ -4,6 +4,18 @@ meta:
4
4
  desc: Componente para criação de tabela dinâmica usando o `QTable` do quasar.
5
5
 
6
6
  props:
7
+ actions-menu-props:
8
+ desc: Propriedades repassadas para o "QasActionsMenu" que adiciona uma coluna "actions" de forma automática.
9
+ default: undefined
10
+ type: Function
11
+ params:
12
+ row:
13
+ desc: Payload da linha da tabela.
14
+ type: Object
15
+ index:
16
+ desc: Índice da linha da tabela.
17
+ type: Number
18
+
7
19
  columns:
8
20
  desc: Colunas que vão ter na tabela.
9
21
  default: []
@@ -20,6 +32,19 @@ props:
20
32
  type: Object
21
33
  examples: ["{ email: { name: 'email', type: 'email', label: 'E-mail' } }"]
22
34
 
35
+ fields-props:
36
+ desc: Propriedade para controlar o uso de componentes dentro das row sem necessidade de abrir slot.
37
+ default: {}
38
+ type: [Object, Function]
39
+ examples: ["{ email: { component: 'QasCopy' } }"]
40
+ params:
41
+ row:
42
+ desc: Payload da linha da tabela.
43
+ type: Object
44
+ index:
45
+ desc: Índice da linha da tabela.
46
+ type: Number
47
+
23
48
  header-props:
24
49
  desc: Propriedades repassadas para o componente `QasHeader`.
25
50
  default: {}
@@ -0,0 +1,94 @@
1
+ <template>
2
+ <component :is="component.is" v-bind="component.props" />
3
+ </template>
4
+
5
+ <script setup>
6
+ import { computed, defineAsyncComponent } from 'vue'
7
+
8
+ defineOptions({ name: 'PvTableGeneratorProps' })
9
+
10
+ const props = defineProps({
11
+ componentData: {
12
+ type: Object,
13
+ default: () => ({})
14
+ },
15
+
16
+ label: {
17
+ type: String,
18
+ default: ''
19
+ },
20
+
21
+ row: {
22
+ type: Object,
23
+ default: () => ({})
24
+ },
25
+
26
+ name: {
27
+ type: String,
28
+ default: ''
29
+ }
30
+ })
31
+
32
+ const component = computed(() => {
33
+ const defaultValue = props.row?.[props.name]
34
+
35
+ const componentPaths = {
36
+ QasActionsMenu: {
37
+ component: () => import('../../actions-menu/QasActionsMenu.vue'),
38
+ props: {}
39
+ },
40
+
41
+ QasBadge: {
42
+ component: () => import('../../badge/QasBadge.vue'),
43
+ props: {
44
+ label: defaultValue
45
+ }
46
+ },
47
+
48
+ QasBtn: {
49
+ component: () => import('../../btn/QasBtn.vue'),
50
+ props: {
51
+ label: defaultValue
52
+ }
53
+ },
54
+
55
+ QasCopy: {
56
+ component: () => import('../../copy/QasCopy.vue'),
57
+ props: {
58
+ text: defaultValue
59
+ }
60
+ },
61
+
62
+ QasStatus: {
63
+ component: () => import('../../status/QasStatus.vue'),
64
+ props: {}
65
+ },
66
+
67
+ QasTextTruncate: {
68
+ component: () => import('../../text-truncate/QasTextTruncate.vue'),
69
+ props: {
70
+ dialogTitle: props.label,
71
+ maxWidth: 260,
72
+
73
+ // caso personalize o componente passando "list", não pode enviar "text" senão vai ter erro de tipo
74
+ text: props.componentData.props?.list?.length ? '' : defaultValue
75
+ }
76
+ },
77
+
78
+ QasToggleVisibility: {
79
+ component: () => import('../../toggle-visibility/QasToggleVisibility.vue'),
80
+ props: {
81
+ text: defaultValue
82
+ }
83
+ }
84
+ }
85
+
86
+ return {
87
+ is: defineAsyncComponent(componentPaths[props.componentData.component].component),
88
+ props: {
89
+ ...componentPaths[props.componentData.component].props,
90
+ ...props.componentData.props
91
+ }
92
+ }
93
+ })
94
+ </script>
@@ -1,7 +1,8 @@
1
1
  <template>
2
2
  <div ref="parent" :class="classes">
3
3
  <div class="no-wrap row text-no-wrap">
4
- <div ref="truncate" class="ellipsis">
4
+ <!-- "data-table-hover" habilita o hover no texto dentro do QasTableGenerator -->
5
+ <div ref="truncate" class="ellipsis" data-table-hover>
5
6
  <slot>
6
7
  <div v-if="hasBadges" class="items-center q-col-gutter-sm row" :class="badgeParentClasses">
7
8
  <div v-for="(item, index) in normalizedBadgesList" :key="index">
@@ -15,20 +16,22 @@
15
16
  </slot>
16
17
  </div>
17
18
 
18
- <qas-btn v-if="hasButton" class="q-ml-sm" :label="buttonLabel" @click.stop.prevent="toggle" />
19
+ <qas-btn v-if="hasButton" class="q-ml-xs" :label="buttonLabel" @click.stop.prevent="toggle" />
19
20
  </div>
20
21
 
21
- <qas-dialog v-model="show" v-bind="defaultProps" aria-label="Diálogo de texto completo" role="dialog">
22
+ <qas-dialog v-model="show" v-bind="defaultProps" aria-label="Diálogo de texto completo" max-width="500px" role="dialog" use-full-max-width>
22
23
  <template v-if="isCounterMode" #description>
23
- <div class="q-col-gutter-y-sm row">
24
- <div
25
- v-for="(item, index) in normalizedList"
26
- :key="index"
27
- class="col-12"
28
- >
29
- {{ item }}
30
- </div>
31
- </div>
24
+ <component :is="dialogComponent.is" v-bind="dialogComponent.props" v-model:results="searchModel">
25
+ <q-list separator>
26
+ <q-item v-for="(item, index) in dialogComponent.list" :key="index" class="q-px-none">
27
+ <q-item-section>
28
+ <div class="text-body1">
29
+ {{ item }}
30
+ </div>
31
+ </q-item-section>
32
+ </q-item>
33
+ </q-list>
34
+ </component>
32
35
  </template>
33
36
  </qas-dialog>
34
37
  </div>
@@ -135,7 +138,9 @@ const {
135
138
 
136
139
  const {
137
140
  defaultProps,
141
+ dialogComponent,
138
142
  show,
143
+ searchModel,
139
144
  toggle
140
145
  } = useDialog({ props, textContent })
141
146
 
@@ -158,6 +163,7 @@ const formattedText = computed(() => props.list.length || props.text ? displayTe
158
163
  function useDialog ({ props, textContent }) {
159
164
  // reactive vars
160
165
  const show = ref(false)
166
+ const searchModel = ref([])
161
167
 
162
168
  // computed
163
169
  const description = computed(() => props.text || textContent.value)
@@ -176,6 +182,31 @@ function useDialog ({ props, textContent }) {
176
182
  }
177
183
  })
178
184
 
185
+ const normalizedSearchModel = computed(() => {
186
+ return props.useObjectList ? searchModel.value.map(({ label }) => label) : searchModel.value
187
+ })
188
+
189
+ const dialogComponent = computed(() => {
190
+ const hasSearchBox = normalizedList.value.length > 12
191
+
192
+ if (hasSearchBox) {
193
+ return {
194
+ is: 'qas-search-box',
195
+ list: normalizedSearchModel.value,
196
+ props: {
197
+ height: '510px',
198
+ list: props.list,
199
+ ...(props.useObjectList && { fuseOptions: { keys: ['label'] } })
200
+ }
201
+ }
202
+ }
203
+
204
+ return {
205
+ is: 'div',
206
+ list: normalizedList.value
207
+ }
208
+ })
209
+
179
210
  // functions
180
211
  function toggle () {
181
212
  show.value = !show.value
@@ -183,8 +214,10 @@ function useDialog ({ props, textContent }) {
183
214
 
184
215
  return {
185
216
  defaultProps,
217
+ dialogComponent,
186
218
 
187
219
  show,
220
+ searchModel,
188
221
 
189
222
  toggle
190
223
  }
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <div class="qas-toggle-visibility">
3
- <div :aria-expanded="isVisible" aria-label="Alternar visibilidade do conteúdo" class="cursor-pointer items-center no-wrap qas-toggle-visibility__container row" role="button" :style @click.prevent.stop="toggleVisibility">
3
+ <!-- "data-table-ignore-tr-hover" é para desabilitar o hover do tr no QasTableGenerator -->
4
+ <div :aria-expanded="isVisible" aria-label="Alternar visibilidade do conteúdo" class="cursor-pointer items-center no-wrap qas-toggle-visibility__container row" data-table-ignore-tr-hover role="button" :style @click.prevent.stop="toggleVisibility">
4
5
  <div class="ellipsis qas-toggle-visibility__content">
5
6
  <div
6
7
  v-if="isVisible"