@bildvitta/quasar-ui-asteroid 3.16.0-beta.4 → 3.16.0-beta.6

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.16.0-beta.4",
4
+ "version": "3.16.0-beta.6",
5
5
  "author": "Bild & Vitta <systemteam@bild.com.br>",
6
6
  "license": "MIT",
7
7
  "main": "dist/asteroid.cjs.min.js",
@@ -2,8 +2,8 @@
2
2
  <div class="qas-btn-dropdown" :class="classes.parent">
3
3
  <div v-if="hasButtons" :class="classes.list">
4
4
  <div v-for="(buttonProps, key, index) in props.buttonsPropsList" :key="key">
5
- <div class="flex">
6
- <qas-btn :disable="props.disable" v-bind="buttonProps" variant="tertiary" @click="onClick">
5
+ <div class="flex no-wrap">
6
+ <qas-btn :disable="props.disable" v-bind="buttonProps" no-wrap variant="tertiary" @click="onClick">
7
7
  <q-menu v-if="hasMenuOnLeftSide" v-model="isMenuOpened" anchor="bottom right" auto-close self="top right" @update:model-value="onUpdateMenuValue">
8
8
  <div :class="classes.menuContent">
9
9
  <slot />
@@ -91,7 +91,7 @@ const classes = computed(() => {
91
91
  },
92
92
 
93
93
  list: {
94
- flex: !isSingleButton.value
94
+ 'flex no-wrap': !isSingleButton.value
95
95
  }
96
96
  }
97
97
  })
@@ -1,13 +1,13 @@
1
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">
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">
4
+ <q-expansion-item header-class="text-bold q-mt-sm q-pa-none" :label="props.label" v-bind="expansionProps.item">
5
5
  <template #header>
6
6
  <slot name="header">
7
7
  <div class="full-width">
8
8
  <div class="items-center q-col-gutter-sm row">
9
9
  <slot name="label">
10
- <h5 class="col-auto text-h5 text-weight-medium">
10
+ <h5 class="col-auto text-h5">
11
11
  {{ props.label }}
12
12
  </h5>
13
13
  </slot>
@@ -18,17 +18,23 @@
18
18
  </div>
19
19
  </div>
20
20
  </div>
21
+
22
+ <div v-if="hasHeaderBottom" class="q-mt-sm">
23
+ <slot name="header-bottom" />
24
+ </div>
21
25
  </div>
22
26
  </slot>
23
27
  </template>
24
28
 
25
- <q-separator class="q-my-md" />
29
+ <q-separator v-if="!isNestedExpansionItem" class="q-my-md" />
26
30
 
27
31
  <slot name="content">
28
32
  <qas-grid-generator v-if="hasGridGenerator" v-bind="gridGeneratorProps" use-inline />
29
33
  </slot>
34
+
35
+ <q-separator v-if="hasBottomSeparator" class="q-mt-md" />
30
36
  </q-expansion-item>
31
- </qas-box>
37
+ </component>
32
38
 
33
39
  <div v-if="hasError" class="q-pt-sm qas-expansion-item__error-message text-caption text-negative">
34
40
  {{ props.errorMessage }}
@@ -37,9 +43,14 @@
37
43
  </template>
38
44
 
39
45
  <script setup>
40
- import { computed } from 'vue'
46
+ import QasBox from '../box/QasBox.vue'
41
47
 
42
- defineOptions({ name: 'QasExpansionItem' })
48
+ import { computed, provide, inject, onMounted, ref, useAttrs } from 'vue'
49
+
50
+ defineOptions({
51
+ name: 'QasExpansionItem',
52
+ inheritAttrs: false
53
+ })
43
54
 
44
55
  const props = defineProps({
45
56
  badges: {
@@ -67,11 +78,74 @@ const props = defineProps({
67
78
  }
68
79
  })
69
80
 
70
- const hasError = computed(() => props.error || !!props.errorMessage)
81
+ const attrs = useAttrs()
71
82
 
83
+ provide('isExpansionItem', true)
84
+
85
+ // slots
86
+ const slots = defineSlots()
87
+
88
+ // refs
89
+ const expansionItem = ref(null)
90
+ const hasNextSibling = ref(false)
91
+
92
+ onMounted(setHasNextSibling)
93
+
94
+ // constants
95
+ const isNestedExpansionItem = inject('isExpansionItem', false)
96
+ const component = {
97
+ is: isNestedExpansionItem ? 'div' : QasBox
98
+ }
99
+
100
+ // computed
101
+ const hasError = computed(() => props.error || !!props.errorMessage)
72
102
  const errorClasses = computed(() => ({ 'qas-expansion-item--error': hasError.value }))
73
103
 
74
104
  const hasGridGenerator = computed(() => !!Object.keys(props.gridGeneratorProps).length)
105
+ const hasBottomSeparator = computed(() => isNestedExpansionItem && hasNextSibling.value)
106
+ const hasHeaderBottom = computed(() => !!slots['header-bottom'])
107
+
108
+ const expansionProps = computed(() => {
109
+ const {
110
+ 'onUpdate:modelValue': onUpdateModelValue,
111
+ onShow,
112
+ onBeforeShow,
113
+ onBeforeHide,
114
+ onAfterShow,
115
+ onAfterHide,
116
+ ...propsPayload
117
+ } = attrs
118
+
119
+ return {
120
+ parent: {
121
+ ...propsPayload
122
+ },
123
+
124
+ item: {
125
+ onUpdateModelValue,
126
+ onShow,
127
+ onBeforeShow,
128
+ onBeforeHide,
129
+ onAfterShow,
130
+ onAfterHide
131
+ }
132
+ }
133
+ })
134
+
135
+ // functions
136
+
137
+ /**
138
+ * Caso o componente esteja dentro de um QasExpansionItem, verifica se existe um próximo irmão
139
+ * para adicionar um separador.
140
+ */
141
+ function setHasNextSibling (value) {
142
+ if (!isNestedExpansionItem) return
143
+
144
+ const hasTextContentSibling = !!expansionItem.value.nextSibling.textContent?.trim?.()
145
+ const hasElementSibling = !!expansionItem.value.nextElementSibling
146
+
147
+ hasNextSibling.value = hasElementSibling || hasTextContentSibling
148
+ }
75
149
  </script>
76
150
 
77
151
  <style lang="scss">
@@ -28,6 +28,9 @@ slots:
28
28
  header:
29
29
  desc: 'Slot para substituir o conteúdo do header'
30
30
 
31
+ header-bottom:
32
+ desc: 'Slot para acessar o conteúdo que fica abaixo do header.'
33
+
31
34
  label:
32
35
  desc: 'Slot para substituir o conteúdo da label do header.'
33
36
 
@@ -6,7 +6,7 @@
6
6
  </slot>
7
7
  </div>
8
8
 
9
- <div v-if="hasRightSide" class="col-3 col-md-3 col-sm-4 justify-end row">
9
+ <div v-if="hasRightSide" class="justify-end row">
10
10
  <slot name="right">
11
11
  <qas-actions-menu v-if="hasDefaultActionsMenu" v-bind="props.actionsMenuProps" />
12
12
 
@@ -59,7 +59,11 @@ const slots = useSlots()
59
59
  // computed
60
60
  const containerClass = computed(() => `items-${props.alignColumns} q-mb-${props.spacing}`)
61
61
 
62
- const leftClass = computed(() => hasRightSide.value ? 'col-9 col-md-9 col-sm-8' : 'col-12')
62
+ const leftClass = computed(() => {
63
+ return {
64
+ 'col-12': !hasRightSide.value
65
+ }
66
+ })
63
67
 
64
68
  const hasDefaultButton = computed(() => !!Object.keys(props.buttonProps).length)
65
69
  const hasDefaultActionsMenu = computed(() => !!Object.keys(props.actionsMenuProps).length)
@@ -82,6 +82,9 @@ const {
82
82
  updateModels
83
83
  } = useView({ emit, props, slots, mode: 'single' })
84
84
 
85
+ // Expose
86
+ defineExpose({ fetchSingle, fetchHandler })
87
+
85
88
  // computed
86
89
  const id = computed(() => props.customId || route.params.id)
87
90
 
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <div class="qas-toggle-visibility">
3
+ <div class="items-center no-wrap row" :style>
4
+ <div class="ellipsis qas-toggle-visibility__content">
5
+ <div
6
+ v-if="isVisible"
7
+ class="ellipsis full-width"
8
+ :title="props.text"
9
+ >
10
+ <slot>
11
+ {{ props.text }}
12
+ </slot>
13
+ </div>
14
+
15
+ <q-separator
16
+ v-else
17
+ size="4px"
18
+ />
19
+ </div>
20
+
21
+ <qas-btn
22
+ class="q-ml-sm qas-toggle-visibility__button"
23
+ :icon
24
+ @click.prevent.stop="toggleVisibility"
25
+ />
26
+ </div>
27
+ </div>
28
+ </template>
29
+
30
+ <script setup>
31
+ import { useToggleVisibility } from '../../composables/private'
32
+
33
+ import { uid } from 'quasar'
34
+ import { computed } from 'vue'
35
+
36
+ defineOptions({ name: 'QasToggleVisibility' })
37
+
38
+ const props = defineProps({
39
+ group: {
40
+ type: String,
41
+ default: ''
42
+ },
43
+
44
+ text: {
45
+ type: String,
46
+ default: ''
47
+ },
48
+
49
+ uuid: {
50
+ type: String,
51
+ default: ''
52
+ },
53
+
54
+ width: {
55
+ type: String,
56
+ default: '140px'
57
+ }
58
+ })
59
+
60
+ const {
61
+ isVisible,
62
+ toggleVisibility
63
+ } = useToggleVisibility({ group: props.group, uuid: props.uuid || uid() })
64
+
65
+ const icon = computed(() => isVisible.value ? 'sym_r_visibility' : 'sym_r_visibility_off')
66
+ const style = computed(() => ({ width: props.width }))
67
+ </script>
68
+
69
+ <style lang="scss">
70
+ .qas-toggle-visibility {
71
+ &__content {
72
+ flex-grow: 1;
73
+ }
74
+
75
+ &__button {
76
+ flex-grow: 0;
77
+ }
78
+ }
79
+ </style>
@@ -0,0 +1,30 @@
1
+ type: component
2
+
3
+ meta:
4
+ desc: Componente para ocultar e exibir conteúdo, utilizado para dados sensíveis.
5
+
6
+ props:
7
+ group:
8
+ desc: Propriedade para criar grupos de separação.
9
+ default: ''
10
+ type: String
11
+ examples: ["name", "document", "users"]
12
+
13
+ text:
14
+ desc: Texto a ser oculto/exibido.
15
+ default: ''
16
+ type: String
17
+
18
+ uuid:
19
+ desc: É criado um uuid random para cada componente, para que possa ser feito o controle interno, porém é possível sobrescrever por esta propriedade.
20
+ default: ''
21
+ type: String
22
+
23
+ width:
24
+ desc: Tamanho do conteúdo a ser oculto/exibido.
25
+ default: '140px'
26
+ type: String
27
+
28
+ slots:
29
+ default:
30
+ desc: Slot para inserir conteúdo a ser oculto/exibido.
@@ -1,2 +1,3 @@
1
1
  export { default as useView } from './use-view'
2
2
  export { default as useGenerator } from './use-generator'
3
+ export { default as useToggleVisibility } from './use-toggle-visibility'
@@ -0,0 +1,48 @@
1
+ import { ref, computed } from 'vue'
2
+
3
+ const visibleState = ref({})
4
+
5
+ /**
6
+ * @param {{
7
+ * group?: string,
8
+ * uuid: string
9
+ * }}
10
+ */
11
+ export default function useToggleVisibility ({ group, uuid }) {
12
+ group = group || 'default'
13
+
14
+ visibleState.value[group] = {
15
+ ...visibleState.value[group],
16
+ [uuid]: false
17
+ }
18
+
19
+ const isVisible = computed(() => visibleState.value[group]?.[uuid] || false)
20
+
21
+ function toggleVisibility () {
22
+ const item = visibleState.value[group]
23
+ const lastVisibleItemKey = Object.keys(item).find(key => !!item[key])
24
+
25
+ /**
26
+ * cenário onde esta visível e clicou no mesmo item
27
+ */
28
+ if (visibleState.value[group][uuid]) {
29
+ visibleState.value[group][uuid] = false
30
+ return
31
+ }
32
+
33
+ /**
34
+ * cenário onde tem um item visível e clicou em outro item
35
+ */
36
+ if (lastVisibleItemKey) {
37
+ visibleState.value[group][lastVisibleItemKey] = false
38
+ }
39
+
40
+ visibleState.value[group][uuid] = true
41
+ }
42
+
43
+ return {
44
+ isVisible,
45
+
46
+ toggleVisibility
47
+ }
48
+ }
package/src/vue-plugin.js CHANGED
@@ -64,6 +64,7 @@ import QasTableGenerator from './components/table-generator/QasTableGenerator.vu
64
64
  import QasTabsGenerator from './components/tabs-generator/QasTabsGenerator.vue'
65
65
  import QasTextTruncate from './components/text-truncate/QasTextTruncate.vue'
66
66
  import QasTimeline from './components/timeline/QasTimeline.vue'
67
+ import QasToggleVisibility from './components/toggle-visibility/QasToggleVisibility.vue'
67
68
  import QasTransfer from './components/transfer/QasTransfer.vue'
68
69
  import QasTreeGenerator from './components/tree-generator/QasTreeGenerator.vue'
69
70
  import QasUploader from './components/uploader/QasUploader.vue'
@@ -157,6 +158,7 @@ async function install (app) {
157
158
  app.component('QasTabsGenerator', QasTabsGenerator)
158
159
  app.component('QasTextTruncate', QasTextTruncate)
159
160
  app.component('QasTimeline', QasTimeline)
161
+ app.component('QasToggleVisibility', QasToggleVisibility)
160
162
  app.component('QasTransfer', QasTransfer)
161
163
  app.component('QasTreeGenerator', QasTreeGenerator)
162
164
  app.component('QasUploader', QasUploader)
@@ -252,6 +254,7 @@ export {
252
254
  QasTabsGenerator,
253
255
  QasTextTruncate,
254
256
  QasTimeline,
257
+ QasToggleVisibility,
255
258
  QasTransfer,
256
259
  QasTreeGenerator,
257
260
  QasUploader,