renusify 2.5.2 → 3.0.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.
Files changed (212) hide show
  1. package/components/app/index.vue +74 -22
  2. package/components/app/toast/index.vue +76 -71
  3. package/components/app/toast/toast.vue +62 -44
  4. package/components/avatar/index.vue +208 -84
  5. package/components/button/buttonConfirm.vue +53 -26
  6. package/components/button/buttonGroup.js +0 -2
  7. package/components/button/buttonGroup.vue +310 -62
  8. package/components/button/index.vue +584 -100
  9. package/components/calendar/index.js +0 -2
  10. package/components/calendar/index.vue +326 -262
  11. package/components/calendar/month.vue +64 -55
  12. package/components/calendar/year.vue +30 -25
  13. package/components/card/index.vue +139 -59
  14. package/components/codeEditor/highlightCss.vue +38 -39
  15. package/components/codeEditor/highlightHtml.vue +64 -64
  16. package/components/codeEditor/highlightJs.vue +37 -38
  17. package/components/codeEditor/index.vue +129 -79
  18. package/components/codeEditor/run.vue +225 -39
  19. package/components/codeEditor/useCodeFormatter.js +150 -0
  20. package/components/confirm/index.vue +139 -80
  21. package/components/container/col.vue +5 -4
  22. package/components/container/divider.vue +28 -19
  23. package/components/container/index.vue +34 -15
  24. package/components/container/row.vue +26 -9
  25. package/components/container/spacer.vue +2 -4
  26. package/components/container/style.scss +3 -0
  27. package/components/content/index.vue +49 -32
  28. package/components/cropper/index.vue +401 -244
  29. package/components/float/index.vue +542 -415
  30. package/components/form/addressInput/index.vue +184 -109
  31. package/components/form/camInput/index.vue +370 -244
  32. package/components/form/checkInput/index.vue +138 -71
  33. package/components/form/checkboxInput/index.vue +87 -47
  34. package/components/form/colorInput/Alpha.vue +81 -83
  35. package/components/form/colorInput/Hue.vue +91 -68
  36. package/components/form/colorInput/Preview.vue +43 -47
  37. package/components/form/colorInput/Saturation.vue +101 -86
  38. package/components/form/colorInput/index.vue +71 -39
  39. package/components/form/colorInput/picker.vue +111 -106
  40. package/components/form/colorInput/useColor.js +153 -0
  41. package/components/form/dateInput/index.vue +691 -356
  42. package/components/form/dateInput/month.vue +63 -54
  43. package/components/form/dateInput/year.vue +35 -25
  44. package/components/form/fileInput/index.js +0 -1
  45. package/components/form/fileInput/index.vue +263 -106
  46. package/components/form/fileInput/single.vue +323 -164
  47. package/components/form/groupInput/index.vue +199 -101
  48. package/components/form/index.vue +189 -83
  49. package/components/form/input/index.vue +416 -377
  50. package/components/form/jsonInput/JsonView.vue +54 -56
  51. package/components/form/jsonInput/index.vue +247 -165
  52. package/components/form/maskInput/index.vue +252 -132
  53. package/components/form/numberInput/index.js +0 -1
  54. package/components/form/numberInput/index.vue +226 -117
  55. package/components/form/passwordInput/index.js +2 -1
  56. package/components/form/passwordInput/index.vue +269 -102
  57. package/components/form/radioInput/index.vue +143 -72
  58. package/components/form/rangeInput/index.vue +280 -167
  59. package/components/form/ratingInput/index.vue +57 -57
  60. package/components/form/selectInput/index.js +1 -3
  61. package/components/form/selectInput/index.vue +584 -296
  62. package/components/form/switchInput/index.vue +73 -59
  63. package/components/form/telInput/index.js +0 -1
  64. package/components/form/telInput/index.vue +238 -135
  65. package/components/form/textArea/index.vue +72 -35
  66. package/components/form/textEditor/index.vue +739 -0
  67. package/components/form/{text-editor → textEditor}/style.scss +8 -16
  68. package/components/form/textInput/index.vue +54 -32
  69. package/components/form/timeInput/index.vue +82 -55
  70. package/components/form/timeInput/range.vue +115 -94
  71. package/components/form/timeInput/timepicker.vue +382 -449
  72. package/components/form/uniqueInput/index.vue +105 -48
  73. package/components/form/unitInput/index.vue +139 -84
  74. package/components/formCreator/index.js +0 -1
  75. package/components/formCreator/index.vue +314 -148
  76. package/components/highlight/index.vue +41 -25
  77. package/components/highlight/style.scss +2 -2
  78. package/components/highlight/{mixin.js → useHighlight.js} +181 -160
  79. package/components/icon/index.vue +79 -33
  80. package/components/img/index.vue +249 -147
  81. package/components/img/preview.vue +180 -198
  82. package/components/img/svgImg.vue +42 -39
  83. package/components/index.js +5 -20
  84. package/components/infinite/index.js +1 -2
  85. package/components/infinite/index.vue +248 -66
  86. package/components/map/index.vue +428 -261
  87. package/components/map/route.vue +794 -487
  88. package/components/map/select.vue +118 -58
  89. package/components/menu/index.vue +201 -91
  90. package/components/meta/meta.js +26 -3
  91. package/components/modal/index.vue +382 -156
  92. package/components/notify/index.vue +204 -86
  93. package/components/notify/notification.vue +38 -55
  94. package/components/progress/circle.vue +189 -70
  95. package/components/progress/line.vue +266 -46
  96. package/components/searchBox/index.js +1 -3
  97. package/components/searchBox/index.vue +194 -101
  98. package/components/skeleton/index.vue +45 -20
  99. package/components/slider/index.vue +318 -156
  100. package/components/swiper/index.vue +254 -106
  101. package/components/table/crud/footer.vue +77 -53
  102. package/components/table/crud/header.vue +71 -72
  103. package/components/table/crud/index.vue +629 -399
  104. package/components/table/index.vue +721 -278
  105. package/components/timeAgo/index.vue +145 -96
  106. package/components/tour/index.vue +338 -235
  107. package/components/tree/index.vue +235 -89
  108. package/components/tree/tree-element.vue +106 -106
  109. package/directive/animate/index.js +77 -0
  110. package/directive/clickOutSide/index.js +98 -0
  111. package/directive/drag/index.js +153 -0
  112. package/directive/index.js +11 -13
  113. package/directive/intersect/index.js +263 -0
  114. package/directive/mask/index.js +67 -0
  115. package/directive/parallax/index.js +78 -0
  116. package/directive/ripple/index.js +14 -0
  117. package/directive/scroll/index.js +244 -0
  118. package/directive/sortable/index.js +274 -0
  119. package/directive/title/index.js +75 -0
  120. package/directive/touch/index.js +268 -0
  121. package/index.js +10 -8
  122. package/package.json +5 -2
  123. package/plugins/validation/Validate.js +88 -79
  124. package/scripts/generate-docs.mjs +226 -0
  125. package/scripts/menu.mjs +240 -0
  126. package/scripts/parser.mjs +1086 -0
  127. package/style/_index.scss +7 -0
  128. package/style/app.scss +13 -65
  129. package/style/colors.scss +5 -22
  130. package/style/functions/index.scss +8 -0
  131. package/style/mixins/index.scss +17 -5
  132. package/style/variables/base.scss +154 -175
  133. package/style/variables/color.scss +0 -12
  134. package/style/variables/utilities.scss +0 -180
  135. package/tools/helper.js +0 -8
  136. package/tools/icons.js +6 -1
  137. package/tools/root.js +71 -0
  138. package/components/app/style.scss +0 -41
  139. package/components/app/toast/style.scss +0 -20
  140. package/components/avatar/style.scss +0 -32
  141. package/components/bar/bottomNav.js +0 -1
  142. package/components/bar/bottomNav.vue +0 -28
  143. package/components/bar/bottomNavigationCircle.js +0 -2
  144. package/components/bar/bottomNavigationCircle.vue +0 -99
  145. package/components/bar/scss/bottomNav.scss +0 -67
  146. package/components/bar/scss/toolbar.scss +0 -174
  147. package/components/bar/toolbar/index.js +0 -8
  148. package/components/bar/toolbar/index.vue +0 -35
  149. package/components/bar/toolbar/laptop.vue +0 -33
  150. package/components/bar/toolbar/menuChilds.vue +0 -41
  151. package/components/bar/toolbar/menuLaptop.vue +0 -41
  152. package/components/bar/toolbar/menuMob.vue +0 -39
  153. package/components/bar/toolbar/mixin.js +0 -43
  154. package/components/bar/toolbar/mobile.vue +0 -34
  155. package/components/breadcrumb/bredcrumbItem.vue +0 -39
  156. package/components/breadcrumb/index.js +0 -3
  157. package/components/breadcrumb/index.vue +0 -71
  158. package/components/breadcrumb/style.scss +0 -51
  159. package/components/button/style.scss +0 -411
  160. package/components/card/style.scss +0 -86
  161. package/components/chart/chart.js +0 -1
  162. package/components/chart/chart.vue +0 -69
  163. package/components/chart/worldMap.js +0 -2
  164. package/components/chart/worldMap.vue +0 -1112
  165. package/components/chat/MessageList.vue +0 -163
  166. package/components/chat/chatInput.vue +0 -150
  167. package/components/chat/chatMsg.vue +0 -276
  168. package/components/chat/index.js +0 -11
  169. package/components/chat/index.vue +0 -113
  170. package/components/chip/index.js +0 -3
  171. package/components/chip/index.vue +0 -77
  172. package/components/chip/style.scss +0 -199
  173. package/components/codeEditor/mixin.js +0 -145
  174. package/components/countdown/index.js +0 -1
  175. package/components/countdown/index.vue +0 -105
  176. package/components/form/colorInput/mixin.js +0 -132
  177. package/components/form/fileInput/file.js +0 -148
  178. package/components/form/telInput/assets/flags.png +0 -0
  179. package/components/form/telInput/assets/flags@2x.png +0 -0
  180. package/components/form/text-editor/index.vue +0 -705
  181. package/components/icon/style.scss +0 -17
  182. package/components/infinite/div.js +0 -6
  183. package/components/infinite/div.vue +0 -193
  184. package/components/infinite/page.js +0 -3
  185. package/components/infinite/page.vue +0 -105
  186. package/components/list/index.js +0 -3
  187. package/components/list/index.vue +0 -122
  188. package/components/list/style.scss +0 -66
  189. package/components/message/index.js +0 -4
  190. package/components/message/index.vue +0 -40
  191. package/components/modal/style.scss +0 -146
  192. package/components/nestable/NestableItem.vue +0 -307
  193. package/components/nestable/editable.js +0 -44
  194. package/components/nestable/index.js +0 -1
  195. package/components/nestable/index.vue +0 -226
  196. package/components/nestable/methods.js +0 -416
  197. package/components/progress/style.scss +0 -229
  198. package/components/table/style.scss +0 -338
  199. package/components/tabs/index.js +0 -3
  200. package/components/tabs/index.vue +0 -151
  201. package/components/timeline/index.js +0 -6
  202. package/components/timeline/index.vue +0 -76
  203. package/directive/resize/index.js +0 -30
  204. package/directive/skeleton/index.js +0 -27
  205. package/directive/skeleton/style.scss +0 -37
  206. package/plugins/request/Request.js +0 -68
  207. package/style/animation.scss +0 -94
  208. package/style/style.scss +0 -8
  209. package/tools/rootable.js +0 -75
  210. /package/components/form/{text-editor → textEditor}/index.js +0 -0
  211. /package/components/form/{text-editor → textEditor}/preview.js +0 -0
  212. /package/components/form/{text-editor → textEditor}/preview.vue +0 -0
@@ -20,8 +20,9 @@
20
20
  :timeout="item.timeout"
21
21
  :width="item.width"
22
22
  @hide="hideChild(item.id,item.on_close)"
23
- @click.prevent="handle(item.on_click)">
24
-
23
+ @click.prevent="handleClick(item.on_click)">
24
+ <!-- Default slot for custom notification content -->
25
+ <!-- provide data prop. The notification item object -->
25
26
  <slot :data="item">
26
27
  {{ item }}
27
28
  </slot>
@@ -29,108 +30,215 @@
29
30
  </notification>
30
31
  </div>
31
32
  </template>
32
- <script>
33
- import {defineAsyncComponent} from 'vue'
33
+ <script setup>
34
+ import {ref, onUnmounted, inject} from 'vue'
35
+ import Notification from "./notification.vue";
36
+
37
+ /**
38
+ * @example // Notify usage
39
+ * <template>
40
+ * <r-notify>
41
+ * <template v-slot="{data}">
42
+ * <div>
43
+ * <div class="title">{{data.content.head}}</div>
44
+ * <div>{{data.content.body}}</div>
45
+ * </div>
46
+ * </template>
47
+ * </r-notify>
48
+ * <r-btn @click="notify(`info`)">show info</r-btn>
49
+ * <r-btn @click="notify(`error`)">show error</r-btn>
50
+ * <r-btn @click="notify(`success`)">show success</r-btn>
51
+ * <r-btn @click="notify(`warning`)">show warning</r-btn>
52
+ * </template>
53
+ * <script>
54
+ * const msg={"head":"title msg","body":"this is a message."}
55
+ * const {$notify} = inject('renusify')
56
+ * const notify=(status)=>{
57
+ * $notify(msg,{
58
+ * "timeout":5000,
59
+ * "status":status,
60
+ * "permanent":false,
61
+ * width:"300px",
62
+ * on_close_all:()=>{
63
+ * console.log("close all")
64
+ * },
65
+ * on_close:()=>{
66
+ * console.log("close")
67
+ * },
68
+ * on_click:()=>{
69
+ * console.log("click")
70
+ * }
71
+ * });
72
+ * }
73
+ * <//script>
74
+ *
75
+ * */
34
76
 
35
- export default {
36
- components: {
37
- notification: defineAsyncComponent(() => import('./notification.vue'))
77
+ const props = defineProps({
78
+ /**
79
+ * Makes notifications permanent (no auto-dismiss)
80
+ * @type {Boolean}
81
+ * @default false
82
+ */
83
+ permanent: {
84
+ default: false
38
85
  },
39
- props: {
40
- permanent: {
41
- default: false
42
- },
43
- top: {
44
- type: Boolean,
45
- default: false
46
- },
47
- left: {
48
- type: Boolean,
49
- default: false
50
- },
51
- status: {
52
- type: String,
53
- default: 'info'
54
- },
55
- width: {
56
- type: String,
57
- default: '350px'
58
- },
59
- timeout: {
60
- type: Number,
61
- default: 4000
62
- }
86
+ /**
87
+ * Positions notifications at the top of the screen
88
+ * @type {Boolean}
89
+ * @default false
90
+ */
91
+ top: {
92
+ type: Boolean,
93
+ default: false
63
94
  },
64
- data() {
65
- return {
66
- list: []
67
- }
95
+ /**
96
+ * Positions notifications at the left side of the screen
97
+ * @type {Boolean}
98
+ * @default false
99
+ */
100
+ left: {
101
+ type: Boolean,
102
+ default: false
68
103
  },
69
- methods: {
70
- handleClose(close) {
71
- if (close !== null) {
72
- close()
73
- }
74
- this.$notify()
75
- },
76
- handle(click) {
77
- if (click !== null) {
78
- click()
79
- }
80
- },
81
- showMe(obj) {
82
- const item = {
83
- id: this.$helper.uniqueId(),
84
- permanent: obj.permanent || this.permanent,
85
- content: obj.data,
86
- status: obj.status || this.status,
87
- width: obj.width || this.width,
88
- timeout: obj.timeout || this.timeout,
89
- on_close_all: obj.on_close_all || null,
90
- on_close: obj.on_close || null,
91
- on_click: obj.on_click || null
92
-
93
- }
94
- this.list.push(item)
95
- },
96
- hideMe() {
97
- this.list = []
98
- },
99
- hideChild(id, close) {
100
- if (close !== null) {
101
- close()
102
- }
103
- for (const i in this.list) {
104
- if (this.$helper.hasKey(this.list, i)) {
105
- if (this.list[i].id === id) {
106
- this.list.splice(i, 1)
107
- }
108
- }
109
- }
110
- },
111
- registerBusMethods() {
112
- window.renusifyBus.on('r-notify', this.showMe)
113
- window.renusifyBus.on('hide-r-notify', this.hideMe)
114
- }
104
+ /**
105
+ * Default status/color for notifications
106
+ * @type {String}
107
+ * @default 'info'
108
+ */
109
+ status: {
110
+ type: String,
111
+ default: 'info'
115
112
  },
116
- created() {
117
- this.registerBusMethods()
113
+ /**
114
+ * Minimum width of the notifications container
115
+ * @type {String}
116
+ * @default '350px'
117
+ */
118
+ width: {
119
+ type: String,
120
+ default: '350px'
121
+ },
122
+ /**
123
+ * Default auto-dismiss timeout in milliseconds
124
+ * @type {Number}
125
+ * @default 4000
126
+ */
127
+ timeout: {
128
+ type: Number,
129
+ default: 4000
130
+ }
131
+ })
132
+
133
+ const {$helper, $notify} = inject('renusify')
134
+
135
+ const list = ref([])
136
+
137
+ /**
138
+ * Handles the "Clear All" button click
139
+ * @param {Function|null} close - Custom close function from notification
140
+ */
141
+ const handleClose = (close) => {
142
+ if (close !== null) {
143
+ close()
144
+ }
145
+ $notify()
146
+ }
147
+
148
+ /**
149
+ * Handles notification click events
150
+ * @param {Function|null} click - Custom click function from notification
151
+ */
152
+ const handleClick = (click) => {
153
+ if (click !== null) {
154
+ click()
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Displays a new notification
160
+ * @param {Object} obj - Notification configuration object
161
+ * @param {*} obj.data - Notification content/data
162
+ * @param {String} [obj.status] - Status/color of the notification
163
+ * @param {Boolean} [obj.permanent] - Whether notification is permanent
164
+ * @param {String} [obj.width] - Width of the notification
165
+ * @param {Number} [obj.timeout] - Auto-dismiss timeout
166
+ * @param {Function} [obj.on_close_all] - Callback when "Clear All" is clicked
167
+ * @param {Function} [obj.on_close] - Callback when notification is closed
168
+ * @param {Function} [obj.on_click] - Callback when notification is clicked
169
+ */
170
+ const showMe = (obj) => {
171
+ const item = {
172
+ id: $helper.uniqueId(),
173
+ permanent: obj.permanent || props.permanent,
174
+ content: obj.data,
175
+ status: obj.status || props.status,
176
+ width: obj.width || props.width,
177
+ timeout: obj.timeout || props.timeout,
178
+ on_close_all: obj.on_close_all || null,
179
+ on_close: obj.on_close || null,
180
+ on_click: obj.on_click || null
181
+ }
182
+ list.value.push(item)
183
+ }
184
+
185
+ /**
186
+ * Clears all notifications
187
+ */
188
+ const hideMe = () => {
189
+ list.value = []
190
+ }
191
+
192
+ /**
193
+ * Hides a specific notification
194
+ * @param {String} id - ID of the notification to hide
195
+ * @param {Function|null} close - Custom close function from notification
196
+ */
197
+ const hideChild = (id, close) => {
198
+ if (close !== null) {
199
+ close()
200
+ }
201
+ const index = list.value.findIndex(item => item.id === id)
202
+ if (index !== -1) {
203
+ list.value.splice(index, 1)
118
204
  }
119
205
  }
206
+
207
+ const registerBusMethods = () => {
208
+ if (window.renusifyBus) {
209
+ window.renusifyBus.on('r-notify', showMe)
210
+ window.renusifyBus.on('hide-r-notify', hideMe)
211
+ }
212
+ }
213
+
214
+ const unregisterBusMethods = () => {
215
+ if (window.renusifyBus) {
216
+ window.renusifyBus.off('r-notify', showMe)
217
+ window.renusifyBus.off('hide-r-notify', hideMe)
218
+ }
219
+ }
220
+
221
+ registerBusMethods()
222
+
223
+ onUnmounted(() => {
224
+ unregisterBusMethods()
225
+ })
226
+
120
227
  </script>
228
+
121
229
  <style lang="scss">
122
230
  @use "sass:map";
123
- @use "../../style/variables/base";
231
+ @use "../../style" as *;
124
232
 
125
233
 
126
- .#{base.$prefix}notify {
234
+ .#{$prefix}notify {
127
235
  display: flex;
128
236
  align-items: center;
129
237
  padding: 10px;
130
238
  position: fixed;
131
239
  width: auto;
132
240
  height: auto;
133
- z-index: map.get(base.$z-index, 'medium');
241
+ z-index: map.get($z-index, 'high');
134
242
  overflow-y: auto;
135
243
  max-height: 100%;
136
244
 
@@ -150,6 +258,16 @@ export default {
150
258
  left: 0;
151
259
  }
152
260
 
261
+ .notify-msg {
262
+ display: flex;
263
+ justify-content: space-between;
264
+ align-items: flex-start;
265
+ padding: 10px;
266
+ border-radius: map.get($borders, 'md');
267
+ position: relative;
268
+ z-index: map.get($z-index, 'important');
269
+ margin: 0.3rem 0;
270
+ }
153
271
  }
154
272
 
155
273
  </style>
@@ -15,65 +15,48 @@
15
15
  </div>
16
16
  </transition>
17
17
  </template>
18
- <script>
19
- export default {
20
- props: {
21
- pos: {
22
- default: 'right'
23
- },
24
- permanent: {
25
- default: false
26
- },
27
- content: {},
28
- status: {
29
- type: String,
30
- default: 'alert-success'
31
- },
32
- width: {
33
- type: String,
34
- default: '350px'
35
- },
36
- timeout: {
37
- type: Number,
38
- default: 4000
39
- }
18
+ <script setup>
19
+ import {ref, onMounted, nextTick} from 'vue'
20
+
21
+ const props = defineProps({
22
+ pos: {
23
+ default: 'right'
40
24
  },
41
- emits:['hide'],
42
- data () {
43
- return {
44
- show: false
45
- }
25
+ permanent: {
26
+ default: false
46
27
  },
47
- methods: {
48
- hideMe () {
49
- this.$emit('hide',true)
50
- }
28
+ content: {},
29
+ status: {
30
+ type: String,
31
+ default: 'alert-success'
51
32
  },
52
- created () {
53
- setTimeout(() => {
54
- this.show = true
55
- }, 10)
56
- if (!this.permanent) {
57
- setTimeout(() => {
58
- this.hideMe()
59
- }, this.timeout)
60
- }
33
+ width: {
34
+ type: String,
35
+ default: '350px'
36
+ },
37
+ timeout: {
38
+ type: Number,
39
+ default: 4000
61
40
  }
62
- }
63
- </script>
64
- <style lang="scss">
65
- @use "sass:map";
66
- @use "../../style/variables/base";
41
+ })
42
+
43
+ const emit = defineEmits(['hide'])
67
44
 
45
+ const show = ref(false)
68
46
 
69
- .notify-msg {
70
- display: flex;
71
- justify-content: space-between;
72
- align-items: flex-start;
73
- padding: 10px;
74
- border-radius: map.get(base.$borders, 'md');
75
- position: relative;
76
- z-index: map.get(base.$z-index, 'important');
77
- margin: 0.3rem 0;
47
+ const hideMe = () => {
48
+ emit('hide', true)
78
49
  }
79
- </style>
50
+
51
+ onMounted(() => {
52
+ nextTick(() => {
53
+ show.value = true
54
+ })
55
+
56
+ if (!props.permanent) {
57
+ setTimeout(() => {
58
+ hideMe()
59
+ }, props.timeout)
60
+ }
61
+ })
62
+ </script>
@@ -28,6 +28,7 @@
28
28
  ></circle>
29
29
  </svg>
30
30
  <div :class="`${$r.prefix}progress-circle-info`">
31
+ <!-- Default slot for custom progress circle content -->
31
32
  <slot>
32
33
  <span v-if="showPercent">{{ modelValue }} %</span>
33
34
  </slot>
@@ -35,78 +36,196 @@
35
36
  </div>
36
37
  </template>
37
38
 
38
- <script>
39
- import './style.scss'
40
-
41
- export default {
42
- name: 'pcircle',
43
- props: {
44
- indeterminate: Boolean,
45
- showPercent: Boolean,
46
- rotate: {
47
- type: [Number, String],
48
- default: 0
49
- },
50
- size: {
51
- type: [Number, String],
52
- default: '32'
53
- },
54
- width: {
55
- type: [Number, String],
56
- default: 4
57
- },
58
- modelValue: {
59
- type: [Number, String],
60
- default: 0
61
- }
39
+ <script setup>
40
+ import {computed} from 'vue'
41
+
42
+ const props = defineProps({
43
+ /**
44
+ * Shows indeterminate/animated progress circle
45
+ * @type {Boolean}
46
+ */
47
+ indeterminate: Boolean,
48
+ /**
49
+ * Shows percentage value in the center (when slot is not used)
50
+ * @type {Boolean}
51
+ */
52
+ showPercent: Boolean,
53
+ /**
54
+ * Rotation angle of the progress circle in degrees
55
+ * @type {Number|String}
56
+ * @default 0
57
+ */
58
+ rotate: {
59
+ type: [Number, String],
60
+ default: 0
61
+ },
62
+ /**
63
+ * Size of the progress circle in pixels
64
+ * @type {Number|String}
65
+ * @default '32'
66
+ */
67
+ size: {
68
+ type: [Number, String],
69
+ default: '32'
62
70
  },
63
- data: () => ({
64
- radius: 20
65
- }),
66
- computed: {
67
-
68
- circumference () {
69
- return 2 * Math.PI * this.radius
70
- },
71
-
72
- normalizedValue () {
73
- if (this.modelValue < 0) {
74
- return 0
75
- }
76
-
77
- if (this.modelValue > 100) {
78
- return 100
79
- }
80
-
81
- return parseFloat(this.modelValue)
82
- },
83
-
84
- strokeDashArray () {
85
- return Math.round(this.circumference * 1000) / 1000
86
- },
87
-
88
- strokeDashOffset () {
89
- return (100 - this.normalizedValue) / 100 * this.circumference + 'px'
90
- },
91
-
92
- strokeWidth () {
93
- return Number(this.width) / +this.size * this.viewBoxSize * 2
94
- },
95
-
96
- styles () {
97
- const size= this.size + 'px'
98
- return `height: ${size};
99
- width: ${size}`
100
- },
101
-
102
- svgStyles () {
103
- return `transform: rotate(${Number(this.rotate)}deg)`
104
- },
105
-
106
- viewBoxSize () {
107
- return this.radius / (1 - Number(this.width) / +this.size)
71
+ /**
72
+ * Stroke width of the progress circle in pixels
73
+ * @type {Number|String}
74
+ * @default 4
75
+ */
76
+ width: {
77
+ type: [Number, String],
78
+ default: 4
79
+ },
80
+ /**
81
+ * Current progress value (0-100)
82
+ * @type {Number|String}
83
+ * @default 0
84
+ */
85
+ modelValue: {
86
+ type: [Number, String],
87
+ default: 0
88
+ }
89
+ })
90
+
91
+ const radius = 20
92
+
93
+ const circumference = computed(() => {
94
+ return 2 * Math.PI * radius
95
+ })
96
+
97
+ const normalizedValue = computed(() => {
98
+ const value = parseFloat(props.modelValue)
99
+
100
+ if (isNaN(value)) return 0
101
+ if (value < 0) return 0
102
+ if (value > 100) return 100
103
+
104
+ return value
105
+ })
106
+
107
+ const strokeDashArray = computed(() => {
108
+ return Math.round(circumference.value * 1000) / 1000
109
+ })
110
+
111
+ const strokeDashOffset = computed(() => {
112
+ return ((100 - normalizedValue.value) / 100) * circumference.value + 'px'
113
+ })
114
+
115
+ const strokeWidth = computed(() => {
116
+ const widthNum = Number(props.width)
117
+ const sizeNum = Number(props.size)
118
+
119
+ if (sizeNum === 0) return 0
120
+ return (widthNum / sizeNum) * viewBoxSize.value * 2
121
+ })
122
+
123
+ const styles = computed(() => {
124
+ const size = props.size + 'px'
125
+ return {
126
+ height: size,
127
+ width: size
128
+ }
129
+ })
130
+
131
+ const svgStyles = computed(() => {
132
+ return {
133
+ transform: `rotate(${Number(props.rotate)}deg)`
134
+ }
135
+ })
136
+
137
+ const viewBoxSize = computed(() => {
138
+ const widthNum = Number(props.width)
139
+ const sizeNum = Number(props.size)
140
+
141
+ if (sizeNum === 0 || widthNum >= sizeNum) return radius
142
+ return radius / (1 - widthNum / sizeNum)
143
+ })
144
+
145
+ </script>
146
+
147
+ <style lang="scss">
148
+ @use "sass:map";
149
+ @use "../../style" as *;
150
+
151
+
152
+ $progress-circle-rotate-animation: progress-circle-rotate 1.4s linear infinite !default;
153
+ $progress-circle-rotate-dash: progress-circle-dash 1.4s ease-in-out infinite !default;
154
+ $process-circle-intermediate-svg-transition: all .2s ease-in-out !default;
155
+ $progress-circle-underlay-stroke: rgba(0, 0, 0, 0.1) !default;
156
+ $progress-circle-overlay-transition: all .6s ease-in-out !default;
157
+
158
+ .#{$prefix}progress-circle {
159
+ position: relative;
160
+ display: inline-flex;
161
+ vertical-align: middle;
162
+ justify-content: center;
163
+ align-items: center;
164
+
165
+ svg {
166
+ width: 100%;
167
+ height: 100%;
168
+ margin: auto;
169
+ position: absolute;
170
+ top: 0;
171
+ bottom: 0;
172
+ left: 0;
173
+ right: 0;
174
+ z-index: 0;
175
+ }
176
+
177
+ &-indeterminate {
178
+ svg {
179
+ animation: $progress-circle-rotate-animation;
180
+ transform-origin: center center;
181
+ transition: $process-circle-intermediate-svg-transition;
108
182
  }
109
183
 
184
+ .#{$prefix}progress-circle-overlay {
185
+ animation: $progress-circle-rotate-dash;
186
+ stroke-linecap: round;
187
+ stroke-dasharray: 80, 200;
188
+ stroke-dashoffset: 0px;
189
+ }
190
+ }
191
+
192
+ &-info {
193
+ align-items: center;
194
+ display: flex;
195
+ justify-content: center
196
+ }
197
+
198
+ &-underlay {
199
+ stroke: $progress-circle-underlay-stroke;
200
+ z-index: 1
201
+ }
202
+
203
+ &-overlay {
204
+ stroke: currentColor;
205
+ z-index: 2;
206
+ transition: $progress-circle-overlay-transition
110
207
  }
111
208
  }
112
- </script>
209
+
210
+ @keyframes progress-circle-dash {
211
+ 0% {
212
+ stroke-dasharray: 1, 200;
213
+ stroke-dashoffset: 0px
214
+ }
215
+ 50% {
216
+ stroke-dasharray: 100, 200;
217
+ stroke-dashoffset: -15px
218
+ }
219
+ 100% {
220
+ stroke-dasharray: 100, 200;
221
+ stroke-dashoffset: -125px
222
+ }
223
+ }
224
+
225
+ @keyframes progress-circle-rotate {
226
+ 100% {
227
+ transform: rotate(360deg)
228
+ }
229
+ }
230
+
231
+ </style>