@bildvitta/quasar-ui-asteroid 3.15.0-beta.9 → 3.16.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bildvitta/quasar-ui-asteroid",
3
3
  "description": "Asteroid",
4
- "version": "3.15.0-beta.9",
4
+ "version": "3.16.0-beta.0",
5
5
  "author": "Bild & Vitta <systemteam@bild.com.br>",
6
6
  "license": "MIT",
7
7
  "main": "dist/asteroid.cjs.min.js",
@@ -139,9 +139,27 @@ const primaryKey = computed(() => {
139
139
  return props.splitName in fullList.value ? props.splitName : Object.keys(fullList.value)?.[0]
140
140
  })
141
141
 
142
+ const defaultButtonPropsList = computed(() => {
143
+ const defaultButtonPropsList = {
144
+ useHoverOnWhiteColor: true,
145
+ useLabelOnSmallScreen: false
146
+ }
147
+
148
+ const normalizedButtonPropsList = {}
149
+
150
+ for (const key in formattedList.value.buttonsList) {
151
+ normalizedButtonPropsList[key] = {
152
+ ...defaultButtonPropsList,
153
+ ...formattedList.value.buttonsList[key]
154
+ }
155
+ }
156
+
157
+ return normalizedButtonPropsList
158
+ })
159
+
142
160
  const btnDropdownProps = computed(() => {
143
161
  return {
144
- buttonsPropsList: formattedList.value.buttonsList,
162
+ buttonsPropsList: defaultButtonPropsList.value,
145
163
  disable: props.disable,
146
164
  useSplit: hasSplit.value
147
165
  }
@@ -15,7 +15,6 @@ export default function useOptionsActions ({ props, color }) {
15
15
  options: {
16
16
  color,
17
17
  iconRight: 'sym_r_more_vert',
18
- useLabelOnSmallScreen: false,
19
18
  ...props.buttonProps,
20
19
  label: getLabel({ useLabel: props.useLabel, label: 'Opções' }) // label não pode ser sobrescrita.
21
20
  }
@@ -41,14 +41,16 @@ const props = defineProps({
41
41
  const defaultButtonDropdownProps = computed(() => ({
42
42
  ...props.buttonDropdownProps,
43
43
 
44
- buttonProps: {
45
- align: 'between',
46
- class: 'text-subtitle2',
47
- color: 'primary',
48
- iconRight: 'sym_r_expand_more',
49
- label: props.currentModule.label,
50
- useEllipsis: true,
51
- useLabelOnSmallScreen: true
44
+ buttonsPropsList: {
45
+ modules: {
46
+ align: 'between',
47
+ class: 'text-subtitle2',
48
+ color: 'primary',
49
+ iconRight: 'sym_r_expand_more',
50
+ label: props.currentModule.label,
51
+ useEllipsis: true,
52
+ useLabelOnSmallScreen: true
53
+ }
52
54
  }
53
55
  }))
54
56
 
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="qas-btn-dropdown" :class="classes.parent">
3
- <div v-if="hasButtons" class="flex">
3
+ <div v-if="hasButtons" :class="classes.list">
4
4
  <div v-for="(buttonProps, key, index) in props.buttonsPropsList" :key="key">
5
5
  <div class="flex">
6
6
  <qas-btn :disable="props.disable" v-bind="buttonProps" variant="tertiary" @click="onClick">
@@ -88,6 +88,10 @@ const classes = computed(() => {
88
88
 
89
89
  menuContent: {
90
90
  'q-pa-md': props.useMenuPadding
91
+ },
92
+
93
+ list: {
94
+ flex: !isSingleButton.value
91
95
  }
92
96
  }
93
97
  })
@@ -11,7 +11,7 @@
11
11
  <qas-actions-menu v-if="hasActions" :list="actionsMenuProps" :use-label="false" />
12
12
  </div>
13
13
 
14
- <div class="q-my-sm">
14
+ <div class="q-my-sm qas-card__content">
15
15
  <slot name="default" />
16
16
  </div>
17
17
 
@@ -97,6 +97,10 @@ const hasFooter = computed(() => hasFooterSlot.value || hasExpansion.value)
97
97
 
98
98
  <style lang="scss">
99
99
  .qas-card {
100
+ &__content {
101
+ max-width: 100%;
102
+ }
103
+
100
104
  &__router {
101
105
  &:hover {
102
106
  color: $primary;
@@ -47,7 +47,7 @@ import {
47
47
  import { Bar as BarChart, Doughnut as DoughnutChart, Line as LineChart } from 'vue-chartjs'
48
48
 
49
49
  // Configurações padrões
50
- import { charts, colors, font } from './config'
50
+ import { charts, colors as defaultColors, font } from './config'
51
51
 
52
52
  // Plugins
53
53
  import zoomPlugin from 'chartjs-plugin-zoom'
@@ -79,6 +79,11 @@ export default {
79
79
  type: Function
80
80
  },
81
81
 
82
+ colorsList: {
83
+ type: Array,
84
+ default: () => []
85
+ },
86
+
82
87
  entity: {
83
88
  required: true,
84
89
  type: String
@@ -161,6 +166,7 @@ export default {
161
166
 
162
167
  const [dataset] = this.data
163
168
  const labels = this.getXAxisData(dataset.data.map(item => item.x))
169
+ const colors = this.colorsList.length ? this.colorsList : defaultColors
164
170
 
165
171
  const datasets = this.data.map(({ label, data }, index) => {
166
172
  const backgroundColor = this.isDoughnut ? colors : colors.at(index)
@@ -10,6 +10,12 @@ props:
10
10
  type: Function
11
11
  examples: ['beforeFetch({ payload, resolve, done })']
12
12
 
13
+ colors-list:
14
+ desc: Lista de cores personalizadas para utilizar nos gráficos
15
+ default: []
16
+ type: Array,
17
+ examples: ['#34B53A', '#016DD9', '#FFB200', '#F62D1B']
18
+
13
19
  entity:
14
20
  desc: Entidade da store, por exemplo se tiver que trabalhar com modulo de usuários, teremos o model "users" na store, que vai ser nossa "entity".
15
21
  required: true
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <div class="qas-expansion-item" :class="errorClasses">
3
+ <qas-box class="qas-expansion-item__box">
4
+ <q-expansion-item header-class="text-bold q-mt-sm q-pa-none" :label="props.label">
5
+ <template #header>
6
+ <slot name="header">
7
+ <div class="full-width">
8
+ <div class="items-center q-col-gutter-sm row">
9
+ <slot name="label">
10
+ <h5 class="col-auto text-h5 text-weight-medium">
11
+ {{ props.label }}
12
+ </h5>
13
+ </slot>
14
+
15
+ <div class="col-auto items-center q-col-gutter-sm row">
16
+ <div v-for="(badge, badgeIndex) in props.badges" :key="badgeIndex" class="col-auto">
17
+ <qas-badge v-bind="badge" />
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </slot>
23
+ </template>
24
+
25
+ <q-separator class="q-my-md" />
26
+
27
+ <slot name="content">
28
+ <qas-grid-generator v-if="hasGridGenerator" v-bind="gridGeneratorProps" use-inline />
29
+ </slot>
30
+ </q-expansion-item>
31
+ </qas-box>
32
+
33
+ <div v-if="hasError" class="q-pt-sm qas-expansion-item__error-message text-caption text-negative">
34
+ {{ props.errorMessage }}
35
+ </div>
36
+ </div>
37
+ </template>
38
+
39
+ <script setup>
40
+ import { computed } from 'vue'
41
+
42
+ defineOptions({ name: 'QasExpansionItem' })
43
+
44
+ const props = defineProps({
45
+ badges: {
46
+ type: Array,
47
+ default: () => []
48
+ },
49
+
50
+ error: {
51
+ type: Boolean
52
+ },
53
+
54
+ errorMessage: {
55
+ type: String,
56
+ default: ''
57
+ },
58
+
59
+ label: {
60
+ type: String,
61
+ default: ''
62
+ },
63
+
64
+ gridGeneratorProps: {
65
+ type: Object,
66
+ default: () => ({})
67
+ }
68
+ })
69
+
70
+ const hasError = computed(() => props.error || !!props.errorMessage)
71
+
72
+ const errorClasses = computed(() => ({ 'qas-expansion-item--error': hasError.value }))
73
+
74
+ const hasGridGenerator = computed(() => !!Object.keys(props.gridGeneratorProps).length)
75
+ </script>
76
+
77
+ <style lang="scss">
78
+ .qas-expansion-item {
79
+ $root: &;
80
+
81
+ &--error {
82
+ #{$root}__box {
83
+ border: 2px solid $negative;
84
+ }
85
+
86
+ #{$root}__error-message {
87
+ padding-left: 12px; // espaçamento igual ao de erro do quasar.
88
+ }
89
+ }
90
+
91
+ .q-item {
92
+ margin-top: 0;
93
+ min-height: auto;
94
+ }
95
+
96
+ .q-item:hover {
97
+ color: initial !important;
98
+ }
99
+ }
100
+ </style>
@@ -0,0 +1,35 @@
1
+ type: component
2
+
3
+ meta:
4
+ desc: Componente de card expansivo, wrapper do QExpansionItem(https://quasar.dev/vue-components/expansion-item)
5
+
6
+ props:
7
+ badges:
8
+ desc: Lista de badges que serão exibidas na parte superior do card.
9
+ type: Array
10
+
11
+ error:
12
+ desc: Booleano que caso seja true o card passa a ter uma borda vermelha.
13
+ type: Boolean
14
+
15
+ error-message:
16
+ desc: Mensagem de erro onde será exibida na parte inferior do card.
17
+ type: String
18
+
19
+ label:
20
+ desc: Titulo exibido na parte superior do card.
21
+ type: String
22
+
23
+ grid-generator-props:
24
+ desc: Propriedades que serão repassadas para o QasGridGenerator.
25
+ type: Object
26
+
27
+ slots:
28
+ header:
29
+ desc: 'Slot para substituir o conteúdo do header'
30
+
31
+ label:
32
+ desc: 'Slot para substituir o conteúdo da label do header.'
33
+
34
+ content:
35
+ desc: 'Slot para substituir o conteúdo principal do card.'
@@ -2,7 +2,7 @@
2
2
  <div :class="fieldsetClasses">
3
3
  <div v-for="(fieldsetItem, fieldsetItemKey) in normalizedFields" :key="fieldsetItemKey" class="full-width">
4
4
  <slot v-if="fieldsetItem.label" :name="`legend-${fieldsetItemKey}`">
5
- <qas-label :label="fieldsetItem.label" />
5
+ <qas-label :label="fieldsetItem.label" :margin="getLabelMargin(fieldsetItem)" />
6
6
  <div v-if="fieldsetItem.description" class="q-mb-md text-body1 text-grey-8">{{ fieldsetItem.description }}</div>
7
7
  </slot>
8
8
 
@@ -26,7 +26,8 @@
26
26
  </template>
27
27
 
28
28
  <script setup>
29
- import useGenerator, { baseProps, gutterValidator } from '../../composables/private/use-generator'
29
+ import { gutterValidator } from '../../helpers/private/gutter-validator'
30
+ import useGenerator, { baseProps } from '../../composables/private/use-generator'
30
31
  import { Spacing } from '../../enums/Spacing'
31
32
  import { computed } from 'vue'
32
33
 
@@ -179,4 +180,8 @@ function useFieldset ({ props }) {
179
180
  hasFieldset
180
181
  }
181
182
  }
183
+
184
+ function getLabelMargin (fieldsetItem) {
185
+ return fieldsetItem.description ? 'sm' : 'md'
186
+ }
182
187
  </script>
@@ -8,7 +8,7 @@ props:
8
8
  desc: Colunas do grid de cada campo.
9
9
  default: col-6
10
10
  type: [Array, String, Object]
11
- examples: ["[{ sm: 6, md: 12 }]", "{ name: { sm: 6, md: 12 } }", "12"]
11
+ examples: ["[{ sm: 6, md: 12 }]", "{ name: { sm: 6, md: 12 } }", "12", "{ sm: 6, md: 12 }"]
12
12
 
13
13
  disable:
14
14
  desc: Deixa os campos desabilitados enviando a prop "disable" para cada campo.
@@ -42,13 +42,13 @@ props:
42
42
  desc: Espaçamento entre rótulos (label).
43
43
  default: lg
44
44
  type: [String, Boolean]
45
- examples: [xs, sm, md, lg, xl, false]
45
+ examples: [xs, sm, md, lg, xl, '2xl', '3xl', '4xl', '5xl', false]
46
46
 
47
47
  gutter:
48
48
  desc: Espaçamento entre colunas.
49
49
  default: lg
50
50
  type: [String, Boolean]
51
- examples: [xs, sm, md, lg, xl, false]
51
+ examples: [xs, sm, md, lg, xl, '2xl', '3xl', '4xl', '5xl', false]
52
52
 
53
53
  model-value:
54
54
  desc: Model do componente, usado para o v-model.
@@ -63,6 +63,9 @@ props:
63
63
  default: []
64
64
  type: Array
65
65
 
66
+ use-common-columns:
67
+ desc: Utilizado quando passar a estrutura da prop "columns" sendo um objeto onde seus breakpoints serão replicados para todos fields.
68
+
66
69
  slots:
67
70
  'field-[nome-da-chave]':
68
71
  desc: Acessa o slot de um campo especifico.
@@ -1,15 +1,15 @@
1
1
  <template>
2
2
  <div :class="classes">
3
- <div v-for="(field, key) in fieldsByResult" :key="key" :class="getFieldClass({ index: key, isGridGenerator: true })">
3
+ <div v-for="(field, key) in fieldsByResult" :key="key" :class="getContainerClass({ key })">
4
4
  <slot :field="field" :name="`field-${field.name}`">
5
5
  <slot :field="field" name="header">
6
- <header :class="props.headerClass" :data-cy="`grid-generator-${field.name}-field`">
6
+ <header :class="headerClass" :data-cy="`grid-generator-${field.name}-field`" :title="getTitle(field, 'label')">
7
7
  {{ field.label }}
8
8
  </header>
9
9
  </slot>
10
10
 
11
11
  <slot :field="field" name="content">
12
- <div :class="props.contentClass" :data-cy="`grid-generator-${field.name}-result`">
12
+ <div :class="contentClass" :data-cy="`grid-generator-${field.name}-result`" :title="getTitle(field, 'formattedResult')">
13
13
  {{ field.formattedResult }}
14
14
  </div>
15
15
  </slot>
@@ -21,12 +21,15 @@
21
21
  <script setup>
22
22
  import useGenerator, { baseProps } from '../../composables/private/use-generator'
23
23
  import { isEmpty, humanize } from '../../helpers'
24
+ import { useScreen } from '../../composables'
24
25
  import { isObject } from 'lodash-es'
25
26
  import { ref, computed, watch } from 'vue'
26
27
 
27
28
  // define component name
28
29
  defineOptions({ name: 'QasGridGenerator' })
29
30
 
31
+ const screen = useScreen()
32
+
30
33
  // props
31
34
  const props = defineProps({
32
35
  ...baseProps,
@@ -37,7 +40,7 @@ const props = defineProps({
37
40
  },
38
41
 
39
42
  headerClass: {
40
- default: 'text-bold',
43
+ default: '',
41
44
  type: [Array, Object, String]
42
45
  },
43
46
 
@@ -54,16 +57,52 @@ const props = defineProps({
54
57
  useEmptyResult: {
55
58
  default: true,
56
59
  type: Boolean
60
+ },
61
+
62
+ useEllipsis: {
63
+ default: true,
64
+ type: Boolean
65
+ },
66
+
67
+ useInline: {
68
+ type: Boolean
57
69
  }
58
70
  })
59
71
 
60
72
  // composables
61
- const { classes, getFieldClass } = useGenerator({ props })
73
+ const { classes: useGeneratorClasses, getFieldClass } = useGenerator({ props })
62
74
 
63
75
  // computed
64
76
  const hasResult = computed(() => Object.keys(props.result).length)
65
77
  const hasFields = computed(() => Object.keys(props.fields).length)
66
78
 
79
+ const contentClass = computed(() => {
80
+ return [
81
+ props.contentClass,
82
+
83
+ {
84
+ ellipsis: !screen.isSmall && props.useEllipsis
85
+ }
86
+ ]
87
+ })
88
+
89
+ const headerClass = computed(() => {
90
+ return [
91
+ props.headerClass,
92
+
93
+ {
94
+ ellipsis: !screen.isSmall && props.useEllipsis,
95
+ 'text-bold': screen.isSmall || !props.useInline
96
+ }
97
+ ]
98
+ })
99
+
100
+ const classes = computed(() => {
101
+ if (props.useInline) return 'row q-col-gutter-md'
102
+
103
+ return useGeneratorClasses.value
104
+ })
105
+
67
106
  const fieldsByResult = ref({})
68
107
 
69
108
  /**
@@ -122,4 +161,16 @@ function getFieldsByResult () {
122
161
  function setFieldsByResult () {
123
162
  fieldsByResult.value = getFieldsByResult()
124
163
  }
164
+
165
+ function getContainerClass ({ key }) {
166
+ if (props.useInline) {
167
+ return 'row justify-between col-12'
168
+ }
169
+
170
+ return getFieldClass({ index: key, isGridGenerator: true })
171
+ }
172
+
173
+ function getTitle (field, key) {
174
+ return props.useEllipsis ? field[key] : ''
175
+ }
125
176
  </script>
@@ -8,7 +8,7 @@ props:
8
8
  desc: Colunas do grid de cada campo.
9
9
  default: col-6
10
10
  type: [Array, String, Object]
11
- examples: ["{ name: { sm: 6, md: 12 } }", "[{ sm: 6, md: 12 }]"]
11
+ examples: ["{ name: { sm: 6, md: 12 } }", "[{ sm: 6, md: 12 }]", "{ sm: 6, md: 12 }"]
12
12
 
13
13
  content-class:
14
14
  desc: Classe de cada "div" pai referente ao resultado.
@@ -30,7 +30,7 @@ props:
30
30
  desc: Espaçamento entre colunas.
31
31
  default: lg
32
32
  type: String
33
- examples: [xs, sm, md, lg, xl]
33
+ examples: [xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl]
34
34
 
35
35
  header-class:
36
36
  desc: Classe de cada "header" pai referente ao "label".
@@ -48,6 +48,18 @@ props:
48
48
  default: true
49
49
  type: Boolean
50
50
 
51
+ use-ellipsis:
52
+ desc: Adiciona a classe "ellipsis" para o elemento do conteúdo.
53
+ default: true
54
+ type: Boolean
55
+
56
+ use-inline:
57
+ desc: Adiciona a disposição dos campos por linha, ou seja, header e content ocupando a linha toda.
58
+ type: Boolean
59
+
60
+ use-common-columns:
61
+ desc: Usado quando precisa passar a prop "columns" como objeto sendo que será o valor comum para todos fields
62
+
51
63
  slots:
52
64
  content:
53
65
  desc: Slot para o conteúdo (content).
@@ -78,7 +78,7 @@ props:
78
78
  desc: Espaçamento entre colunas do formulário.
79
79
  default: lg
80
80
  type: [String, Boolean]
81
- examples: [xs, sm, md, lg, xl, false]
81
+ examples: [xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, false]
82
82
 
83
83
  identifier-item-key:
84
84
  desc: Define um identificador para o item. O identificador será utilizado para validar exclusão do item, por exemplo.
@@ -194,7 +194,7 @@ export default {
194
194
 
195
195
  if (this.fuse || this.hasFuse) this.setFuse()
196
196
 
197
- this.mx_filteredOptions = this.options
197
+ this.mx_filteredOptions = [...this.options]
198
198
  },
199
199
 
200
200
  immediate: true
@@ -0,0 +1,152 @@
1
+ <template>
2
+ <div class="qas-stepper" :class="classes">
3
+ <q-stepper ref="stepper" v-model="model" active-color="primary" active-icon="none" animated :contracted="screen.untilLarge" done-color="primary" done-icon="none" flat :header-class="headerClass" inactive-color="grey-6" keep-alive>
4
+ <template v-for="(_, name) in $slots" #[name]="context">
5
+ <slot :name="name" v-bind="getContext(context)" />
6
+ </template>
7
+ </q-stepper>
8
+ </div>
9
+ </template>
10
+
11
+ <script setup>
12
+ import { computed, ref } from 'vue'
13
+ import { Spacing } from '../../enums/Spacing'
14
+ import { gutterValidator } from '../../helpers/private/gutter-validator'
15
+ import useScreen from '../../composables/use-screen'
16
+
17
+ defineOptions({ name: 'QasStepper' })
18
+
19
+ const props = defineProps({
20
+ disable: {
21
+ type: Boolean
22
+ },
23
+
24
+ modelValue: {
25
+ type: [String, Number],
26
+ default: 0
27
+ },
28
+
29
+ spacing: {
30
+ default: Spacing.Lg,
31
+ type: [String, Boolean],
32
+ validator: gutterValidator
33
+ }
34
+ })
35
+
36
+ const stepper = ref(null)
37
+
38
+ const screen = useScreen()
39
+
40
+ const emit = defineEmits(['update:modelValue'])
41
+
42
+ defineExpose({ next, previous, goTo })
43
+
44
+ const model = computed({
45
+ get () {
46
+ return props.modelValue
47
+ },
48
+
49
+ set (modelValue) {
50
+ return emit('update:modelValue', modelValue)
51
+ }
52
+ })
53
+
54
+ const classes = computed(() => ({ 'qas-stepper--disable': props.disable }))
55
+
56
+ const headerClass = computed(() => `text-subtitle1 q-pb-${props.spacing}`)
57
+
58
+ function getContext (context) {
59
+ return {
60
+ ...context,
61
+ next,
62
+ previous
63
+ }
64
+ }
65
+
66
+ function goTo (step) {
67
+ stepper.value.goTo(step)
68
+ }
69
+
70
+ function next () {
71
+ if (props.disable) return
72
+
73
+ stepper.value.next()
74
+ }
75
+
76
+ function previous () {
77
+ if (props.disable) return
78
+
79
+ stepper.value.previous()
80
+ }
81
+ </script>
82
+
83
+ <style lang="scss">
84
+ .qas-stepper {
85
+ .q-stepper {
86
+ background-color: transparent;
87
+
88
+ &__tab {
89
+ padding: 0;
90
+ }
91
+
92
+ &__caption {
93
+ @include set-typography($caption);
94
+ color: $grey-6;
95
+ }
96
+ }
97
+
98
+ &--disable {
99
+ .q-stepper {
100
+ &__title {
101
+ color: $grey-6;
102
+ }
103
+
104
+ &__line::after,
105
+ &__line::before,
106
+ &__dot {
107
+ background-color: $grey-6 !important;
108
+ }
109
+ }
110
+ }
111
+
112
+ .q-stepper--horizontal .q-stepper__line::before,
113
+ .q-stepper--horizontal .q-stepper__line::after {
114
+ height: 4px;
115
+ border-radius: var(--qas-generic-border-radius);
116
+ }
117
+
118
+ .q-stepper__header--standard-labels .q-stepper__tab {
119
+ min-height: auto;
120
+ }
121
+
122
+ .q-stepper__tab:nth-child(1),
123
+ .q-stepper__tab--done {
124
+
125
+ .q-stepper__line::after,
126
+ .q-stepper__line::before {
127
+ background-color: var(--q-primary);
128
+ }
129
+ }
130
+
131
+ .q-stepper__tab:nth-child(2),
132
+ .q-stepper__tab--active {
133
+ .q-stepper__line::before {
134
+ background-color: var(--q-primary);
135
+ }
136
+ }
137
+
138
+ .q-stepper__nav,
139
+ .q-stepper__step-inner {
140
+ padding: 0;
141
+ }
142
+
143
+ .q-stepper__header--contracted .q-stepper__tab:first-child .q-stepper__dot,
144
+ .q-stepper__header--contracted .q-stepper__tab:last-child .q-stepper__dot {
145
+ transform: translateX(0);
146
+ }
147
+
148
+ .q-focus-helper {
149
+ display: none;
150
+ }
151
+ }
152
+ </style>
@@ -0,0 +1,36 @@
1
+ type: component
2
+
3
+ meta:
4
+ desc: Componente de stepper.
5
+
6
+ props:
7
+ disable:
8
+ desc: Deixa o componente desabilitado.
9
+ default: false
10
+ type: Boolean
11
+
12
+ spacing:
13
+ desc: Espaçamento entre o stepper e o conteúdo da página.
14
+ default: lg
15
+ type: [String, Boolean]
16
+ examples: [xs, sm, md, lg, xl, '2xl', '3xl', '4xl', '5xl', false]
17
+
18
+ model-value:
19
+ desc: Model do componente, responsável por controlar em qual step deverá ser exibido.
20
+ model: true
21
+ type: [Number, String]
22
+
23
+ events:
24
+ '@update:model-value -> function(value)':
25
+ desc: Dispara quando o model-value altera, também usado para v-model.
26
+ params:
27
+ value:
28
+ desc: Valor do mode-value.
29
+ type: [Number, String]
30
+
31
+ methods:
32
+ 'next: () => void':
33
+ desc: Avança o stepper para o prõximo step.
34
+
35
+ 'previous: () => void':
36
+ desc: Volta o stepper para o step anterior.
@@ -0,0 +1,84 @@
1
+ <template>
2
+ <qas-stepper ref="stepper" v-model="model" v-bind="stepperProps">
3
+ <template #default>
4
+ <q-step v-for="(step, stepIndex) in props.steps" :key="stepIndex" :done="isDone(stepIndex)" :name="getStepName(stepIndex)" v-bind="stepPropsList[stepIndex]">
5
+ <component :is="step.component" />
6
+ </q-step>
7
+ </template>
8
+ </qas-stepper>
9
+ </template>
10
+
11
+ <script setup>
12
+ import { ref, provide, computed } from 'vue'
13
+
14
+ defineOptions({ name: 'QasStepperFormView' })
15
+
16
+ const props = defineProps({
17
+ steps: {
18
+ type: Array,
19
+ required: true
20
+ },
21
+
22
+ formViewProps: {
23
+ type: Object,
24
+ default: () => ({})
25
+ },
26
+
27
+ stepperProps: {
28
+ type: Object,
29
+ default: () => ({})
30
+ }
31
+ })
32
+
33
+ const model = defineModel({ type: Number, default: 1 })
34
+
35
+ const values = ref({})
36
+ const stepPropsList = ref([])
37
+ const stepper = ref(null)
38
+
39
+ setStepProps({ payload: [...props.steps.map(({ stepProps }) => stepProps)] })
40
+
41
+ const defaultFormViewProps = computed(() => {
42
+ return {
43
+ useBoundary: false,
44
+ useNotifySuccess: false,
45
+ ...props.formViewProps
46
+ }
47
+ })
48
+
49
+ function setStepProps ({ step, payload }) {
50
+ if (step) {
51
+ stepPropsList.value[step - 1] = payload
52
+ } else {
53
+ stepPropsList.value = payload
54
+ }
55
+ }
56
+
57
+ /*
58
+ * - Merge do payload com objetivo de enviar o payload completo de todos steps no stepper final
59
+ * - É possível ir para um step especifico ou somente ir para o próximo.
60
+ */
61
+ function nextStep ({ payload = {} }) {
62
+ Object.assign(values.value, payload)
63
+
64
+ stepper.value.next()
65
+ }
66
+
67
+ function isDone (stepIndex) {
68
+ return model.value > stepIndex + 1
69
+ }
70
+
71
+ function getStepName (stepIndex) {
72
+ return stepIndex + 1
73
+ }
74
+
75
+ provide('stepper', {
76
+ stepperModel: model,
77
+ formViewProps: defaultFormViewProps,
78
+ goTo: step => stepper.value.goTo(step),
79
+ next: nextStep,
80
+ previous: () => stepper.value.previous(),
81
+ setStepProps,
82
+ stepsValues: values
83
+ })
84
+ </script>
@@ -0,0 +1,58 @@
1
+ type: component
2
+
3
+ meta:
4
+ desc: Componente para steppers de formulário.
5
+
6
+ props:
7
+ steps:
8
+ desc: Lista de step, cada item possuindo "stepProps" e "component".
9
+ required: true
10
+ type: Array
11
+
12
+ form-view-props:
13
+ desc: Propriedades que serão repassadas para os componentes, podendo repassar coisas que serão comúm entre as páginas, como "entity", "mode".
14
+ type: Object
15
+
16
+ stepper-props:
17
+ desc: Propriedades que serão repassadas para o QasStepper.
18
+ type: Object
19
+
20
+ inject:
21
+ stepper-model:
22
+ desc: Model do stepper caso precise recuperar o step atual para alguma lógica. Possui reatividade, portanto para acessar é necessário do ".value"
23
+ type: Number
24
+
25
+ form-view-props:
26
+ desc: Propriedades do QasFormView que são comuns entre todos os steppers. Possui reatividade, portanto para acessar é necessário do ".value"
27
+ type: Object
28
+
29
+ 'goTo: (step) => void':
30
+ desc: Função usada para mudar o step atual.
31
+ params:
32
+ step:
33
+ desc: Nome do step que deseja visualizar.
34
+ type: Number
35
+
36
+ 'next: (payload) => void':
37
+ desc: Avança para o próximo step.
38
+ params:
39
+ payload:
40
+ desc: Payload do formulário atual, que será mergeado no "stepperValues", com a intenção de guardar o payload completo para ser enviado no último step.
41
+ type: Object
42
+
43
+ 'previous: () => void':
44
+ desc: Volta para o step anterior.
45
+
46
+ 'setStepProps: () => void':
47
+ desc: Altera as propriedades de um step específico caso precise que seja alterado com base em alguma lógica atual da página.
48
+ params:
49
+ step:
50
+ desc: Step que deseja alterar as propriedades
51
+ type: Number
52
+
53
+ payload:
54
+ desc: Propriedades do step como "title", "prefix", "caption", entre outros.
55
+
56
+ steps-values:
57
+ desc: Payload com todos valores que foram mergeados através da função "next" ao decorrer dos avanços dos steps. É usado para você recuperar no último step com intenção de enviar o payload completo de todos step para a API. Possui reatividade, portanto para acessar é necessário do ".value"
58
+ type: Object
@@ -1,5 +1,6 @@
1
1
  import { computed } from 'vue'
2
2
  import { Spacing } from '../../enums/Spacing'
3
+ import { gutterValidator } from '../../helpers/private/gutter-validator'
3
4
 
4
5
  const IRREGULAR_CLASSES = ['col', 'col-auto', 'fit']
5
6
 
@@ -18,21 +19,11 @@ export const baseProps = {
18
19
  default: Spacing.Lg,
19
20
  type: [String, Boolean],
20
21
  validator: gutterValidator
21
- }
22
- }
23
-
24
- // TODO: validar a necessidade da prop ser boolean
25
- /**
26
- * Valida se o gutter passado respeita os valores do enum Spacing ou é um boolean.
27
- *
28
- * @function
29
- * @param {(string|boolean)} value
30
- * @returns {boolean}
31
- */
32
- export function gutterValidator (value) {
33
- const availableSpacings = Object.values(Spacing)
22
+ },
34
23
 
35
- return typeof value === 'boolean' || availableSpacings.includes(value)
24
+ useCommonColumns: {
25
+ type: Boolean
26
+ }
36
27
  }
37
28
 
38
29
  /**
@@ -99,7 +90,11 @@ export default function ({ props = {} }) {
99
90
  for (const key in formattedColumns) {
100
91
  const value = formattedColumns[key]
101
92
 
102
- classes.push(IRREGULAR_CLASSES.includes(value) ? value : `${profiles[key]}-${value}`)
93
+ if (IRREGULAR_CLASSES.includes(value)) {
94
+ classes.push(value === 'col' ? profiles[key] : value)
95
+ } else {
96
+ classes.push(`${profiles[key]}-${value}`)
97
+ }
103
98
  }
104
99
 
105
100
  return [...classes, renamedClasses]
@@ -116,10 +111,23 @@ export default function ({ props = {} }) {
116
111
  * @private
117
112
  */
118
113
  function _handleColumnsByField ({ index, isGridGenerator }) {
114
+ /*
115
+ * Quando é passado o columns como um único objeto que será replicado para todos fields.
116
+ */
117
+ if (props.useCommonColumns && Object.keys(props.columns).length) {
118
+ return _getBreakpoint(props.columns)
119
+ }
120
+
121
+ /*
122
+ * Quando não é passado columns, retornará o default.
123
+ */
119
124
  if (!props.columns[index]) {
120
125
  return _getDefaultColumnClass(isGridGenerator)
121
126
  }
122
127
 
128
+ /*
129
+ * Quando é passado um objeto por field.
130
+ */
123
131
  return _getBreakpoint(props.columns[index])
124
132
  }
125
133
 
@@ -45,6 +45,16 @@ $space-3xl: (
45
45
  y: ($space-y-base * 3) // 48px
46
46
  );
47
47
 
48
+ $space-4xl: (
49
+ x: ($space-x-base * 3.5),// 56px
50
+ y: ($space-y-base * 3.5) // 56px
51
+ );
52
+
53
+ $space-5xl: (
54
+ x: ($space-x-base * 4), // 64px
55
+ y: ($space-y-base * 4) // 64px
56
+ );
57
+
48
58
  $spaces: (
49
59
  none: $space-none, // 0px
50
60
  xs: $space-xs, // 4px
@@ -53,7 +63,9 @@ $spaces: (
53
63
  lg: $space-lg, // 24px
54
64
  xl: $space-xl, // 32px
55
65
  2xl: $space-2xl, // 40px
56
- 3xl: $space-3xl // 48px
66
+ 3xl: $space-3xl, // 48px
67
+ 4xl: $space-4xl, // 56px
68
+ 5xl: $space-5xl // 64px
57
69
  );
58
70
 
59
71
  $flex-gutter-xs : map.get($space-xs, 'x');
@@ -63,6 +75,8 @@ $flex-gutter-lg : map.get($space-lg, 'x');
63
75
  $flex-gutter-xl : map.get($space-xl, 'x');
64
76
  $flex-gutter-2xl : map.get($space-2xl, 'x');
65
77
  $flex-gutter-3xl : map.get($space-3xl, 'x');
78
+ $flex-gutter-4xl : map.get($space-4xl, 'x');
79
+ $flex-gutter-5xl : map.get($space-5xl, 'x');
66
80
 
67
81
  $flex-gutter: (
68
82
  none: 0, // 0px
@@ -71,8 +85,10 @@ $flex-gutter: (
71
85
  md: $flex-gutter-md, // 16px
72
86
  lg: $flex-gutter-lg, // 24px
73
87
  xl: $flex-gutter-xl, // 32px
74
- 2xl: $flex-gutter-2xl, // 48px
75
- 3xl: $flex-gutter-3xl // 40px
88
+ 2xl: $flex-gutter-2xl, // 40px
89
+ 3xl: $flex-gutter-3xl, // 48px
90
+ 4xl: $flex-gutter-4xl, // 56px
91
+ 5xl: $flex-gutter-5xl // 64px
76
92
  );
77
93
 
78
94
  :root {
@@ -14,6 +14,8 @@
14
14
  * Xl: 'xl',
15
15
  * '2xl': '2xl',
16
16
  * '3xl': '3xl',
17
+ * '4xl': '4xl',
18
+ * '5xl': '5xl'
17
19
  * }}
18
20
  */
19
21
  export const Spacing = {
@@ -24,7 +26,9 @@ export const Spacing = {
24
26
  Lg: 'lg',
25
27
  Xl: 'xl',
26
28
  '2xl': '2xl',
27
- '3xl': '3xl'
29
+ '3xl': '3xl',
30
+ '4xl': '4xl',
31
+ '5xl': '5xl'
28
32
  }
29
33
 
30
34
  /**
@@ -40,9 +44,11 @@ export const Spacing = {
40
44
  * Sm: '8px',
41
45
  * Md: '16px',
42
46
  * Lg: '24px',
43
- * Xl: '32px',
47
+ * Xl: '52px',
44
48
  * '2xl': '40px',
45
- * '3xl': '48px'
49
+ * '3xl': '48px',
50
+ * '4xl': '56px',
51
+ * '5xl': '64px'
46
52
  * }}
47
53
  */
48
54
  export const SpacingWithUnit = {
@@ -53,5 +59,7 @@ export const SpacingWithUnit = {
53
59
  Lg: '24px',
54
60
  Xl: '32px',
55
61
  '2xl': '40px',
56
- '3xl': '48px'
62
+ '3xl': '48px',
63
+ '4xl': '56px',
64
+ '5xl': '64px'
57
65
  }
@@ -0,0 +1,15 @@
1
+ import { Spacing } from '../../enums/Spacing'
2
+
3
+ // TODO: validar a necessidade da prop ser boolean
4
+ /**
5
+ * Valida se o gutter passado respeita os valores do enum Spacing ou é um boolean.
6
+ *
7
+ * @function
8
+ * @param {(string|boolean)} value
9
+ * @returns {boolean}
10
+ */
11
+ export function gutterValidator (value) {
12
+ const availableSpacings = Object.values(Spacing)
13
+
14
+ return typeof value === 'boolean' || availableSpacings.includes(value)
15
+ }
package/src/vue-plugin.js CHANGED
@@ -23,6 +23,7 @@ import QasDialog from './components/dialog/QasDialog.vue'
23
23
  import QasDialogRouter from './components/dialog-router/QasDialogRouter.vue'
24
24
  import QasDrawer from './components/drawer/QasDrawer.vue'
25
25
  import QasEmptyResultText from './components/empty-result-text/QasEmptyResultText.vue'
26
+ import QasExpansionItem from './components/expansion-item/QasExpansionItem.vue'
26
27
  import QasField from './components/field/QasField.vue'
27
28
  import QasFilters from './components/filters/QasFilters.vue'
28
29
  import QasFormGenerator from './components/form-generator/QasFormGenerator.vue'
@@ -57,6 +58,8 @@ import QasSignatureUploader from './components/signature-uploader/QasSignatureUp
57
58
  import QasSingleView from './components/single-view/QasSingleView.vue'
58
59
  import QasSortable from './components/sortable/QasSortable.vue'
59
60
  import QasStatus from './components/status/QasStatus.vue'
61
+ import QasStepper from './components/stepper/QasStepper.vue'
62
+ import QasStepperFormView from './components/stepper-form-view/QasStepperFormView.vue'
60
63
  import QasTableGenerator from './components/table-generator/QasTableGenerator.vue'
61
64
  import QasTabsGenerator from './components/tabs-generator/QasTabsGenerator.vue'
62
65
  import QasTextTruncate from './components/text-truncate/QasTextTruncate.vue'
@@ -113,6 +116,7 @@ async function install (app) {
113
116
  app.component('QasDialogRouter', QasDialogRouter)
114
117
  app.component('QasDrawer', QasDrawer)
115
118
  app.component('QasEmptyResultText', QasEmptyResultText)
119
+ app.component('QasExpansionItem', QasExpansionItem)
116
120
  app.component('QasField', QasField)
117
121
  app.component('QasFilters', QasFilters)
118
122
  app.component('QasFormGenerator', QasFormGenerator)
@@ -147,6 +151,8 @@ async function install (app) {
147
151
  app.component('QasSingleView', QasSingleView)
148
152
  app.component('QasSortable', QasSortable)
149
153
  app.component('QasStatus', QasStatus)
154
+ app.component('QasStepper', QasStepper)
155
+ app.component('QasStepperFormView', QasStepperFormView)
150
156
  app.component('QasTableGenerator', QasTableGenerator)
151
157
  app.component('QasTabsGenerator', QasTabsGenerator)
152
158
  app.component('QasTextTruncate', QasTextTruncate)
@@ -204,6 +210,7 @@ export {
204
210
  QasDialogRouter,
205
211
  QasDrawer,
206
212
  QasEmptyResultText,
213
+ QasExpansionItem,
207
214
  QasField,
208
215
  QasFilters,
209
216
  QasFormGenerator,
@@ -238,6 +245,8 @@ export {
238
245
  QasSingleView,
239
246
  QasSortable,
240
247
  QasStatus,
248
+ QasStepper,
249
+ QasStepperFormView,
241
250
  QasTableGenerator,
242
251
  QasTabsGenerator,
243
252
  QasTextTruncate,