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
@@ -11,52 +11,272 @@
11
11
  </div>
12
12
  </template>
13
13
 
14
- <script>
15
- import './style.scss'
16
-
17
- export default {
18
- name: 'pline',
19
- props: {
20
- modelValue: [Number, String],
21
- color: String,
22
- progressStyle: [String, Object, Array],
23
- showPercent: Boolean,
24
- outlined: Boolean,
25
- rounded: Boolean,
26
- showBackground: Boolean,
27
- size: {
28
- type: String,
29
- default: 'small',
30
- validator: function (value) {
31
- return ['small', 'medium', 'large', 'x-large'].indexOf(value) !== -1
32
- }
33
- }
34
- },
35
- computed: {
36
- isIndeterminate() {
37
- if (this.modelValue !== undefined) {
38
- return !(this.modelValue >= 0 && this.modelValue <= 100)
39
- } else {
40
- return true
41
- }
42
- },
43
- classes() {
44
- let c = ''
45
- c += this.isIndeterminate ? 'line-indeterminate' : 'line-determinate'
46
-
47
- if (this.color) {
48
- c += ' ' + this.color
49
- }
50
- return c
51
- },
52
- styles() {
53
- let c = ''
54
- if (!this.isIndeterminate) {
55
- c += 'width:' + this.modelValue + '%;'
56
- }
57
-
58
- return c
59
- }
14
+ <script setup>
15
+ import {computed} from 'vue'
16
+
17
+ const props = defineProps({
18
+ /**
19
+ * Current progress value (0-100). If undefined or outside 0-100 range, shows indeterminate state.
20
+ * @type {Number|String}
21
+ */
22
+ modelValue: [Number, String],
23
+ /**
24
+ * CSS class for progress bar color styling
25
+ * @type {String}
26
+ */
27
+ color: String,
28
+ /**
29
+ * Additional inline styles for the progress bar. Can be a string, object, or array.
30
+ * @type {String|Object|Array}
31
+ */
32
+ progressStyle: [String, Object, Array],
33
+ /**
34
+ * Shows percentage text alongside the progress bar
35
+ * @type {Boolean}
36
+ */
37
+ showPercent: Boolean,
38
+ /**
39
+ * Applies outlined styling to the progress bar
40
+ * @type {Boolean}
41
+ */
42
+ outlined: Boolean,
43
+ /**
44
+ * Applies rounded corners to the progress bar
45
+ * @type {Boolean}
46
+ */
47
+ rounded: Boolean,
48
+ /**
49
+ * Shows background track behind the progress bar
50
+ * @type {Boolean}
51
+ */
52
+ showBackground: Boolean,
53
+ /**
54
+ * Size variant of the progress bar
55
+ * @type {String}
56
+ * @default 'sm'
57
+ * @values 'sm', 'md', 'lg', 'xl'
58
+ */
59
+ size: {
60
+ type: String,
61
+ default: 'sm',
62
+ validator: (value) => ['sm', 'md', 'lg', 'xl'].includes(value)
63
+ }
64
+ })
65
+
66
+ const emit = defineEmits([
67
+ /**
68
+ * Emitted when progress value changes
69
+ * @param {Number|String} value - New progress value
70
+ */
71
+ 'update:modelValue'
72
+ ])
73
+
74
+ const isIndeterminate = computed(() => {
75
+ if (props.modelValue !== undefined) {
76
+ return !(props.modelValue >= 0 && props.modelValue <= 100)
77
+ } else {
78
+ return true
79
+ }
80
+ })
81
+
82
+ const classes = computed(() => {
83
+ const classList = []
84
+
85
+ classList.push(isIndeterminate.value ? 'line-indeterminate' : 'line-determinate')
86
+
87
+ if (props.color) {
88
+ classList.push(props.color)
89
+ }
90
+
91
+ if (props.size) {
92
+ classList.push(`size-${props.size}`)
93
+ }
94
+
95
+ if (props.outlined) {
96
+ classList.push('outlined')
97
+ }
98
+
99
+ if (props.rounded) {
100
+ classList.push('rounded')
101
+ }
102
+
103
+ if (props.showBackground) {
104
+ classList.push('with-background')
105
+ }
106
+
107
+ return classList.join(' ')
108
+ })
109
+
110
+ const styles = computed(() => {
111
+ const styleObj = {}
112
+
113
+ if (!isIndeterminate.value && props.modelValue !== undefined) {
114
+ styleObj.width = `${props.modelValue}%`
115
+ }
116
+
117
+
118
+ if (props.progressStyle) {
119
+ if (typeof props.progressStyle === 'string') {
120
+ props.progressStyle.split(';').forEach(style => {
121
+ if (style.trim()) {
122
+ const [key, value] = style.split(':').map(s => s.trim())
123
+ if (key && value) {
124
+ styleObj[key] = value
125
+ }
60
126
  }
127
+ })
128
+ } else if (typeof props.progressStyle === 'object') {
129
+ Object.assign(styleObj, props.progressStyle)
61
130
  }
131
+ }
132
+
133
+ return styleObj
134
+ })
135
+
62
136
  </script>
137
+
138
+ <style lang="scss">
139
+ @use "sass:map";
140
+ @use "../../style" as *;
141
+
142
+ .#{$prefix}progress {
143
+ text-align: center;
144
+
145
+ .progress-outlined {
146
+ color: var(--color-sheet-container-highest)
147
+ }
148
+
149
+ .line-determinate {
150
+ background-color: var(--color-on-sheet);
151
+ }
152
+
153
+ .line-indeterminate {
154
+ background-color: var(--color-on-sheet);
155
+ }
156
+
157
+ .progress-background {
158
+ background-color: var(--color-sheet-container-highest);
159
+ }
160
+
161
+ &.progress-outlined {
162
+ border: 1px solid;
163
+ }
164
+
165
+ &.progress-rounded {
166
+ border-radius: 20px;
167
+ overflow: hidden;
168
+ }
169
+
170
+ .progress-container {
171
+ position: relative;
172
+ display: block;
173
+ width: 100%;
174
+ background-clip: padding-box;
175
+ overflow: hidden;
176
+ }
177
+
178
+ &.size {
179
+ &-sm {
180
+ .progress-container {
181
+ height: 4px;
182
+ }
183
+ }
184
+
185
+ &-md {
186
+ .progress-container {
187
+ height: 8px;
188
+ }
189
+
190
+ &.progress-outlined {
191
+ border-width: 2px;
192
+ }
193
+ }
194
+
195
+ &-lg {
196
+ .progress-container {
197
+ height: 12px;
198
+ }
199
+
200
+ &.progress-outlined {
201
+ border-width: 3px;
202
+ }
203
+ }
204
+
205
+ &-xl {
206
+ .progress-container {
207
+ height: 16px;
208
+ }
209
+
210
+ &.progress-outlined {
211
+ border-width: 4px;
212
+ }
213
+ }
214
+ }
215
+
216
+ .line-determinate {
217
+ position: absolute;
218
+ top: 0;
219
+ bottom: 0;
220
+ transition: width .3s linear;
221
+ border-radius: 2px;
222
+ }
223
+
224
+ .line-indeterminate {
225
+ border-radius: 2px;
226
+
227
+ &:before {
228
+ content: '';
229
+ position: absolute;
230
+ background-color: inherit;
231
+ top: 0;
232
+ left: 0;
233
+ bottom: 0;
234
+ will-change: left, right;
235
+ animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;
236
+ }
237
+
238
+ :after {
239
+ content: '';
240
+ position: absolute;
241
+ background-color: inherit;
242
+ top: 0;
243
+ left: 0;
244
+ bottom: 0;
245
+ will-change: left, right;
246
+ animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;
247
+ animation-delay: 1.15s;
248
+ }
249
+ }
250
+
251
+
252
+ @keyframes indeterminate {
253
+ 0% {
254
+ left: -35%;
255
+ right: 100%;
256
+ }
257
+ 60% {
258
+ left: 100%;
259
+ right: -90%;
260
+ }
261
+ 100% {
262
+ left: 100%;
263
+ right: -90%;
264
+ }
265
+ }
266
+
267
+ @keyframes indeterminate-short {
268
+ 0% {
269
+ left: -200%;
270
+ right: 100%;
271
+ }
272
+ 60% {
273
+ left: 107%;
274
+ right: -8%;
275
+ }
276
+ 100% {
277
+ left: 107%;
278
+ right: -8%;
279
+ }
280
+ }
281
+ }
282
+ </style>
@@ -2,7 +2,5 @@ export * as rSearchBox from './index.vue'
2
2
  export * as l_line from '../progress/line.js'
3
3
  export * as l_btn from '../button/index.js'
4
4
  export * as l_card from '../card/index.js'
5
- export * as l_list from '../list/index.js'
6
5
  export * as l_icon from '../icon/index.js'
7
- export * as l_select from '../form/selectInput/index.js'
8
- export * as d_clickOutside from '../../directive/clickOutSide/index.js'
6
+ export * as l_select from '../form/selectInput/index.js'
@@ -3,26 +3,22 @@
3
3
  'to-top': openToTop}]">
4
4
  <template v-if="!closable || show">
5
5
  <div
6
- v-click-outside="handleclose"
7
- :class="[inputControlClass, { 'z-important search-open': open }]"
6
+ :class="{ 'z-important search-open': open }"
8
7
  class="search-input"
9
8
  >
10
- <span v-if="categories" class="w-30">
9
+ <span v-if="categories" class="category-holder">
11
10
  <r-select-input
12
11
  v-model="category"
13
12
  :items="categories"
14
- class="mt-0"
15
- inputControlClass="ps-2"
13
+ class="mt-0 ps-2"
16
14
  disable-search
17
15
  first-select
18
16
  hide
19
- tile
20
17
  justValue
21
18
  ></r-select-input>
22
19
  </span>
23
20
  <span
24
- :class="{ 'w-70': categories, 'w-full': !categories }"
25
- class="d-flex v-center"
21
+ class="d-flex v-center flex-grow-1"
26
22
  >
27
23
  <input
28
24
  :placeholder="label"
@@ -34,7 +30,10 @@
34
30
  @focusout="active = false"
35
31
  @input="handle"
36
32
  />
37
- <r-icon class="mx-1" v-html="$r.icons.search"></r-icon>
33
+ <!-- Slot for custom toggle button icon -->
34
+ <slot name="icon">
35
+ <r-icon class="mx-1" v-html="$r.icons.search"></r-icon>
36
+ </slot>
38
37
  </span>
39
38
  </div>
40
39
  <r-card
@@ -49,114 +48,194 @@
49
48
  class="w-full"
50
49
  color="color-two"
51
50
  ></r-progress-line>
52
- <r-list
51
+ <div
53
52
  v-if="list.length > 0"
54
- :items="list"
55
53
  @update:modelValue="listInput"
56
54
  >
57
- <template v-slot="props">
58
- <slot :item="props.item">
59
- <div class="list-title">{{ props.item["name"] }}</div>
55
+ <div v-for="(item,i) in list" :key="i" class="list-item">
56
+ <!-- Slot for custom search result item rendering. Provide item prop - The search result item -->
57
+ <slot :item="item">
58
+ {{ item["name"] }}
60
59
  </slot>
61
- </template>
62
- </r-list>
60
+ </div>
61
+ </div>
63
62
  <div v-else-if="!loading" class="py-5">
64
63
  {{ notFoundMsg }}
65
64
  </div>
66
65
  </r-card>
67
- <transition name="fade" v-if="!noOverlay">
68
- <div v-if="open" class="search-shadow"></div>
66
+ <transition name="fade">
67
+ <div v-if="open" :class="{'search-shadow':!noOverlay}" @click="handleclose"></div>
69
68
  </transition>
70
69
  </template>
71
- <r-btn v-else class="mt-5" icon @click.prevent="show = !show">
72
- <r-icon v-html="$r.icons.search"></r-icon>
70
+ <r-btn v-else icon v-bind="btnAttr" @click.prevent="show = !show">
71
+ <!-- Slot for custom toggle button icon -->
72
+ <slot name="icon">
73
+ <r-icon v-html="$r.icons.search"></r-icon>
74
+ </slot>
73
75
  </r-btn>
74
76
  </div>
75
77
  </template>
76
- <script>
77
- export default {
78
- name: "r-search-box",
79
- props: {
80
- closable: Boolean,
81
- notFoundMsg: {
82
- type: String,
83
- default: "Can't Find Anything :(",
84
- },
85
- label: String,
86
- url: String,
87
- inputControlClass: [String, Object, Array],
88
- query: {
89
- type: String,
90
- default: "search",
91
- },
92
- modelValue: [String, Number],
93
- noOverlay: Boolean,
94
- openToTop: Boolean,
95
- categories: Array,
96
- headers: Object,
97
- },
98
- emits: ["update:modelValue", "select"],
99
- data() {
100
- return {
101
- show: false,
102
- lazyValue: this.modelValue,
103
- loading: false,
104
- active: false,
105
- open: false,
106
- idSet: null,
107
- category: null,
108
- list: [],
109
- };
110
- },
111
- watch: {
112
- modelValue() {
113
- this.lazyValue = this.modelValue;
114
- },
78
+
79
+ <script setup>
80
+ import {ref, watch, inject} from 'vue'
81
+
82
+ const props = defineProps({
83
+ /**
84
+ * Enables closable mode with toggle button
85
+ * @type {Boolean}
86
+ */
87
+ closable: Boolean,
88
+ /**
89
+ * Message shown when no search results are found
90
+ * @type {String}
91
+ * @default "Can't Find Anything :("
92
+ */
93
+ notFoundMsg: {
94
+ type: String,
95
+ default: "Can't Find Anything :(",
115
96
  },
116
- methods: {
117
- handleclose() {
118
- this.open = false;
119
- },
120
- get() {
121
- if (this.url) {
122
- this.loading = true;
123
- this.$axios
124
- .get(this.url, {
125
- params: {
126
- [this.query]: this.lazyValue,
127
- category: this.category,
128
- },
129
- headers: this.headers,
130
- })
131
- .then(
132
- ({data}) => {
133
- this.list = data;
134
- this.loading = false;
135
- this.open = true;
136
- },
137
- () => {
138
- this.loading = false;
139
- }
140
- );
141
- }
142
- },
143
- handle(e) {
144
- this.lazyValue = e.target.value;
145
- this.open = true;
146
- this.loading = true;
147
- clearTimeout(this.idSet);
148
- this.idSet = setTimeout(() => {
149
- this.$emit("update:modelValue", this.lazyValue);
150
- this.get();
151
- }, 1000);
152
- },
153
- listInput(e) {
154
- this.$emit("select", e);
155
- this.open = false;
156
- },
97
+ /**
98
+ * Placeholder text for the search input
99
+ * @type {String}
100
+ */
101
+ label: String,
102
+ /**
103
+ * API endpoint URL for search requests
104
+ * @type {String}
105
+ */
106
+ url: String,
107
+ /**
108
+ * Attributes passed to the toggle button in closable mode
109
+ * @type {Object}
110
+ */
111
+ btnAttr: Object,
112
+ /**
113
+ * Query parameter name for the search term
114
+ * @type {String}
115
+ * @default "search"
116
+ */
117
+ query: {
118
+ type: String,
119
+ default: "search",
157
120
  },
158
- };
121
+ /**
122
+ * Current search value (v-model)
123
+ * @type {String|Number}
124
+ */
125
+ modelValue: [String, Number],
126
+ /**
127
+ * Disables the overlay/backdrop
128
+ * @type {Boolean}
129
+ */
130
+ noOverlay: Boolean,
131
+ /**
132
+ * Opens search results dropdown above the input instead of below
133
+ * @type {Boolean}
134
+ */
135
+ openToTop: Boolean,
136
+ /**
137
+ * Array of category items for search filtering
138
+ * @type {Array}
139
+ */
140
+ categories: Array,
141
+ /**
142
+ * Additional HTTP headers for search requests
143
+ * @type {Object}
144
+ */
145
+ headers: Object,
146
+ })
147
+
148
+ const emit = defineEmits([
149
+ /**
150
+ * Emitted when search value changes (v-model)
151
+ * @param {String|Number} value - New search value
152
+ */
153
+ 'update:modelValue',
154
+ /**
155
+ * Emitted when a search result item is selected
156
+ * @param {*} item - Selected search result
157
+ */
158
+ 'select'
159
+ ])
160
+
161
+ const $axios = inject('axios')
162
+
163
+ const show = ref(false)
164
+ const lazyValue = ref(props.modelValue)
165
+ const loading = ref(false)
166
+ const active = ref(false)
167
+ const open = ref(false)
168
+ const idSet = ref(null)
169
+ const category = ref(null)
170
+ const list = ref([])
171
+
172
+ watch(() => props.modelValue, (newValue) => {
173
+ lazyValue.value = newValue
174
+ })
175
+
176
+ /**
177
+ * Closes the search results dropdown
178
+ */
179
+ const handleclose = () => {
180
+ open.value = false
181
+ }
182
+
183
+ /**
184
+ * Fetches search results from the API
185
+ */
186
+ const get = () => {
187
+ if (!props.url || !$axios) return
188
+
189
+ loading.value = true
190
+
191
+ const params = {
192
+ [props.query]: lazyValue.value
193
+ }
194
+
195
+ if (category.value) {
196
+ params.category = category.value
197
+ }
198
+
199
+ $axios.get(props.url, {
200
+ params: params,
201
+ headers: props.headers
202
+ })
203
+ .then(({data}) => {
204
+ list.value = data
205
+ loading.value = false
206
+ open.value = true
207
+ })
208
+ .catch(() => {
209
+ loading.value = false
210
+ })
211
+ }
212
+
213
+ /**
214
+ * Handles search input changes with debouncing
215
+ * @param {Event} e - Input event
216
+ */
217
+ const handle = (e) => {
218
+ lazyValue.value = e.target.value
219
+ open.value = true
220
+ loading.value = true
221
+
222
+ clearTimeout(idSet.value)
223
+ idSet.value = setTimeout(() => {
224
+ emit('update:modelValue', lazyValue.value)
225
+ get()
226
+ }, 1000)
227
+ }
228
+
229
+ /**
230
+ * Handles search result selection
231
+ * @param {*} e - Selected item
232
+ */
233
+ const listInput = (e) => {
234
+ emit('select', e)
235
+ open.value = false
236
+ }
159
237
  </script>
238
+
160
239
  <style lang="scss">
161
240
  @use "sass:map";
162
241
  @use "../../style/variables/base";
@@ -258,5 +337,19 @@ export default {
258
337
  }
259
338
  }
260
339
  }
340
+
341
+ .category-holder {
342
+ width: 100px;
343
+ }
344
+
345
+ .list-item {
346
+ padding: 16px 8px;
347
+ border-bottom: 1px solid var(--color-sheet-container-low);
348
+
349
+ &:hover {
350
+ background-color: var(--color-one-container);
351
+ color: var(--color-on-one-container);
352
+ }
353
+ }
261
354
  }
262
355
  </style>