renusify 2.5.1 → 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 +140 -81
  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 +72 -40
  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 +83 -56
  70. package/components/form/timeInput/range.vue +116 -95
  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 +383 -158
  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 +631 -401
  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 +107 -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 -710
  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
@@ -2,296 +2,377 @@
2
2
  <div
3
3
  :class="{
4
4
  [`${$r.prefix}input-container`]:true,
5
- [c_color]:c_color&&!isDisabled&&!hasError,
6
- 'color-error-text':hasError&&genMessages.length>0,
7
- 'hide-detail':c_hide,
5
+ 'input-invalid':hasError,
6
+ 'input-valid':!hasError,
7
+ 'input-error':hasError&&genMessages.length>0,
8
+ 'hide-detail':hide,
8
9
  'input-focused':active,
9
10
  'input-disabled':isDisabled,
10
- 'input-ltr':c_ltr
11
+ 'input-ltr':ltr
11
12
  }"
12
13
  >
13
- <div ref="input" :class="[c_inputControlClass,{'input-tile':c_tile,'ps-8':preIcon}]" class="input-control">
14
- <label :for="computedId" class="label"
15
- v-if="label"
16
- :class="[c_labelControlClass,
17
- {'label-active':labelActive,
18
- 'ms-5':((preIcon&&!labelActive&&!active))
19
- }]"
14
+ <div ref="input" class="input-control">
15
+ <label v-if="label"
16
+ :class="{
17
+ 'label-active':activeLabel,
18
+ 'label-margin':((preIcon&&!activeLabel&&!active))
19
+ }"
20
+ :for="computedId"
21
+ class="label"
20
22
  >
21
- <span class="color-error-text" v-if="isRequired">*</span> {{ label }}
23
+ <!-- Slot for custom label content. Provide isRequired prop. -->
24
+ <slot name="label" :isRequired="isRequired">
25
+ <span v-if="isRequired" class="color-error-text">*</span> {{ label }}
26
+ </slot>
22
27
  </label>
23
- <r-icon class="pre-icon" v-if="preIcon" v-html="preIcon" @click.prevent.stop="$emit('pre-icon',true)"></r-icon>
24
- <slot :isRequired="isRequired" :uid="uid"></slot>
25
- <r-icon class="after-icon" v-if="icon" v-html="icon" @click.prevent.stop="$emit('icon',true)"></r-icon>
28
+ <span v-if="preIcon" class="pre-icon" @click.prevent.stop="$emit('pre-icon',true)">
29
+ <!-- Slot for pre-icon content -->
30
+ <slot name="preIcon">
31
+ <r-icon v-html="preIcon"></r-icon>
32
+ </slot>
33
+ </span>
34
+ <div class="input-holder">
35
+ <!-- Default slot for input content. Provide isRequired, uid props. -->
36
+ <slot :isRequired="isRequired" :uid="uid"></slot>
37
+ </div>
38
+ <span v-if="icon" class="icon" @click.prevent.stop="$emit('icon',true)">
39
+ <!-- Slot for icon content -->
40
+ <slot name="icon">
41
+ <r-icon v-html="icon"></r-icon>
42
+ </slot>
43
+ </span>
26
44
  </div>
27
- <div class="massage"
45
+ <div class="massage body-3"
28
46
  :class="{
29
47
  'massage-active':genMessages.length>0,
30
48
  }">
31
- <div :class="{'animation-shake-3':c_msgShake}">{{ genMessages.join(',') }}</div>
32
-
49
+ <!-- Slot for custom message display -->
50
+ <slot :messages="genMessages" name="message">{{ genMessages.join(',') }}</slot>
33
51
  </div>
34
52
  </div>
35
53
  </template>
36
- <script>
37
-
38
- export default {
39
- name: 'r-input',
40
- inject: {
41
- 'form': {
42
- default: false
43
- }
44
- },
45
- props: {
46
- id: String,
47
- icon: String,
48
- preIcon: String,
49
- msg: String,
50
- labelControlClass: [String, Object, Array],
51
- inputControlClass: [String, Object, Array],
52
- color: String,
53
- label: String,
54
- modelValue: [String, Boolean, Number, Array, Object],
55
- active: Boolean,
56
- hide: {type: Boolean, default: undefined},
57
- tile: {type: Boolean, default: undefined},
58
- disabled: Boolean,
59
- readonly: Boolean,
60
- error: Boolean,
61
- ltr: {type: Boolean, default: undefined},
62
- msgShake: {type: Boolean, default: undefined},
63
- rules: {
64
- type: [Array, Function],
65
- default: () => []
66
- },
67
- validateOnBlur: {type: Boolean, default: undefined}
68
- },
69
- emits: ['pre-icon', 'icon', 'update:modelValue'],
70
- data() {
71
- return {
72
- uid: 'input_' + this.$helper.uniqueId(),
73
- lazyValue: this.modelValue,
74
- focused: false,
75
- errorBucket: [],
76
- hasColor: false,
77
- hasFocused: false,
78
- hasInput: false,
79
- isFocused: false,
80
- isResetting: false,
81
- valid: false
82
- }
83
- },
84
- beforeMount() {
85
- this.validate()
54
+ <script setup>
55
+ import {ref, computed, watch, inject, onMounted, onBeforeUnmount} from 'vue'
56
+
57
+ const props = defineProps({
58
+ /**
59
+ * Input ID attribute
60
+ * @type {String}
61
+ */
62
+ id: String,
63
+
64
+ /**
65
+ * Icon to display after input
66
+ * @type {String}
67
+ */
68
+ icon: String,
69
+
70
+ /**
71
+ * Icon to display before input
72
+ * @type {String}
73
+ */
74
+ preIcon: String,
75
+
76
+ /**
77
+ * Custom error message
78
+ * @type {String}
79
+ */
80
+ msg: String,
81
+
82
+ /**
83
+ * Input label text
84
+ * @type {String}
85
+ */
86
+ label: String,
87
+
88
+ /**
89
+ * Input placeholder text
90
+ * @type {String}
91
+ */
92
+ placeholder: String,
93
+
94
+ /**
95
+ * The model value for the input (v-model)
96
+ * @type {String|Boolean|Number|Array|Object}
97
+ */
98
+ modelValue: [String, Boolean, Number, Array, Object],
99
+
100
+ /**
101
+ * Whether input is in focused state
102
+ * @type {Boolean}
103
+ */
104
+ active: Boolean,
105
+
106
+ /**
107
+ * Whether label should always be active
108
+ * @type {Boolean}
109
+ */
110
+ labelActive: Boolean,
111
+
112
+ /**
113
+ * Hides validation details
114
+ * @type {Boolean}
115
+ * @default undefined
116
+ */
117
+ hide: {type: Boolean, default: undefined},
118
+
119
+ /**
120
+ * Disables the input
121
+ * @type {Boolean}
122
+ */
123
+ disabled: Boolean,
124
+
125
+ /**
126
+ * Makes input read-only
127
+ * @type {Boolean}
128
+ */
129
+ readonly: Boolean,
130
+
131
+ /**
132
+ * Manually sets error state
133
+ * @type {Boolean}
134
+ */
135
+ error: Boolean,
136
+
137
+ /**
138
+ * Auto-focuses input on mount
139
+ * @type {Boolean}
140
+ */
141
+ autofocus: Boolean,
142
+
143
+ /**
144
+ * Sets left-to-right text direction
145
+ * @type {Boolean}
146
+ * @default undefined
147
+ */
148
+ ltr: {type: Boolean, default: undefined},
149
+
150
+ /**
151
+ * Validation rules
152
+ * @type {Array|Function}
153
+ * @default () => []
154
+ */
155
+ rules: {
156
+ type: [Array, Function],
157
+ default: () => []
86
158
  },
87
- mounted() {
88
- let inp = this.$refs.input.querySelector('input')
89
- if (inp) {
90
- inp.setAttribute('id', this.uid)
91
- }
92
- },
93
- created() {
94
- this.form && this.form.register(this)
95
- },
96
- beforeUnmount() {
97
- this.form && this.form.unregister(this)
98
- },
99
- computed: {
100
- computedId() {
101
- return this.id || this.uid
102
- },
103
- isRequired() {
104
- return this.rules ? (this.rules.indexOf('required') > -1) : false
105
- },
106
- isDisabled() {
107
- return this.disabled || this.readonly
108
- },
109
- hasError() {
110
- if (this.error) {
111
- return true
112
- }
113
- return this.errorBucket.length > 0
114
- },
115
- genMessages() {
116
- let m = []
117
- if (this.msg) {
118
- m = [this.msg]
119
- }
120
- return this.hasMessages ? this.validations : m
121
- },
122
- hasMessages() {
123
- return this.validationTarget.length > 0
124
- },
125
- shouldValidate() {
126
- if (this.isResetting) return false
127
- return this.c_validateOnBlur ? this.hasFocused && !this.isFocused : this.hasInput || this.hasFocused
128
- },
129
- validations() {
130
- return this.validationTarget.slice(0, 1)
131
- },
132
- validationTarget() {
133
- if (this.shouldValidate) {
134
- return this.errorBucket
135
- } else return []
136
- },
137
- labelActive() {
138
- return (this.lazyValue !== undefined && this.lazyValue !== '' && this.lazyValue !== null)
139
- },
140
- c_labelControlClass() {
141
- if (this.labelControlClass === undefined && this.$r.inputs.labelControlClass) {
142
- return this.$r.inputs.labelControlClass
143
- }
144
- return this.labelControlClass
145
- },
146
- c_inputControlClass() {
147
- if (this.inputControlClass === undefined && this.$r.inputs.inputControlClass) {
148
- return this.$r.inputs.inputControlClass
149
- }
150
- return this.inputControlClass
151
- },
152
- c_color() {
153
- if (this.color === undefined && this.$r.inputs.color) {
154
- return this.$r.inputs.color
155
- }
156
- return this.color || 'color-one-text'
157
- },
158
- c_hide() {
159
- if (this.hide === undefined && this.$r.inputs.hide) {
160
- return this.$r.inputs.hide
161
- }
162
- return this.hide
163
- },
164
- c_tile() {
165
- if (this.tile === undefined && this.$r.inputs.tile) {
166
- return this.$r.inputs.tile
167
- }
168
- return this.tile
169
- },
170
- c_ltr() {
171
- if (this.ltr === undefined && this.$r.inputs.ltr) {
172
- return this.$r.inputs.ltr
173
- }
174
- return this.ltr
175
- },
176
- c_msgShake() {
177
- if (this.msgShake === undefined && this.$r.inputs.msgShake) {
178
- return this.$r.inputs.msgShake
179
- }
180
- return this.msgShake === undefined ? true : this.msgShake
181
- },
182
- c_validateOnBlur() {
183
- if (this.validateOnBlur === undefined && this.$r.inputs.validateOnBlur) {
184
- return this.$r.inputs.validateOnBlur
185
- }
186
- return this.validateOnBlur
187
- }
188
- },
189
- watch: {
190
- rules: {
191
- handler(newVal, oldVal) {
192
- if (this.deepEqual(newVal, oldVal)) return
193
- this.validate()
194
- },
195
-
196
- deep: true
197
- },
198
-
199
- isFocused(val) {
200
- // Should not check validation
201
- // if disabled
202
- if (!val && !this.isDisabled) {
203
- this.hasFocused = true
204
- this.c_validateOnBlur && this.validate()
205
- }
206
- },
207
-
208
- isResetting() {
209
- setTimeout(() => {
210
- this.hasInput = false
211
- this.hasFocused = false
212
- this.isResetting = false
213
- this.validate()
214
- }, 0)
215
- },
216
-
217
- modelValue(val) {
218
- this.hasInput = true
219
- this.lazyValue = val
220
- this.validate()
221
- },
222
- active(val) {
223
- this.focused = val
224
- }
225
159
 
226
- },
227
- methods: {
228
- deepEqual(a, b) {
229
- if (a === b) return true
160
+ /**
161
+ * Validate input on blur event
162
+ * @type {Boolean}
163
+ * @default true
164
+ */
165
+ validateOnBlur: {type: Boolean, default: true}
166
+ })
167
+
168
+ const emit = defineEmits([
169
+ /**
170
+ * Emitted when pre-icon is clicked
171
+ * @param {Boolean} true - Indicates pre-icon was clicked
172
+ */
173
+ 'pre-icon',
174
+
175
+ /**
176
+ * Emitted when icon is clicked
177
+ * @param {Boolean} true - Indicates icon was clicked
178
+ */
179
+ 'icon',
180
+
181
+ /**
182
+ * Emitted when model value changes
183
+ * @param {any} value - New model value
184
+ */
185
+ 'update:modelValue'
186
+ ])
187
+
188
+ const form = inject('form', false)
189
+ const {$r, $v, $helper} = inject('renusify')
190
+
191
+ const uid = ref('input_' + $helper.uniqueId())
192
+ const lazyValue = ref(props.modelValue)
193
+ const errorBucket = ref([])
194
+ const hasFocused = ref(false)
195
+ const hasInput = ref(false)
196
+ const isResetting = ref(false)
197
+ const valid = ref(false)
198
+ const input = ref(null)
199
+
200
+ const computedId = computed(() => props.id || uid.value)
201
+
202
+ const isRequired = computed(() => {
203
+ return props.rules ? (Array.isArray(props.rules) && props.rules.indexOf('required') > -1) : false
204
+ })
205
+
206
+ const isDisabled = computed(() => props.disabled || props.readonly)
207
+
208
+ const hasError = computed(() => {
209
+ if (props.error) {
210
+ return true
211
+ }
212
+ return errorBucket.value.length > 0
213
+ })
230
214
 
231
- if (a instanceof Date && b instanceof Date) {
232
- // If the values are Date, they were convert to timestamp with getTime and compare it
233
- if (a.getTime() !== b.getTime()) return false
234
- }
215
+ const genMessages = computed(() => {
216
+ let m = []
217
+ if (props.msg) {
218
+ m = [props.msg]
219
+ }
220
+ return hasMessages.value ? validations.value : m
221
+ })
222
+
223
+ const hasMessages = computed(() => validationTarget.value.length > 0)
224
+
225
+ const shouldValidate = computed(() => {
226
+ if (isResetting.value) return false
227
+ return hasInput.value || hasFocused.value
228
+ })
229
+
230
+ const validations = computed(() => {
231
+ return validationTarget.value.slice(0, 1)
232
+ })
233
+
234
+ const validationTarget = computed(() => {
235
+ if (shouldValidate.value) {
236
+ return errorBucket.value
237
+ } else return []
238
+ })
239
+
240
+ const activeLabel = computed(() =>
241
+ props.labelActive ||
242
+ ![undefined, '', null].includes(lazyValue.value)
243
+ )
244
+
245
+ /**
246
+ * Deep equality check for two values
247
+ * @param {any} a - First value
248
+ * @param {any} b - Second value
249
+ * @returns {Boolean} True if values are deeply equal
250
+ */
251
+ const deepEqual = (a, b) => {
252
+ if (a === b) return true
253
+
254
+ if (a instanceof Date && b instanceof Date) {
255
+ if (a.getTime() !== b.getTime()) return false
256
+ }
235
257
 
236
- if (a !== Object(a) || b !== Object(b)) {
237
- // If the values aren't objects, they were already checked for equality
238
- return false
239
- }
258
+ if (a !== Object(a) || b !== Object(b)) {
259
+ return false
260
+ }
240
261
 
241
- const props = Object.keys(a)
262
+ const propsA = Object.keys(a)
242
263
 
243
- if (props.length !== Object.keys(b).length) {
244
- // Different number of props, don't bother to check
245
- return false
246
- }
264
+ if (propsA.length !== Object.keys(b).length) {
265
+ return false
266
+ }
247
267
 
248
- return props.every(p => this.deepEqual(a[p], b[p]))
249
- },
250
-
251
- reset() {
252
- this.isResetting = true
253
- this.$emit('update:modelValue', null)
254
- },
255
-
256
- resetValidation() {
257
- this.isResetting = true
258
- },
259
-
260
- validate(force = false, value) {
261
- const errorBucket = []
262
- value = value || this.modelValue
263
- if (force) this.hasInput = this.hasFocused = true
264
- const rules = this.$v(this.rules)
265
- for (let index = 0; index < rules.length; index++) {
266
- const rule = rules[index]
267
- const valid = typeof rule === 'function' ? rule(value) : rule
268
-
269
- if (typeof valid === 'string') {
270
- errorBucket.push(valid)
271
- } else if (typeof valid !== 'boolean') {
272
- console.log(`Rules should return a string or boolean, received '${typeof valid}' instead` + this)
273
- }
274
- }
268
+ return propsA.every(p => deepEqual(a[p], b[p]))
269
+ }
275
270
 
276
- this.errorBucket = errorBucket
277
- this.valid = errorBucket.length === 0
278
- return this.valid
279
- }
271
+ /**
272
+ * Resets input value to null
273
+ */
274
+ const reset = () => {
275
+ isResetting.value = true
276
+ emit('update:modelValue', null)
277
+ }
278
+
279
+ /**
280
+ * Resets validation state
281
+ */
282
+ const resetValidation = () => {
283
+ isResetting.value = true
284
+ }
285
+
286
+ /**
287
+ * Validates input value against rules
288
+ * @param {Boolean} force - Force validation regardless of state
289
+ * @param {any} value - Value to validate (defaults to modelValue)
290
+ * @returns {Boolean} True if validation passes
291
+ */
292
+ const validate = (force = false, value) => {
293
+ const errorBucketLocal = []
294
+ value = value || props.modelValue
295
+ if (force) {
296
+ hasInput.value = true
297
+ hasFocused.value = true
298
+ }
299
+
300
+ const rules = $v ? $v(props.rules) : props.rules
280
301
 
302
+ if (Array.isArray(rules)) {
303
+ for (let index = 0; index < rules.length; index++) {
304
+ const rule = rules[index]
305
+ const validResult = typeof rule === 'function' ? rule(value) : rule
306
+
307
+ if (typeof validResult === 'string') {
308
+ errorBucketLocal.push(validResult)
309
+ } else if (typeof validResult !== 'boolean') {
310
+ console.log(`Rules should return a string or boolean, received '${typeof validResult}' instead`, this)
311
+ }
312
+ }
281
313
  }
282
314
 
315
+ errorBucket.value = errorBucketLocal
316
+ valid.value = errorBucketLocal.length === 0
317
+ return valid.value
283
318
  }
284
319
 
320
+ watch(() => props.rules, (newVal, oldVal) => {
321
+ if (deepEqual(newVal, oldVal)) return
322
+ validate()
323
+ }, {deep: true})
324
+
325
+ watch(isResetting, () => {
326
+ setTimeout(() => {
327
+ hasInput.value = false
328
+ hasFocused.value = false
329
+ isResetting.value = false
330
+ validate()
331
+ }, 0)
332
+ })
333
+
334
+ watch(() => props.modelValue, (val) => {
335
+ hasInput.value = true
336
+ lazyValue.value = val
337
+ validate()
338
+ })
339
+
340
+ validate()
341
+
342
+ onMounted(() => {
343
+ if (input.value) {
344
+ let inp = input.value.querySelector('input')
345
+ if (inp) {
346
+ inp.setAttribute('id', uid.value)
347
+ }
348
+ }
349
+ })
350
+
351
+ if (form) {
352
+ const formInput = {
353
+ uid: uid.value,
354
+ hasError,
355
+ validate: (force = false) => validate(force),
356
+ reset: () => reset(),
357
+ resetValidation: () => resetValidation()
358
+ }
359
+
360
+ form.register(formInput)
361
+
362
+ onBeforeUnmount(() => {
363
+ form.unregister(formInput)
364
+ })
365
+ }
285
366
  </script>
286
367
  <style lang="scss">
287
368
  @use "sass:map";
288
- @use "../../../style/variables/base";
289
- @use "../../../style/mixins";
369
+ @use "../../../style" as *;
290
370
 
291
371
 
292
- .#{base.$prefix}input-container {
372
+ .#{$prefix}input-container {
293
373
  position: relative;
294
374
  align-items: flex-start;
375
+ text-align: start;
295
376
  display: flex;
296
377
  flex: 1 1 auto;
297
378
  flex-direction: column;
@@ -306,35 +387,15 @@ export default {
306
387
  }
307
388
  }
308
389
 
309
- &:not(.input-disabled) {
310
- input,
311
- textarea {
312
- color: var(--color-on-sheet)
313
- }
314
- }
315
-
316
- &:not(.input-disabled) {
317
- .label, .#{base.$prefix}icon, .#{base.$prefix}btn {
318
- color: var(--color-on-sheet-low)
319
- }
320
- }
321
-
322
390
  input::placeholder,
323
391
  textarea::placeholder {
324
- color: var(--color-on-sheet-low)
392
+ color: var(--color-on-sheet-low);
393
+ opacity: 0.7;
325
394
  }
326
395
 
327
396
  &.input-disabled {
328
397
  opacity: 0.38;
329
398
  pointer-events: none;
330
-
331
- * {
332
- color: var(--color-on-sheet)
333
- }
334
-
335
- .input-control {
336
- background-color: var(--color-sheet-container);
337
- }
338
399
  }
339
400
 
340
401
 
@@ -369,54 +430,49 @@ export default {
369
430
 
370
431
  .input-control {
371
432
  display: flex;
372
- flex-direction: column;
373
433
  height: 40px;
374
434
  flex-grow: 1;
375
- flex-wrap: wrap;
376
435
  width: 100%;
377
- align-items: flex-start;
436
+ align-items: center;
378
437
  justify-content: center;
379
438
  position: relative;
380
439
  border: solid 1px var(--color-sheet-low);
381
440
  background-color: var(--color-sheet-container);
441
+ color: var(--color-on-sheet);
442
+ caret-color: var(--color-on-sheet);
443
+ padding: 0 8px;
444
+ border-radius: map.get($borders, 'sm');
445
+ transition: $primary-transition;
446
+
447
+ .input-holder {
448
+ flex-grow: 1;
449
+ border-radius: inherit;
450
+ }
382
451
 
383
- .after-icon {
384
- position: absolute;
452
+ .icon {
385
453
  cursor: pointer;
386
- @include mixins.ltr() {
387
- right: 5px;
454
+ @include ltr() {
455
+ margin-left: 4px;
388
456
  }
389
- @include mixins.rtl() {
390
- left: 5px;
457
+ @include rtl() {
458
+ margin-right: 4px;
391
459
  }
392
460
 
393
461
  }
394
462
 
395
463
  .pre-icon {
396
- position: absolute;
397
464
  cursor: pointer;
398
- @include mixins.ltr() {
399
- left: 5px;
465
+ @include ltr() {
466
+ margin-right: 4px;
400
467
  }
401
- @include mixins.rtl() {
402
- right: 5px;
468
+ @include rtl() {
469
+ margin-left: 4px;
403
470
  }
404
471
 
405
472
  }
406
-
407
- &:not(.input-tile) {
408
- padding: 0 16px;
409
- border-radius: map.get(base.$borders, 'xl');
410
- }
411
-
412
- &.input-tile {
413
- padding: 0 8px;
414
- border-radius: map.get(base.$borders, 'sm');
415
- }
416
473
  }
417
474
 
418
475
  &.hide-detail {
419
-
420
476
  > .input-control {
421
477
  border: unset !important;
422
478
  height: auto;
@@ -430,93 +486,72 @@ export default {
430
486
  position: absolute;
431
487
  z-index: 0;
432
488
  top: 8px;
433
- transition: base.$primary-transition;
489
+ transition: $primary-transition;
434
490
 
435
- @include mixins.ltr() {
436
- left: 15px;
437
- transform-origin: top left;
491
+ @include ltr() {
492
+ left: 10px;
438
493
  }
439
494
 
440
- @include mixins.rtl() {
441
- right: 15px;
442
- transform-origin: top right;
495
+ @include rtl() {
496
+ right: 10px;
443
497
  }
444
498
  }
445
499
 
446
- :not(.input-tile) {
447
- .label-active {
448
- @include mixins.ltr() {
449
- transform: translateY(-27px) translateX(5px) scale(.9);
450
- }
451
- @include mixins.rtl() {
452
- transform: translateY(-27px) translateX(-5px) scale(.9);
453
- }
454
- transition: base.$primary-transition
500
+ .label-margin {
501
+ @include ltr() {
502
+ margin-left: 25px;
455
503
  }
456
- }
457
504
 
458
- .label-fixed {
459
- transform: none !important;
460
- top: -20px !important;
461
- @include mixins.ltr() {
462
- left: 0 !important;
463
- }
464
- @include mixins.rtl() {
465
- right: 0 !important;
505
+ @include rtl() {
506
+ margin-right: 25px;
466
507
  }
467
508
  }
468
509
 
469
- .input-tile {
470
- .label-active {
471
- @include mixins.ltr() {
472
- transform: translateY(-27px) translateX(-8px) scale(.9);
473
- }
474
- @include mixins.rtl() {
475
- transform: translateY(-27px) translateX(8px) scale(.9);
476
- }
477
- transition: base.$primary-transition
510
+ .label-active {
511
+ @include ltr() {
512
+ transform: translateY(-30px) scale(.9);
513
+ left: 0;
514
+ }
515
+ @include rtl() {
516
+ transform: translateY(-30px) scale(.9);
517
+ right: 0;
478
518
  }
519
+ transition: $primary-transition
479
520
  }
480
521
 
522
+
481
523
  &.input-focused {
482
524
  .input-control {
483
- border: solid 1px currentColor;
484
- }
525
+ color: var(--color-one);
526
+ border-color: currentColor;
485
527
 
486
- .#{base.$prefix}icon, .#{base.$prefix}btn {
487
- color: currentColor !important;
528
+ .input-holder {
529
+ color: var(--color-on-sheet);
530
+ }
488
531
  }
489
532
 
490
- :not(.input-tile) {
491
- .label {
492
- color: currentColor !important;
493
- @include mixins.ltr() {
494
- transform: translateY(-27px) translateX(5px) scale(.9);
495
- }
496
- @include mixins.rtl() {
497
- transform: translateY(-27px) translateX(-5px) scale(.9);
498
- }
499
- transition: base.$primary-transition
500
- }
533
+ .#{$prefix}icon, .#{$prefix}btn {
534
+ color: currentColor;
501
535
  }
502
536
 
503
- .input-tile {
504
- .label {
505
- color: currentColor !important;
506
- @include mixins.ltr() {
507
- transform: translateY(-27px) translateX(-8px) scale(.9);
508
- }
509
- @include mixins.rtl() {
510
- transform: translateY(-27px) translateX(8px) scale(.9);
511
- }
512
- transition: base.$primary-transition
537
+ .label {
538
+ color: currentColor;
539
+ @include ltr() {
540
+ transform: translateY(-30px) scale(.9);
541
+ left: 0;
542
+ }
543
+ @include rtl() {
544
+ transform: translateY(-30px) scale(.9);
545
+ right: 0;
513
546
  }
547
+ transition: $primary-transition
514
548
  }
549
+
515
550
  }
516
551
 
517
552
  .massage {
518
553
  display: none;
519
- margin-left: 10px;
554
+ width: 100%;
520
555
 
521
556
  &-active {
522
557
  display: block;
@@ -524,27 +559,31 @@ export default {
524
559
  }
525
560
 
526
561
 
527
- &.color-error-text {
528
- .label {
529
- color: currentColor;
530
- }
562
+ &.input-error {
563
+ color: var(--color-error);
531
564
 
532
565
  .input-control {
533
- border: solid 1px currentColor;
566
+ background: var(--color-error-container);
567
+ color: var(--color-on-error-container);
568
+ caret-color: var(--color-on-error-container);
534
569
  }
535
570
  }
536
571
 
537
- &.#{base.$prefix}text-area {
538
- .input-control {
539
- height: auto;
540
-
541
- &:not(.input-tile) {
542
- border-radius: map.get(base.$borders, 'xl');
543
- }
572
+ &:not(.input-error) {
573
+ .massage-active {
574
+ color: var(--color-info)
544
575
  }
576
+ }
545
577
 
578
+ input[type="number"]::-webkit-outer-spin-button,
579
+ input[type="number"]::-webkit-inner-spin-button {
580
+ -webkit-appearance: none;
581
+ margin: 0;
546
582
  }
547
- }
548
583
 
584
+ input[type="number"] {
585
+ -moz-appearance: textfield;
586
+ }
587
+ }
549
588
 
550
589
  </style>