@bildvitta/quasar-ui-asteroid 2.12.4 → 3.0.0-alpha.1

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.
Files changed (188) hide show
  1. package/dist/api/QasBox.json +16 -0
  2. package/dist/api/QasBreakline.json +32 -0
  3. package/dist/api/QasBtn.json +15 -0
  4. package/dist/api/QasDebugger.json +13 -0
  5. package/dist/asteroid.cjs.css +1 -0
  6. package/dist/asteroid.cjs.js +9154 -0
  7. package/dist/asteroid.cjs.min.js +6 -0
  8. package/dist/asteroid.esm.css +1 -0
  9. package/dist/asteroid.esm.js +9145 -0
  10. package/dist/asteroid.esm.min.js +6 -0
  11. package/dist/asteroid.umd.css +1 -0
  12. package/dist/asteroid.umd.js +9148 -0
  13. package/dist/asteroid.umd.min.js +6 -0
  14. package/dist/vetur/asteroid-attributes.json +30 -0
  15. package/dist/vetur/asteroid-tags.json +29 -0
  16. package/package.json +42 -56
  17. package/src/assets/logo-modular.svg +1 -0
  18. package/src/asteroid.js +1 -0
  19. package/src/components/actions/QasActions.vue +45 -0
  20. package/src/components/actions-menu/QasActionsMenu.vue +8 -19
  21. package/src/components/alert/QasAlert.vue +90 -0
  22. package/src/components/app-bar/QasAppBar.vue +59 -61
  23. package/src/components/app-menu/QasAppMenu.vue +128 -41
  24. package/src/components/avatar/QasAvatar.vue +7 -3
  25. package/src/components/box/QasBox.vue +12 -4
  26. package/src/components/box/QasBox.yml +13 -0
  27. package/src/components/breakline/QasBreakline.vue +37 -0
  28. package/src/components/breakline/QasBreakline.yml +25 -0
  29. package/src/components/btn/QasBtn.vue +27 -24
  30. package/src/components/btn/QasBtn.yml +12 -0
  31. package/src/components/card/QasCard.vue +29 -21
  32. package/src/components/checkbox-group/QasCheckboxGroup.vue +31 -17
  33. package/src/components/copy/QasCopy.vue +22 -11
  34. package/src/components/date-time-input/QasDateTimeInput.vue +16 -26
  35. package/src/components/debugger/QasDebugger.vue +2 -0
  36. package/src/components/debugger/QasDebugger.yml +10 -0
  37. package/src/components/delete/QasDelete.vue +28 -15
  38. package/src/components/dialog/QasDialog.vue +71 -67
  39. package/src/components/dialog-router/QasDialogRouter.vue +12 -4
  40. package/src/components/field/QasField.vue +22 -25
  41. package/src/components/filters/QasFilters.vue +31 -24
  42. package/src/components/form-generator/QasFormGenerator.vue +13 -15
  43. package/src/components/form-view/QasFormView.vue +117 -66
  44. package/src/components/gallery/QasGallery.vue +39 -26
  45. package/src/components/grid-generator/QasGridGenerator.vue +12 -6
  46. package/src/components/index.js +0 -0
  47. package/src/components/input/QasInput.vue +38 -36
  48. package/src/components/label/QasLabel.vue +14 -15
  49. package/src/components/layout/QasLayout.vue +81 -0
  50. package/src/components/list-items/QasListItems.vue +16 -8
  51. package/src/components/list-view/QasListView.vue +31 -28
  52. package/src/components/map/QasMap.vue +15 -25
  53. package/src/components/nested-fields/QasNestedFields.vue +39 -36
  54. package/src/components/numeric-input/QasNumericInput.vue +125 -0
  55. package/src/components/page-header/QasPageHeader.vue +19 -10
  56. package/src/components/password-input/QasPasswordInput.vue +20 -18
  57. package/src/components/password-strength-checker/QasPasswordStrengthChecker.vue +52 -31
  58. package/src/components/profile/QasProfile.vue +14 -12
  59. package/src/components/resizer/QasResizer.vue +1 -1
  60. package/src/components/search-box/QasSearchBox.vue +36 -20
  61. package/src/components/select/QasSelect.vue +43 -44
  62. package/src/components/select-list/QasSelectList.vue +64 -51
  63. package/src/components/signature-pad/QasSignaturePad.vue +57 -41
  64. package/src/components/signature-uploader/QasSignatureUploader.vue +15 -13
  65. package/src/components/single-view/QasSingleView.vue +31 -17
  66. package/src/components/sortable/QasSortable.vue +45 -27
  67. package/src/components/table-generator/QasTableGenerator.vue +95 -22
  68. package/src/components/tabs-generator/QasTabsGenerator.vue +36 -24
  69. package/src/components/text-truncate/QasTextTruncate.vue +25 -17
  70. package/src/components/transfer/QasTransfer.vue +57 -53
  71. package/src/components/uploader/QasUploader.vue +169 -48
  72. package/src/css/background.scss +1 -1
  73. package/src/css/border.scss +7 -6
  74. package/src/css/design-system.scss +0 -43
  75. package/src/css/fonts.scss +2 -28
  76. package/src/css/opacity.scss +0 -4
  77. package/src/css/set-brand.scss +15 -0
  78. package/src/css/transitions.scss +1 -1
  79. package/src/helpers/add-counter-suffix.js +3 -0
  80. package/src/helpers/{base64ToBlob.js → base-64-to-blob.js} +0 -0
  81. package/src/helpers/{constructObject.js → construct-object.js} +0 -0
  82. package/src/helpers/filter-object.js +8 -6
  83. package/src/helpers/filters.js +3 -4
  84. package/src/helpers/get-slot-children-text.js +15 -0
  85. package/src/helpers/{greatestCommonDivisor.js → greatest-common-divisor.js} +0 -0
  86. package/src/helpers/images.js +28 -0
  87. package/src/helpers/index.js +11 -57
  88. package/src/helpers/is-local-development.js +3 -0
  89. package/src/helpers/scroll-on-grap.js +61 -0
  90. package/src/index.cjs.js +1 -0
  91. package/src/index.esm.js +4 -0
  92. package/src/index.scss +18 -20
  93. package/src/index.umd.js +2 -0
  94. package/src/mixins/context.js +1 -1
  95. package/src/mixins/dialog-router.js +17 -0
  96. package/src/mixins/form.js +4 -12
  97. package/src/mixins/generator.js +14 -14
  98. package/src/mixins/index.js +2 -8
  99. package/src/mixins/password.js +73 -11
  100. package/src/mixins/screen.js +8 -6
  101. package/src/mixins/view.js +57 -20
  102. package/src/plugins/Dialog.js +14 -0
  103. package/src/plugins/NotifySuccess.js +3 -3
  104. package/src/plugins/index.js +4 -2
  105. package/src/store/history.js +43 -0
  106. package/src/store/index.js +1 -0
  107. package/src/vue-plugin.js +185 -0
  108. package/.babelrc +0 -12
  109. package/.storybook/main.js +0 -35
  110. package/.storybook/preview.js +0 -26
  111. package/debug.log +0 -1
  112. package/index.js +0 -4
  113. package/jest-setup.js +0 -1
  114. package/jest.config.json +0 -22
  115. package/postcss.config.js +0 -5
  116. package/src/components/Introduction.stories.mdx +0 -12
  117. package/src/components/actions-menu/QasActionsMenu.stories.js +0 -73
  118. package/src/components/app-bar/QasAppBar.stories.js +0 -88
  119. package/src/components/app-menu/QasAppMenu.stories.js +0 -62
  120. package/src/components/apps-menu/QasAppsMenu.spec.js +0 -58
  121. package/src/components/apps-menu/QasAppsMenu.stories.js +0 -54
  122. package/src/components/apps-menu/QasAppsMenu.vue +0 -48
  123. package/src/components/avatar/QasAvatar.spec.js +0 -14
  124. package/src/components/avatar/QasAvatar.stories.js +0 -52
  125. package/src/components/box/QasBox.spec.js +0 -18
  126. package/src/components/box/QasBox.stories.js +0 -35
  127. package/src/components/break-line/QasBreakLine.stories.js +0 -57
  128. package/src/components/break-line/QasBreakLine.vue +0 -52
  129. package/src/components/btn/QasBtn.stories.js +0 -45
  130. package/src/components/btn-actions/QasBtnActions.stories.js +0 -77
  131. package/src/components/btn-actions/QasBtnActions.vue +0 -54
  132. package/src/components/card/QasCard.stories.js +0 -126
  133. package/src/components/checkbox-group/QasCheckboxGroup.stories.js +0 -59
  134. package/src/components/copy/QasCopy.stories.js +0 -41
  135. package/src/components/date-time-input/QasDateTimeInput.stories.js +0 -67
  136. package/src/components/debugger/QasDebugger.stories.js +0 -33
  137. package/src/components/decimal-input/QasDecimalInput.stories.js +0 -82
  138. package/src/components/decimal-input/QasDecimalInput.vue +0 -92
  139. package/src/components/delete/QasDelete.stories.js +0 -80
  140. package/src/components/dialog/QasDialog.stories.js +0 -139
  141. package/src/components/dialog-router/QasDialogRouter.stories.js +0 -38
  142. package/src/components/field/QasField.stories.js +0 -181
  143. package/src/components/filters/QasFilters.stories.js +0 -121
  144. package/src/components/form-generator/QasFormGenerator.stories.js +0 -115
  145. package/src/components/form-view/QasFormView.stories.js +0 -236
  146. package/src/components/gallery/QasGallery.stories.js +0 -91
  147. package/src/components/grid-generator/QasGridGenerator.stories.js +0 -138
  148. package/src/components/input/QasInput.stories.js +0 -78
  149. package/src/components/label/QasLabel.stories.js +0 -60
  150. package/src/components/list-items/QasListItems.stories.js +0 -130
  151. package/src/components/list-view/QasListView.stories.js +0 -168
  152. package/src/components/map/QasMap.stories.js +0 -75
  153. package/src/components/nested-fields/QasNestedFields.stories.js +0 -255
  154. package/src/components/page-header/QasPageHeader.stories.js +0 -61
  155. package/src/components/password-input/QasPasswordInput.stories.js +0 -76
  156. package/src/components/password-strength-checker/QasPasswordStrengthChecker.stories.js +0 -54
  157. package/src/components/profile/QasProfile.stories.js +0 -131
  158. package/src/components/resizer/QasResizer.stories.js +0 -43
  159. package/src/components/search-box/QasSearchBox.stories.js +0 -111
  160. package/src/components/select/QasSelect.stories.js +0 -113
  161. package/src/components/select-list/QasSelectList.stories.js +0 -153
  162. package/src/components/signature-pad/QasSignaturePad.stories.js +0 -51
  163. package/src/components/signature-uploader/QasSignatureUploader.stories.js +0 -69
  164. package/src/components/single-view/QasSingleView.stories.js +0 -130
  165. package/src/components/sortable/QasSortable.stories.js +0 -80
  166. package/src/components/table-generator/QasTableGenerator.stories.js +0 -116
  167. package/src/components/tabs-generator/QasTabsGenerator.stories.js +0 -145
  168. package/src/components/text-truncate/QasTextTruncate.stories.js +0 -55
  169. package/src/components/tip/QasTip.stories.js +0 -57
  170. package/src/components/tip/QasTip.vue +0 -68
  171. package/src/components/tooltip/QasTooltip.stories.js +0 -63
  172. package/src/components/tooltip/QasTooltip.vue +0 -81
  173. package/src/components/transfer/QasTransfer.stories.js +0 -118
  174. package/src/components/uploader/QasCustomUploader.vue +0 -121
  175. package/src/components/uploader/QasUploader.stories.js +0 -139
  176. package/src/directives/Test.js +0 -13
  177. package/src/helpers/historyHandler.js +0 -52
  178. package/src/helpers/label.js +0 -3
  179. package/src/index.js +0 -245
  180. package/src/mixins/map-markers.js +0 -26
  181. package/src/mixins/unsaved-changes.js +0 -24
  182. package/src/mixins/uploader.js +0 -30
  183. package/src/mocks/json/user.json +0 -27
  184. package/src/mocks/json/users-new.json +0 -23
  185. package/src/mocks/json/users.json +0 -97
  186. package/src/mocks/storeModule.js +0 -71
  187. package/src/pages/Forbidden.vue +0 -6
  188. package/src/pages/NotFound.vue +0 -6
@@ -1,11 +1,5 @@
1
1
  <template>
2
- <q-select v-model="model" v-bind="attributes" v-on="listeners" @filter="filterOptions">
3
- <slot v-for="(slot, key) in $slots" :slot="key" :name="key" />
4
-
5
- <template v-for="(slot, key) in $scopedSlots" :slot="key" slot-scope="scope">
6
- <slot :name="key" v-bind="scope" />
7
- </template>
8
-
2
+ <q-select v-model="model" v-bind="attributes" @filter="filterOptions">
9
3
  <template #append>
10
4
  <slot name="append">
11
5
  <q-icon v-if="searchable" name="o_search" />
@@ -21,11 +15,19 @@
21
15
  </q-item>
22
16
  </slot>
23
17
  </template>
18
+
19
+ <template v-for="(_, name) in $slots" #[name]="context">
20
+ <slot :name="name" v-bind="context || {}" />
21
+ </template>
24
22
  </q-select>
25
23
  </template>
26
24
 
27
25
  <script>
26
+ import Fuse from 'fuse.js'
27
+
28
28
  export default {
29
+ name: 'QasSelect',
30
+
29
31
  props: {
30
32
  fuseOptions: {
31
33
  default: () => ({}),
@@ -37,31 +39,33 @@ export default {
37
39
  type: String
38
40
  },
39
41
 
40
- options: {
41
- default: () => [],
42
- type: Array
43
- },
44
-
45
- value: {
42
+ modelValue: {
46
43
  default: () => [],
47
44
  type: [Array, Object, String, Number]
48
45
  },
49
46
 
50
- valueKey: {
51
- default: '',
52
- type: String
53
- },
54
-
55
47
  noOptionLabel: {
56
48
  default: 'Nenhum resultado foi encontrado.',
57
49
  type: String
58
50
  },
59
51
 
52
+ options: {
53
+ default: () => [],
54
+ type: Array
55
+ },
56
+
60
57
  searchable: {
61
58
  type: Boolean
59
+ },
60
+
61
+ valueKey: {
62
+ default: '',
63
+ type: String
62
64
  }
63
65
  },
64
66
 
67
+ emits: ['update:modelValue'],
68
+
65
69
  data () {
66
70
  return {
67
71
  filteredOptions: [],
@@ -70,20 +74,18 @@ export default {
70
74
  },
71
75
 
72
76
  computed: {
73
- model: {
74
- get () {
75
- return this.value
76
- },
77
-
78
- set (value) {
79
- this.$emit('input', value)
80
- }
81
- },
77
+ attributes () {
78
+ return {
79
+ clearable: this.searchable,
80
+ emitValue: true,
81
+ mapOptions: true,
82
+ outlined: true,
82
83
 
83
- listeners () {
84
- const { input, ...events } = this.$listeners
84
+ ...this.$attrs,
85
85
 
86
- return events
86
+ options: this.filteredOptions,
87
+ useInput: this.searchable
88
+ }
87
89
  },
88
90
 
89
91
  defaultFuseOptions () {
@@ -110,19 +112,13 @@ export default {
110
112
  return this.options.map(item => this.renameKey(item))
111
113
  },
112
114
 
113
- isMultiple () {
114
- return this.$attrs.multiple || this.$attrs.multiple === ''
115
- },
115
+ model: {
116
+ get () {
117
+ return this.modelValue
118
+ },
116
119
 
117
- attributes () {
118
- return {
119
- emitValue: true,
120
- mapOptions: true,
121
- outlined: true,
122
- clearable: this.searchable,
123
- ...this.$attrs,
124
- options: this.filteredOptions,
125
- useInput: this.searchable
120
+ set (value) {
121
+ this.$emit('update:modelValue', value)
126
122
  }
127
123
  }
128
124
  },
@@ -140,13 +136,13 @@ export default {
140
136
 
141
137
  this.filteredOptions = this.formattedResult
142
138
  },
139
+
143
140
  immediate: true
144
141
  }
145
142
  },
146
143
 
147
144
  async created () {
148
145
  if (this.searchable) {
149
- const Fuse = (await import('fuse.js')).default
150
146
  this.fuse = new Fuse(this.options, this.defaultFuseOptions)
151
147
  }
152
148
  },
@@ -166,7 +162,10 @@ export default {
166
162
  },
167
163
 
168
164
  renameKey (item) {
169
- const mapKeys = { label: this.labelKey, value: this.valueKey }
165
+ const mapKeys = {
166
+ label: this.labelKey,
167
+ value: this.valueKey
168
+ }
170
169
 
171
170
  for (const newKey in mapKeys) {
172
171
  if (!item.hasOwnProperty.call(newKey)) {
@@ -1,9 +1,9 @@
1
1
  <template>
2
- <qas-search-box v-bind="$attrs" class="q-pa-md" :fuse-options="fuseOptions" :list="sortedOptions">
2
+ <qas-search-box class="q-pa-md" :fuse-options="fuseOptions" :list="sortedList">
3
3
  <template #default="{ results }">
4
4
  <q-list separator>
5
- <q-item v-for="(result, index) in results" :key="index">
6
- <slot name="item" v-bind="self">
5
+ <q-item v-for="result in results" :key="result.value">
6
+ <slot name="item" v-bind="slotData">
7
7
  <slot name="item-section" :result="result">
8
8
  <q-item-section class="items-start text-bold">
9
9
  <div :class="labelClass" @click="redirectRoute(result)">{{ result.label }}</div>
@@ -11,8 +11,8 @@
11
11
  </slot>
12
12
 
13
13
  <q-item-section avatar>
14
- <slot name="item-action" v-bind="self">
15
- <qas-btn hide-mobile-label v-bind="setButtonProps(result)" size="sm" @click="handleClick(result)" />
14
+ <slot name="item-action" v-bind="slotData">
15
+ <qas-btn v-bind="getButtonProps(result)" @click="handleClick(result)" />
16
16
  </slot>
17
17
  </q-item-section>
18
18
  </slot>
@@ -23,17 +23,22 @@
23
23
  </template>
24
24
 
25
25
  <script>
26
- import { sortBy } from 'lodash'
26
+ import { sortBy } from 'lodash-es'
27
+ import { screenMixin } from '../../mixins'
27
28
 
28
- import QasBtn from '../btn/QasBtn'
29
- import QasSearchBox from '../search-box/QasSearchBox'
29
+ import QasBtn from '../btn/QasBtn.vue'
30
+ import QasSearchBox from '../search-box/QasSearchBox.vue'
30
31
 
31
32
  export default {
33
+ name: 'QasSelectList',
34
+
32
35
  components: {
33
36
  QasBtn,
34
37
  QasSearchBox
35
38
  },
36
39
 
40
+ mixins: [screenMixin],
41
+
37
42
  props: {
38
43
  deleteOnly: {
39
44
  type: Boolean
@@ -44,40 +49,41 @@ export default {
44
49
  type: Object
45
50
  },
46
51
 
47
- options: {
52
+ list: {
48
53
  default: () => [],
49
54
  type: Array
50
55
  },
51
56
 
57
+ modelValue: {
58
+ type: Array,
59
+ default: () => []
60
+ },
61
+
52
62
  to: {
53
63
  default: () => ({}),
54
64
  type: Object
55
65
  },
56
66
 
57
67
  toIdentifier: {
58
- type: String,
59
- default: 'value'
60
- },
61
-
62
- value: {
63
- type: Array,
64
- default: () => []
68
+ default: 'value',
69
+ type: String
65
70
  }
66
71
  },
67
72
 
73
+ emits: [
74
+ 'added',
75
+ 'update:modelValue',
76
+ 'removed'
77
+ ],
78
+
68
79
  data () {
69
80
  return {
70
- sortedOptions: [],
81
+ sortedList: [],
71
82
  values: []
72
83
  }
73
84
  },
74
85
 
75
86
  computed: {
76
- // TODO: parar de usar "mobile".
77
- isMobile () {
78
- return this.$q.screen.xs
79
- },
80
-
81
87
  isRedirectEnabled () {
82
88
  return Object.keys(this.to).length
83
89
  },
@@ -86,29 +92,34 @@ export default {
86
92
  return this.isRedirectEnabled ? 'cursor-pointer' : ''
87
93
  },
88
94
 
89
- self () {
90
- return this
95
+ slotData () {
96
+ return {
97
+ add: this.add,
98
+ handleClick: this.handleClick,
99
+ remove: this.remove,
100
+ updateModel: this.updateModel
101
+ }
91
102
  }
92
103
  },
93
104
 
94
105
  watch: {
95
- options: {
106
+ list: {
96
107
  handler (value) {
97
- if (!this.sortedOptions.length) {
98
- this.sortedOptions = value
108
+ if (!this.sortedList.length) {
109
+ this.sortedList = value
99
110
  }
100
111
  },
101
112
 
102
113
  immediate: true
103
114
  },
104
115
 
105
- value (value) {
116
+ modelValue (value) {
106
117
  this.values = [...value]
107
118
  }
108
119
  },
109
120
 
110
121
  created () {
111
- this.values = [...this.value]
122
+ this.values = [...this.modelValue]
112
123
 
113
124
  this.handleOptions()
114
125
  },
@@ -121,18 +132,31 @@ export default {
121
132
  this.$emit('added', item)
122
133
  },
123
134
 
135
+ getButtonProps ({ value }) {
136
+ const isSelected = this.values.includes(value)
137
+
138
+ return {
139
+ dense: this.mx_isSmall,
140
+ hideLabelOnSmallScreen: true,
141
+ icon: !this.mx_isSmall ? undefined : isSelected ? 'o_close' : 'o_add',
142
+ label: isSelected ? 'Remover' : 'Adicionar',
143
+ outline: isSelected,
144
+ size: 'sm'
145
+ }
146
+ },
147
+
124
148
  handleClick (item) {
125
149
  return this.values.includes(item.value) ? this.remove(item) : this.add(item)
126
150
  },
127
151
 
128
152
  handleOptions () {
129
- if (this.value.length) {
130
- return this.sortOptions()
153
+ if (this.modelValue.length) {
154
+ return this.sortList()
131
155
  }
132
156
 
133
- const unwatch = this.$watch('value', value => {
134
- if (!this.sortedOptions.length) {
135
- this.sortOptions()
157
+ const unwatch = this.$watch('modelValue', () => {
158
+ if (!this.sortedList.length) {
159
+ this.sortList()
136
160
  unwatch()
137
161
  }
138
162
  })
@@ -154,25 +178,14 @@ export default {
154
178
  this.$emit('removed', item, index)
155
179
  },
156
180
 
157
- setButtonProps ({ value }) {
158
- const isSelected = this.values.includes(value)
159
-
160
- return {
161
- dense: this.isMobile,
162
- icon: !this.isMobile ? undefined : isSelected ? 'o_close' : 'o_add',
163
- label: isSelected ? 'Remover' : 'Adicionar',
164
- outline: isSelected
165
- }
166
- },
167
-
168
- sortOptions () {
169
- this.sortedOptions = this.deleteOnly
170
- ? this.options.filter(option => this.value.includes(option.value))
171
- : sortBy(this.options, option => !this.value.includes(option.value))
181
+ sortList () {
182
+ this.sortedList = this.deleteOnly
183
+ ? this.options.filter(option => this.modelValue.includes(option.value))
184
+ : sortBy(this.options, option => !this.modelValue.includes(option.value))
172
185
  },
173
186
 
174
- updateModel () {
175
- this.$emit('input', this.values)
187
+ updateModel (model) {
188
+ this.$emit('update:modelValue', model || this.values)
176
189
  }
177
190
  }
178
191
  }
@@ -1,25 +1,27 @@
1
1
  <template>
2
2
  <div ref="signatureContainer" class="qas-signature-pad relative-position">
3
3
  <canvas :id="canvasId" :ref="$attrs.ref" class="qas-signature-pad__canvas rounded-borders vertical-bottom" :height="height" />
4
- <q-btn v-if="!isEmpty" class="absolute q-mb-sm q-mr-sm qas-signature-pad__clear" color="primary" dense icon="o_delete" round @click="clearSignature" />
4
+ <qas-btn v-if="!empty" class="absolute-bottom-right q-mb-sm q-mr-sm" color="primary" dense icon="o_delete" round @click="clearSignature" />
5
5
  </div>
6
6
  </template>
7
7
 
8
8
  <script>
9
- import SignaturePad from 'signature_pad'
10
9
  import { uid } from 'quasar'
11
- import { isEqual } from 'lodash'
10
+ import { isEqual } from 'lodash-es'
11
+ import SignaturePad from 'signature_pad'
12
12
 
13
+ import QasBtn from '../btn/QasBtn.vue'
13
14
  export default {
14
- props: {
15
- options: {
16
- default: () => ({}),
17
- type: Object
18
- },
15
+ name: 'QasSignaturePad',
19
16
 
20
- type: {
21
- default: 'image/png',
22
- type: String
17
+ components: {
18
+ QasBtn
19
+ },
20
+
21
+ props: {
22
+ empty: {
23
+ type: Boolean,
24
+ default: true
23
25
  },
24
26
 
25
27
  height: {
@@ -27,62 +29,81 @@ export default {
27
29
  type: String
28
30
  },
29
31
 
30
- isEmpty: {
31
- type: Boolean,
32
- default: true
32
+ signatureOptions: {
33
+ default: () => ({}),
34
+ type: Object
35
+ },
36
+
37
+ type: {
38
+ default: 'image/png',
39
+ type: String
33
40
  }
34
41
  },
35
42
 
43
+ emits: ['update:empty'],
44
+
45
+ expose: ['clearSignature', 'saveSignature', 'updateEmptyModel'],
46
+
36
47
  data () {
37
48
  return {
49
+ canvasId: uid(),
50
+ hasEndStrokeEvent: false,
38
51
  signaturePad: null,
39
- canvasId: uid()
52
+ SignaturePad: null
40
53
  }
41
54
  },
42
55
 
43
56
  watch: {
44
- options (newValue, oldValue) {
57
+ async signatureOptions (newValue, oldValue) {
45
58
  if (isEqual(newValue, oldValue)) return
46
59
 
47
- this.setupSignaturePad()
48
- this.isEmptyEmitter()
60
+ await this.setupSignaturePad()
61
+ this.updateEmptyModel()
49
62
  }
50
63
  },
51
64
 
52
- destroyed () {
53
- window.removeEventListener('resize', this.setCanvasWidth)
54
- },
55
-
56
- mounted () {
65
+ async mounted () {
57
66
  window.addEventListener('resize', this.setCanvasWidth)
58
67
  this.setCanvasWidth()
68
+
59
69
  this.setupSignaturePad()
60
70
  },
61
71
 
62
- methods: {
63
- setupSignaturePad () {
64
- this.signaturePad = new SignaturePad(document.getElementById(this.canvasId), this.options)
65
- this.signaturePad.onEnd = this.isEmptyEmitter
66
- this.clearSignature()
67
- },
68
-
69
- saveSignature () {
70
- return this.signaturePad.toDataURL(this.type)
71
- },
72
+ unmounted () {
73
+ window.removeEventListener('resize', this.setCanvasWidth)
74
+ this.signaturePad.off()
75
+ },
72
76
 
77
+ methods: {
73
78
  clearSignature () {
74
79
  this.signaturePad.clear()
75
- this.isEmptyEmitter()
80
+ this.updateEmptyModel()
76
81
  },
77
82
 
78
- isEmptyEmitter () {
79
- this.$emit('update:isEmpty', this.signaturePad.isEmpty())
83
+ saveSignature () {
84
+ return this.signaturePad.toDataURL(this.type)
80
85
  },
81
86
 
82
87
  setCanvasWidth () {
83
88
  const signatureContainer = this.$refs.signatureContainer
84
89
  const canvasElement = signatureContainer.querySelector('canvas')
85
90
  canvasElement.setAttribute('width', signatureContainer.offsetWidth)
91
+ },
92
+
93
+ setupSignaturePad () {
94
+ const canvasElement = document.getElementById(this.canvasId)
95
+ this.signaturePad = new SignaturePad(canvasElement, this.signatureOptions)
96
+
97
+ if (!this.hasEndStrokeEvent) {
98
+ this.signaturePad.addEventListener('endStroke', this.updateEmptyModel)
99
+ }
100
+
101
+ this.hasEndStrokeEvent = true
102
+ this.clearSignature()
103
+ },
104
+
105
+ updateEmptyModel () {
106
+ this.$emit('update:empty', this.signaturePad.isEmpty())
86
107
  }
87
108
  }
88
109
  }
@@ -90,11 +111,6 @@ export default {
90
111
 
91
112
  <style lang="scss">
92
113
  .qas-signature-pad {
93
- &__clear {
94
- bottom: 0;
95
- right: 0;
96
- }
97
-
98
114
  &__canvas {
99
115
  border: 1px solid $grey-3;
100
116
  }
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <div>
3
- <qas-uploader ref="uploader" v-model="uploader" :label="uploadLabel" :readonly="readonly" v-bind="$attrs" :use-resize="false">
3
+ <qas-uploader ref="uploader" v-model="model" :label="uploadLabel" :readonly="readonly" :use-resize="false" v-bind="$attrs">
4
4
  <template #header="{ scope }">
5
- <div class="cursor-pointer flex flex-center full-width justify-between no-border no-wrap q-gutter-xs text-white transparent" :class="headerClasses" @click="openDialog">
5
+ <div class="cursor-pointer flex flex-center full-width justify-between no-border no-wrap q-gutter-xs text-white transparent" :class="headerClass" @click="openDialog">
6
6
  <div class="col column items-start justify-center">
7
- <div v-if="scope.label" class="q-uploader__title">{{ scope.label }}</div>
7
+ <div v-if="uploadLabel" class="q-uploader__title">{{ uploadLabel }}</div>
8
8
  </div>
9
9
 
10
10
  <q-btn v-if="!readonly" dense flat icon="o_add" round @click="openDialog" />
@@ -21,7 +21,7 @@
21
21
  </template>
22
22
 
23
23
  <template #description>
24
- <qas-signature-pad ref="signaturePadModal" height="250" :is-empty.sync="isEmpty" />
24
+ <qas-signature-pad ref="signaturePadModal" v-model:empty="isEmpty" height="250" />
25
25
  </template>
26
26
 
27
27
  <template #actions>
@@ -40,6 +40,8 @@ import { base64ToBlob } from '../../helpers'
40
40
  import { NotifyError } from '../../plugins'
41
41
 
42
42
  export default {
43
+ name: 'QasSignatureUploader',
44
+
43
45
  components: {
44
46
  QasDialog,
45
47
  QasUploader,
@@ -57,7 +59,7 @@ export default {
57
59
  type: String
58
60
  },
59
61
 
60
- value: {
62
+ modelValue: {
61
63
  default: '',
62
64
  type: String
63
65
  },
@@ -72,6 +74,8 @@ export default {
72
74
  }
73
75
  },
74
76
 
77
+ emits: ['update:modelValue'],
78
+
75
79
  data () {
76
80
  return {
77
81
  isOpenedDialog: false,
@@ -81,24 +85,22 @@ export default {
81
85
  },
82
86
 
83
87
  computed: {
84
- uploader: {
88
+ model: {
85
89
  get () {
86
- return this.value
90
+ return this.modelValue
87
91
  },
88
92
 
89
93
  set (value) {
90
- this.$emit('input', value)
94
+ this.$emit('update:modelValue', value)
91
95
  }
92
96
  },
93
97
 
94
- headerClasses () {
98
+ headerClass () {
95
99
  return `q-pa-${this.readonly ? 'md' : 'sm'}`
96
100
  }
97
101
  },
98
102
 
99
103
  methods: {
100
- base64ToBlob,
101
-
102
104
  NotifyError,
103
105
 
104
106
  openDialog () {
@@ -120,7 +122,7 @@ export default {
120
122
 
121
123
  removeSignature () {
122
124
  this.$refs.buttonCleanFiles.$el.click()
123
- this.$emit('input')
125
+ this.$emit('update:modelValue')
124
126
  },
125
127
 
126
128
  upload (scope) {
@@ -131,7 +133,7 @@ export default {
131
133
  const file = new File([blob], `${fileName}.${extension}`, { type: this.type })
132
134
 
133
135
  scope.addFiles([file])
134
- } catch (error) {
136
+ } catch {
135
137
  NotifyError('Ops! Erro ao enviar sua assinatura.')
136
138
  }
137
139
  }