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

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.5",
5
5
  "author": "Bild & Vitta <systemteam@bild.com.br>",
6
6
  "license": "MIT",
7
7
  "main": "dist/asteroid.cjs.min.js",
@@ -1,13 +1,13 @@
1
1
  <template>
2
- <div class="qas-expansion-item" :class="errorClasses">
3
- <qas-box class="qas-expansion-item__box">
2
+ <div ref="expansionItem" class="qas-expansion-item" :class="errorClasses">
3
+ <component :is="component.is" class="qas-expansion-item__box">
4
4
  <q-expansion-item header-class="text-bold q-mt-sm q-pa-none" :label="props.label">
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,7 +43,9 @@
37
43
  </template>
38
44
 
39
45
  <script setup>
40
- import { computed } from 'vue'
46
+ import QasBox from '../box/QasBox.vue'
47
+
48
+ import { computed, provide, inject, onMounted, ref } from 'vue'
41
49
 
42
50
  defineOptions({ name: 'QasExpansionItem' })
43
51
 
@@ -67,17 +75,55 @@ const props = defineProps({
67
75
  }
68
76
  })
69
77
 
70
- const hasError = computed(() => props.error || !!props.errorMessage)
78
+ provide('isExpansionItem', true)
79
+
80
+ // slots
81
+ const slots = defineSlots()
82
+
83
+ // refs
84
+ const expansionItem = ref(null)
85
+ const hasNextSibling = ref(false)
86
+
87
+ onMounted(setHasNextSibling)
88
+
89
+ // constants
90
+ const isNestedExpansionItem = inject('isExpansionItem', false)
91
+ const component = {
92
+ is: isNestedExpansionItem ? 'div' : QasBox
93
+ }
71
94
 
95
+ // computed
96
+ const hasError = computed(() => props.error || !!props.errorMessage)
72
97
  const errorClasses = computed(() => ({ 'qas-expansion-item--error': hasError.value }))
73
98
 
74
99
  const hasGridGenerator = computed(() => !!Object.keys(props.gridGeneratorProps).length)
100
+ const hasBottomSeparator = computed(() => isNestedExpansionItem && hasNextSibling.value)
101
+ const hasHeaderBottom = computed(() => !!slots['header-bottom'])
102
+
103
+ // functions
104
+
105
+ /**
106
+ * Caso o componente esteja dentro de um QasExpansionItem, verifica se existe um próximo irmão
107
+ * para adicionar um separador.
108
+ */
109
+ function setHasNextSibling (value) {
110
+ if (!isNestedExpansionItem) return
111
+
112
+ const hasTextContentSibling = !!expansionItem.value.nextSibling.textContent?.trim?.()
113
+ const hasElementSibling = !!expansionItem.value.nextElementSibling
114
+
115
+ hasNextSibling.value = hasElementSibling || hasTextContentSibling
116
+ }
75
117
  </script>
76
118
 
77
119
  <style lang="scss">
78
120
  .qas-expansion-item {
79
121
  $root: &;
80
122
 
123
+ & + & {
124
+ margin-top: var(--qas-spacing-lg);
125
+ }
126
+
81
127
  &--error {
82
128
  #{$root}__box {
83
129
  border: 2px solid $negative;
@@ -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
 
@@ -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="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,