@bildvitta/quasar-ui-asteroid 3.17.0-beta.5 → 3.17.0-beta.7
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 +1 -1
- package/src/components/btn-dropdown/QasBtnDropdown.vue +14 -1
- package/src/components/chart-view/QasChartView.vue +1 -1
- package/src/components/date-time-input/QasDateTimeInput.vue +1 -1
- package/src/components/expansion-item/QasExpansionItem.vue +18 -1
- package/src/components/form-generator/QasFormGenerator.vue +15 -13
- package/src/components/form-generator/QasFormGenerator.yml +3 -0
- package/src/components/grid-generator/QasGridGenerator.vue +2 -2
- package/src/components/header/QasHeader.vue +41 -7
- package/src/components/header/QasHeader.yml +5 -0
- package/src/components/list-items/QasListItems.vue +28 -4
- package/src/components/list-items/QasListItems.yml +10 -0
- package/src/components/list-view/QasListView.vue +4 -4
- package/src/components/table-generator/QasTableGenerator.vue +7 -1
- package/src/components/text-truncate/QasTextTruncate.vue +3 -3
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
<div v-if="props.useSplit">
|
|
22
|
-
<qas-btn
|
|
22
|
+
<qas-btn v-bind="splittedButtonProps">
|
|
23
23
|
<q-menu v-if="hasDefaultSlot" anchor="bottom right" auto-close self="top right">
|
|
24
24
|
<div :class="classes.menuContent">
|
|
25
25
|
<slot />
|
|
@@ -103,6 +103,19 @@ const hasButtons = computed(() => !screen.isSmall || !props.useSplit)
|
|
|
103
103
|
const hasDefaultSlot = computed(() => !!slots.default)
|
|
104
104
|
const hasMenuOnLeftSide = computed(() => hasDefaultSlot.value && !props.useSplit && isSingleButton.value)
|
|
105
105
|
|
|
106
|
+
const splittedButtonProps = computed(() => {
|
|
107
|
+
const iconKey = screen.isSmall ? 'icon' : 'iconRight'
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
color: 'grey-10',
|
|
111
|
+
disable: props.disable,
|
|
112
|
+
[iconKey]: props.dropdownIcon,
|
|
113
|
+
variant: 'tertiary',
|
|
114
|
+
label: 'Opções',
|
|
115
|
+
useLabelOnSmallScreen: false
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
106
119
|
watch(() => props.menu, value => {
|
|
107
120
|
isMenuOpened.value = value
|
|
108
121
|
}, { immediate: true })
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<qas-input ref="input" v-bind="attributes" v-model="currentValue" inputmode="numeric" :unmasked-value="false" @blur="validateDateTimeOnBlur" @focus="resetError" @update:model-value="updateModelValue">
|
|
3
3
|
<template #append>
|
|
4
|
-
<qas-btn v-if="!props.useTimeOnly" color="grey-10" :disable="attrs.readonly" icon="
|
|
4
|
+
<qas-btn v-if="!props.useTimeOnly" color="grey-10" :disable="attrs.readonly" icon="sym_r_calendar_today" variant="tertiary">
|
|
5
5
|
<q-popup-proxy ref="dateProxy" transition-hide="scale" transition-show="scale" v-bind="props.datePopupProxyProps">
|
|
6
6
|
<qas-date v-model="currentValue" v-bind="defaultDateProps" :mask="maskDate" width="290px" @update:model-value="updateModelValue" />
|
|
7
7
|
</q-popup-proxy>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="expansionItem" class="full-width qas-expansion-item" :class="errorClasses" v-bind="expansionProps.parent">
|
|
3
|
-
<component :is="component.is" class="qas-expansion-item__box">
|
|
3
|
+
<component :is="component.is" class="qas-expansion-item__box" v-bind="boxProps">
|
|
4
4
|
<q-expansion-item header-class="text-bold q-mt-sm q-pa-none qas-expansion-item__header" :label="props.label" v-bind="expansionProps.item">
|
|
5
5
|
<template #header>
|
|
6
6
|
<slot name="header">
|
|
@@ -100,6 +100,8 @@ onMounted(setHasNextSibling)
|
|
|
100
100
|
|
|
101
101
|
// constants
|
|
102
102
|
const isNestedExpansionItem = inject('isExpansionItem', false)
|
|
103
|
+
const isNestedBox = inject('isBox', false)
|
|
104
|
+
|
|
103
105
|
const component = {
|
|
104
106
|
is: isNestedExpansionItem ? 'div' : QasBox
|
|
105
107
|
}
|
|
@@ -157,6 +159,21 @@ const expansionProps = computed(() => {
|
|
|
157
159
|
}
|
|
158
160
|
})
|
|
159
161
|
|
|
162
|
+
const boxProps = computed(() => {
|
|
163
|
+
/**
|
|
164
|
+
* Caso o QasExpansionItem estiver dentro de um QasBox e não for um QasExpansionItem
|
|
165
|
+
* dentro de outro QasExpansionItem, o componente terá uma borda.
|
|
166
|
+
*/
|
|
167
|
+
const isBoxed = isNestedBox && !isNestedExpansionItem
|
|
168
|
+
|
|
169
|
+
if (!isBoxed) return {}
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
unelevated: isBoxed,
|
|
173
|
+
outlined: isBoxed
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
|
|
160
177
|
// functions
|
|
161
178
|
|
|
162
179
|
/**
|
|
@@ -2,22 +2,26 @@
|
|
|
2
2
|
<div :class="fieldsetClasses">
|
|
3
3
|
<div v-for="(fieldsetItem, fieldsetItemKey) in normalizedFields" :key="fieldsetItemKey" :class="getFieldSetColumnClass(fieldsetItem.column)">
|
|
4
4
|
<component :is="containerComponent.is" v-bind="containerComponent.props">
|
|
5
|
-
<slot v-if="
|
|
5
|
+
<slot v-if="fieldsetItem.__isFieldset" :name="`legend-${fieldsetItemKey}`">
|
|
6
6
|
<qas-header v-bind="getHeaderProps(fieldsetItem)" />
|
|
7
7
|
</slot>
|
|
8
8
|
|
|
9
9
|
<div>
|
|
10
10
|
<slot :fields="fieldsetItem.fields?.visible" :name="`legend-section-${fieldsetItemKey}`">
|
|
11
|
-
<div class="
|
|
12
|
-
<div
|
|
13
|
-
<div
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
|
|
11
|
+
<div class="q-col-gutter-md row">
|
|
12
|
+
<div class="col">
|
|
13
|
+
<div :class="fieldContainerClasses">
|
|
14
|
+
<div v-for="(field, key) in fieldsetItem.fields.visible" :key="key" :class="getFieldClass({ index: key, fields: normalizedFields })">
|
|
15
|
+
<slot :field="field" :name="`field-${field.name}`">
|
|
16
|
+
<qas-field :disable="isFieldDisabled(field)" v-bind="props.fieldsProps[field.name]" :error="props.errors[key]" :field="field" :model-value="props.modelValue[field.name]" @update:model-value="updateModelValue({ key: field.name, value: $event })" />
|
|
17
|
+
</slot>
|
|
18
|
+
</div>
|
|
17
19
|
</div>
|
|
18
20
|
</div>
|
|
19
21
|
|
|
20
|
-
<
|
|
22
|
+
<div v-if="hasButtonProps(fieldsetItem)" class="col-12 col-sm-auto items-end justify-end row">
|
|
23
|
+
<qas-btn v-bind="fieldsetItem.buttonProps" />
|
|
24
|
+
</div>
|
|
21
25
|
</div>
|
|
22
26
|
|
|
23
27
|
<div v-for="(field, key) in fieldsetItem.fields.hidden" :key="key">
|
|
@@ -27,6 +31,8 @@
|
|
|
27
31
|
</div>
|
|
28
32
|
</slot>
|
|
29
33
|
</div>
|
|
34
|
+
|
|
35
|
+
<slot v-if="fieldsetItem.__isFieldset" :name="`legend-bottom-${fieldsetItemKey}`" />
|
|
30
36
|
</component>
|
|
31
37
|
</div>
|
|
32
38
|
</div>
|
|
@@ -200,7 +206,7 @@ const fieldContainerClasses = computed(() => {
|
|
|
200
206
|
]
|
|
201
207
|
})
|
|
202
208
|
|
|
203
|
-
//
|
|
209
|
+
// functions
|
|
204
210
|
function getFieldType ({ type }) {
|
|
205
211
|
return type === 'hidden' ? 'hidden' : 'visible'
|
|
206
212
|
}
|
|
@@ -233,10 +239,6 @@ function hasButtonProps ({ buttonProps = {} }) {
|
|
|
233
239
|
return !!Object.keys(buttonProps).length
|
|
234
240
|
}
|
|
235
241
|
|
|
236
|
-
function getRowContainerClasses (item) {
|
|
237
|
-
return { row: hasButtonProps(item) }
|
|
238
|
-
}
|
|
239
|
-
|
|
240
242
|
// composables
|
|
241
243
|
function useFieldset ({ props }) {
|
|
242
244
|
const fieldsetClasses = computed(() => {
|
|
@@ -97,6 +97,9 @@ slots:
|
|
|
97
97
|
default: {}
|
|
98
98
|
type: Object
|
|
99
99
|
|
|
100
|
+
'legend-bottom-[nome-da-chave]':
|
|
101
|
+
desc: Acessa o slot da seção abaixo do conteúdo do form de um fieldset específico.
|
|
102
|
+
|
|
100
103
|
events:
|
|
101
104
|
'@update:model-value -> function(value)':
|
|
102
105
|
desc: Dispara quando o model-value altera, também usado para v-model.
|
|
@@ -153,7 +153,7 @@ const formattedFields = computed(() => {
|
|
|
153
153
|
// watch
|
|
154
154
|
watch(() => formattedFields.value, setFieldsByResult, { immediate: true })
|
|
155
155
|
|
|
156
|
-
//
|
|
156
|
+
// functions
|
|
157
157
|
function getFieldsByResult () {
|
|
158
158
|
if (!hasResult.value || !hasFields.value) return {}
|
|
159
159
|
|
|
@@ -203,7 +203,7 @@ function getContentClasses (field) {
|
|
|
203
203
|
props.contentClass,
|
|
204
204
|
|
|
205
205
|
{
|
|
206
|
-
ellipsis: !screen.isSmall &&
|
|
206
|
+
ellipsis: !screen.isSmall && hasEllipsis(field)
|
|
207
207
|
}
|
|
208
208
|
]
|
|
209
209
|
}
|
|
@@ -15,9 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
<slot name="actions">
|
|
17
17
|
<div class="q-mt-xs text-right">
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
<qas-btn v-if="hasDefaultButton" :use-label-on-small-screen="false" v-bind="props.buttonProps" />
|
|
18
|
+
<component :is="actionsComponent.is" v-if="hasActionsSection" v-bind="actionsComponent.props" />
|
|
21
19
|
</div>
|
|
22
20
|
</slot>
|
|
23
21
|
</div>
|
|
@@ -31,9 +29,7 @@
|
|
|
31
29
|
|
|
32
30
|
<div v-if="!hasLabelSection" class="justify-end row">
|
|
33
31
|
<slot name="actions">
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
<qas-btn v-if="hasDefaultButton" :use-label-on-small-screen="false" v-bind="props.buttonProps" />
|
|
32
|
+
<component :is="actionsComponent.is" v-if="hasActionsSection" v-bind="actionsComponent.props" />
|
|
37
33
|
</slot>
|
|
38
34
|
</div>
|
|
39
35
|
</div>
|
|
@@ -69,6 +65,11 @@ const props = defineProps({
|
|
|
69
65
|
default: ''
|
|
70
66
|
},
|
|
71
67
|
|
|
68
|
+
filtersProps: {
|
|
69
|
+
default: () => ({}),
|
|
70
|
+
type: Object
|
|
71
|
+
},
|
|
72
|
+
|
|
72
73
|
labelProps: {
|
|
73
74
|
type: Object,
|
|
74
75
|
default: () => ({})
|
|
@@ -106,10 +107,43 @@ const defaultLabelProps = computed(() => {
|
|
|
106
107
|
}
|
|
107
108
|
})
|
|
108
109
|
|
|
109
|
-
const
|
|
110
|
+
const actionsComponent = computed(() => {
|
|
111
|
+
const component = {
|
|
112
|
+
[hasDefaultButton.value]: {
|
|
113
|
+
is: 'qas-btn',
|
|
114
|
+
props: {
|
|
115
|
+
...props.buttonProps,
|
|
116
|
+
useLabelOnSmallScreen: false
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
[hasDefaultActionsMenu.value]: {
|
|
121
|
+
is: 'qas-actions-menu',
|
|
122
|
+
props: props.actionsMenuProps
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
[hasDefaultFilters.value]: {
|
|
126
|
+
is: 'qas-filters',
|
|
127
|
+
props: {
|
|
128
|
+
useSearch: false,
|
|
129
|
+
useChip: false,
|
|
130
|
+
useSpacing: false,
|
|
131
|
+
...props.filtersProps
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return component.true
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
const hasActionsSection = computed(() => {
|
|
140
|
+
return !!slots.actions || hasDefaultButton.value || hasDefaultActionsMenu.value || hasDefaultFilters.value
|
|
141
|
+
})
|
|
142
|
+
|
|
110
143
|
const hasBadges = computed(() => !!props.badges.length)
|
|
111
144
|
const hasLabel = computed(() => !!Object.keys(props.labelProps).length)
|
|
112
145
|
const hasDefaultButton = computed(() => !!Object.keys(props.buttonProps).length)
|
|
146
|
+
const hasDefaultFilters = computed(() => !!Object.keys(props.filtersProps).length)
|
|
113
147
|
const hasDefaultActionsMenu = computed(() => !!Object.keys(props.actionsMenuProps).length)
|
|
114
148
|
const hasDescriptionSection = computed(() => props.description || slots.description)
|
|
115
149
|
const hasLabelSection = computed(() => hasLabel.value || slots.label || hasBadges.value)
|
|
@@ -4,7 +4,18 @@
|
|
|
4
4
|
<q-item v-for="(item, index) in props.list" :key="index" :clickable="props.useClickableItem" @click="onClick({ item, index }, true)">
|
|
5
5
|
<slot :index="index" :item="item" name="item">
|
|
6
6
|
<q-item-section>
|
|
7
|
-
<slot :index="index" :item="item" name="item-section"
|
|
7
|
+
<slot :index="index" :item="item" name="item-section">
|
|
8
|
+
<qas-label
|
|
9
|
+
v-if="item[props.labelKey]"
|
|
10
|
+
:label="item[props.labelKey]"
|
|
11
|
+
:margin="getLabelMargin(item)"
|
|
12
|
+
typography="h5"
|
|
13
|
+
/>
|
|
14
|
+
|
|
15
|
+
<div v-if="item[props.descriptionKey]" class="text-body1">
|
|
16
|
+
{{ item[props.descriptionKey] }}
|
|
17
|
+
</div>
|
|
18
|
+
</slot>
|
|
8
19
|
</q-item-section>
|
|
9
20
|
|
|
10
21
|
<q-item-section v-if="props.useSectionActions" side>
|
|
@@ -26,11 +37,21 @@ import { computed } from 'vue'
|
|
|
26
37
|
defineOptions({ name: 'QasListItems' })
|
|
27
38
|
|
|
28
39
|
const props = defineProps({
|
|
40
|
+
descriptionKey: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: 'description'
|
|
43
|
+
},
|
|
44
|
+
|
|
29
45
|
icon: {
|
|
30
46
|
type: String,
|
|
31
47
|
default: 'sym_r_chevron_right'
|
|
32
48
|
},
|
|
33
49
|
|
|
50
|
+
labelKey: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: 'label'
|
|
53
|
+
},
|
|
54
|
+
|
|
34
55
|
list: {
|
|
35
56
|
default: () => [],
|
|
36
57
|
type: Array
|
|
@@ -57,17 +78,20 @@ const classes = computed(() => ({ 'qas-list-items--no-click': !props.useClickabl
|
|
|
57
78
|
|
|
58
79
|
const component = computed(() => props.useBox ? 'qas-box' : 'div')
|
|
59
80
|
|
|
81
|
+
// functions
|
|
60
82
|
function onClick ({ item, index }, fromItem) {
|
|
61
83
|
/**
|
|
62
84
|
* se o click veio do q-item e "useClickableItem" for "false", ou
|
|
63
85
|
* se o click não veio do q-item e "useClickableItem" for "true", então retorna sem emitir.
|
|
64
86
|
*/
|
|
65
|
-
if (
|
|
66
|
-
(fromItem && !props.useClickableItem) || (!fromItem && props.useClickableItem)
|
|
67
|
-
) return
|
|
87
|
+
if ((fromItem && !props.useClickableItem) || (!fromItem && props.useClickableItem)) return
|
|
68
88
|
|
|
69
89
|
emit('click-item', { item, index })
|
|
70
90
|
}
|
|
91
|
+
|
|
92
|
+
function getLabelMargin (item) {
|
|
93
|
+
return item[props.descriptionKey] ? 'xs' : 'none'
|
|
94
|
+
}
|
|
71
95
|
</script>
|
|
72
96
|
|
|
73
97
|
<style lang="scss">
|
|
@@ -4,11 +4,21 @@ meta:
|
|
|
4
4
|
desc: Componente para listagem.
|
|
5
5
|
|
|
6
6
|
props:
|
|
7
|
+
description-key:
|
|
8
|
+
desc: Chave para acessar a descrição do item.
|
|
9
|
+
default: description
|
|
10
|
+
type: String
|
|
11
|
+
|
|
7
12
|
icon:
|
|
8
13
|
desc: Nome do ícone
|
|
9
14
|
default: sym_r_chevron_right
|
|
10
15
|
type: String
|
|
11
16
|
|
|
17
|
+
label-key:
|
|
18
|
+
desc: Chave para acessar o label do item.
|
|
19
|
+
default: label
|
|
20
|
+
type: String
|
|
21
|
+
|
|
12
22
|
list:
|
|
13
23
|
desc: Lista para ser selecionada.
|
|
14
24
|
default: []
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
<main class="relative-position">
|
|
13
13
|
<div v-if="showResults">
|
|
14
14
|
<slot />
|
|
15
|
+
|
|
16
|
+
<q-inner-loading :showing="mx_isFetching">
|
|
17
|
+
<q-spinner color="grey" size="3em" />
|
|
18
|
+
</q-inner-loading>
|
|
15
19
|
</div>
|
|
16
20
|
|
|
17
21
|
<div v-else-if="!mx_isFetching">
|
|
@@ -29,10 +33,6 @@
|
|
|
29
33
|
<div v-if="hasPages" class="flex items-center q-mt-md" :class="paginationClasses">
|
|
30
34
|
<qas-pagination v-model="page" :max="totalPages" @click="changePage" />
|
|
31
35
|
</div>
|
|
32
|
-
|
|
33
|
-
<q-inner-loading :showing="hasResults && mx_isFetching">
|
|
34
|
-
<q-spinner color="grey" size="3em" />
|
|
35
|
-
</q-inner-loading>
|
|
36
36
|
</main>
|
|
37
37
|
</q-pull-to-refresh>
|
|
38
38
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<qas-header v-if="hasHeaderProps" v-bind="headerProps" />
|
|
5
5
|
</slot>
|
|
6
6
|
|
|
7
|
-
<q-table 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 qas-table-generator 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>
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
</q-td>
|
|
20
20
|
</template>
|
|
21
21
|
</q-table>
|
|
22
|
+
|
|
23
|
+
<qas-empty-result-text v-if="!hasResults" />
|
|
22
24
|
</component>
|
|
23
25
|
</template>
|
|
24
26
|
|
|
@@ -130,6 +132,10 @@ export default {
|
|
|
130
132
|
return !!this.$slots['body-cell']
|
|
131
133
|
},
|
|
132
134
|
|
|
135
|
+
hasResults () {
|
|
136
|
+
return !!this.resultsByFields.length
|
|
137
|
+
},
|
|
138
|
+
|
|
133
139
|
attributes () {
|
|
134
140
|
const attributes = {
|
|
135
141
|
class: this.tableClass,
|
|
@@ -148,7 +148,7 @@ function useDialog ({ props, textContent }) {
|
|
|
148
148
|
}
|
|
149
149
|
})
|
|
150
150
|
|
|
151
|
-
//
|
|
151
|
+
// functions
|
|
152
152
|
function toggle () {
|
|
153
153
|
show.value = !show.value
|
|
154
154
|
}
|
|
@@ -170,7 +170,7 @@ function useMutationObserver ({ truncate, callbackFn = () => {} }) {
|
|
|
170
170
|
onMounted(() => observeContentChange())
|
|
171
171
|
onUnmounted(() => observer.value.disconnect())
|
|
172
172
|
|
|
173
|
-
//
|
|
173
|
+
// functions
|
|
174
174
|
function observeContentChange () {
|
|
175
175
|
const config = { childList: true, subtree: true, characterData: true }
|
|
176
176
|
|
|
@@ -197,7 +197,7 @@ function useTruncate ({ parent, props }) {
|
|
|
197
197
|
// computed
|
|
198
198
|
const isTruncated = computed(() => textWidth.value > maxPossibleWidth.value)
|
|
199
199
|
|
|
200
|
-
//
|
|
200
|
+
// functions
|
|
201
201
|
function truncateText () {
|
|
202
202
|
parent.value.style.maxWidth = '100%'
|
|
203
203
|
textWidth.value = truncate.value.clientWidth
|