inertia-bootstrap-forms 1.0.33 → 1.0.35

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.
@@ -1,10 +1,10 @@
1
1
  <script>
2
2
  import {Dropdown, DropdownToggle, DropdownMenu, InputGroup, InputGroupText} from 'vue3-bootstrap-components';
3
- import {computed, inject} from "vue";
3
+ import {computed, defineComponent, inject} from "vue";
4
4
  import QuantityInput from "./QuantityInput.vue";
5
5
  import GroupControl from "./GroupControl.vue";
6
6
 
7
- export default {
7
+ export default defineComponent({
8
8
  components: {GroupControl, QuantityInput, InputGroup, InputGroupText, Dropdown, DropdownToggle, DropdownMenu},
9
9
  props: {
10
10
  name: {
@@ -97,7 +97,7 @@ export default {
97
97
  showDropdown : false,
98
98
  }
99
99
  }
100
- }
100
+ })
101
101
  </script>
102
102
  <template>
103
103
  <div ref="input" class="multi-quantity-input fanum">
@@ -1,7 +1,8 @@
1
1
  <script>
2
2
  import TextInput from "./TextInput.vue";
3
+ import {defineComponent} from "vue";
3
4
 
4
- export default {
5
+ export default defineComponent({
5
6
  components: {
6
7
  TextInput
7
8
  },
@@ -12,7 +13,7 @@ export default {
12
13
  required: true,
13
14
  },
14
15
  },
15
- }
16
+ })
16
17
  </script>
17
18
  <template>
18
19
  <TextInput
@@ -1,8 +1,8 @@
1
1
  <script>
2
2
  import Vue3PersianDatetimePicker from 'vue3-persian-datetime-picker';
3
- import {computed, inject} from "vue";
3
+ import {computed, defineComponent, inject} from "vue";
4
4
 
5
- export default {
5
+ export default defineComponent({
6
6
  components: {Vue3PersianDatetimePicker},
7
7
  props: {
8
8
  name: {
@@ -74,7 +74,7 @@ export default {
74
74
  data() {
75
75
  return {}
76
76
  }
77
- }
77
+ })
78
78
  </script>
79
79
 
80
80
  <template>
@@ -1,8 +1,8 @@
1
1
  <script>
2
2
  import {InputGroup, InputGroupText} from 'vue3-bootstrap-components';
3
- import {computed, inject} from "vue";
3
+ import {computed, defineComponent, inject} from "vue";
4
4
 
5
- export default {
5
+ export default defineComponent({
6
6
  components: {InputGroup, InputGroupText},
7
7
  props: {
8
8
  name: {
@@ -80,7 +80,7 @@ export default {
80
80
  data() {
81
81
  return {}
82
82
  }
83
- }
83
+ })
84
84
  </script>
85
85
  <template>
86
86
  <InputGroup class="input-group-quantity">
@@ -1,13 +1,14 @@
1
1
  <script>
2
2
  import {Spinner} from "vue3-bootstrap-components";
3
+ import {defineComponent} from "vue";
3
4
 
4
- export default {
5
+ export default defineComponent({
5
6
  components: {
6
7
  Spinner
7
8
  },
8
9
  inject: ['form'],
9
10
  props: {},
10
- }
11
+ })
11
12
  </script>
12
13
  <template>
13
14
  <button
@@ -1,9 +1,9 @@
1
1
  <script>
2
2
  import './css/from-select.scss';
3
3
  import Choices from 'choices.js';
4
- import {computed, inject} from "vue";
4
+ import {computed, defineComponent, inject} from "vue";
5
5
 
6
- export default {
6
+ export default defineComponent({
7
7
  emits: ['update:modelValue', 'search', 'change', 'selected'],
8
8
  props: {
9
9
  name: {
@@ -44,6 +44,10 @@ export default {
44
44
  type: Boolean,
45
45
  default: false
46
46
  },
47
+ hideDropdown: {
48
+ type: Boolean,
49
+ default: false
50
+ },
47
51
  search: {
48
52
  type: Object,
49
53
  default: {
@@ -75,6 +79,15 @@ export default {
75
79
 
76
80
  return {modelValue, form, group};
77
81
  },
82
+ computed: {
83
+ selectedValue() {
84
+ if (!this.multiple) {
85
+ return this.modelValue;
86
+ }
87
+
88
+ return (typeof this.modelValue == 'object') ? Object.values(this.modelValue) : (this.modelValue ? [this.modelValue] : null)
89
+ }
90
+ },
78
91
  methods: {
79
92
  init() {
80
93
  this.choices = new Choices(this.$refs.input, {
@@ -175,11 +188,12 @@ export default {
175
188
  },
176
189
  }
177
190
  }
178
- }
191
+ })
179
192
  </script>
180
193
  <template>
181
194
  <div class="select2-controller" :class="{
182
- 'is-invalid': form.errors[name]
195
+ 'is-invalid': form.errors[name],
196
+ 'select2-dropdown-hidden': hideDropdown === true
183
197
  }">
184
198
  <select
185
199
  v-bind="$props"
@@ -192,7 +206,9 @@ export default {
192
206
  }"
193
207
  :placeholder="placeholder"
194
208
  ref="input">
195
- <option :value="item.id" v-for="(item, key) in options" :selected="modelValue === item.id">{{ item.name }}
209
+ <option
210
+ :value="(item.id || item)" v-for="(item, key) in options"
211
+ :selected="multiple ? (selectedValue || []).includes(item.id || item) : (item.id || item) === modelValue">{{ item.name || item }}
196
212
  </option>
197
213
  </select>
198
214
  </div>
@@ -0,0 +1,144 @@
1
+ <script>
2
+ import {defineComponent, inject} from "vue";
3
+
4
+ export default defineComponent({
5
+ props: {
6
+ modelValue: '',
7
+ name: {
8
+ type: String,
9
+ required: true,
10
+ },
11
+ multiple: {
12
+ type: Boolean,
13
+ default: false,
14
+ },
15
+ endpoint: {
16
+ type: String,
17
+ default: '/upload',
18
+ },
19
+ },
20
+ setup(props) {
21
+ let form = inject('form');
22
+
23
+ if (form === undefined) {
24
+ form = {
25
+ errors: {},
26
+ getID(name) {
27
+ }
28
+ };
29
+ }
30
+
31
+ return {form};
32
+ },
33
+ computed: {
34
+ allFiles() {
35
+ return this.files
36
+ },
37
+ },
38
+ methods: {
39
+ addFile(file) {
40
+ let uploadedFile = {
41
+ id: crypto.randomUUID(),
42
+ percent: 0,
43
+ error: 0,
44
+ file: file,
45
+ };
46
+
47
+ if (this.multiple) {
48
+ this.files.push(uploadedFile);
49
+ } else {
50
+ this.files = [uploadedFile];
51
+ }
52
+
53
+ this.uploadFile(uploadedFile);
54
+ this.$refs.input.value = '';
55
+ },
56
+ calculatePercent(event, file) {
57
+ if (event.lengthComputable) {
58
+ this.files.find(item => item.id === file.id)['percent'] = Math.round((event.loaded / event.total) * 100);
59
+ }
60
+ },
61
+ addFileToInputValue(file, res) {
62
+ this.files.find(item => item.id === file.id).path = res.data.path;
63
+
64
+ this.form[this.name] = this.multiple ? this.files.map(item => item.path) : this.files[0].path;
65
+ this.$emit('update:modelValue', this.form[this.name]);
66
+ },
67
+ async uploadFile(file) {
68
+ let _this = this;
69
+ let formData = new FormData();
70
+ formData.append('file', file.file);
71
+ _this.files.find(item => item.id === file.id)['error'] = '';
72
+
73
+ await fetch(this.endpoint,
74
+ {
75
+ method: 'POST',
76
+ headers: {
77
+ 'Accept': 'application/json',
78
+ },
79
+ body: formData,
80
+ },
81
+ )
82
+ .then(response => response.json())
83
+ .then(function (res) {
84
+ _this.addFileToInputValue(file, res)
85
+ }).catch(function (err) {
86
+ console.error('error on uploader', err);
87
+ _this.files.find(item => item.id === file.id)['error'] = (err.response?.data?.message || err.message);
88
+ });
89
+ },
90
+ async deleteFile(file) {
91
+ this.files = this.files.filter(item => item.id !== file.id);
92
+ await fetch(this.endpoint, {
93
+ method: 'DELETE',
94
+ body: file.path
95
+ });
96
+ },
97
+ fileSelected(e) {
98
+ Array.from(e.target.files).forEach(file => this.addFile(file));
99
+ }
100
+ },
101
+ data() {
102
+ return {
103
+ files: [],
104
+ }
105
+ }
106
+ })
107
+ </script>
108
+ <template>
109
+ <div class="file-input-uploader">
110
+ <input
111
+ ref="input"
112
+ :name="name"
113
+ :class="{'is-invalid': form?.errors[name] !== undefined}"
114
+ :disabled="form?.processing"
115
+ type="file"
116
+ :multiple="multiple"
117
+ @change="fileSelected"
118
+ class="form-control">
119
+ <div class="file-input-uploader--list">
120
+ <div :id="'file-'+file.id" class="file-input-uploader--list-item" v-for="file in allFiles">
121
+ <div class="file-input-uploader--progress" v-if="file.percent && file.percent< 100">
122
+ <div :style="{width: file.percent + '%'}"></div>
123
+ </div>
124
+ <div>{{ file.file.name }}</div>
125
+ <div class="file-input-uploader--list-error" v-if="file.error">{{ file.error }}</div>
126
+ <div class="file-input-uploader--list-item--size" dir="ltr">{{ Math.round(file.file.size / 1024) }}Kb</div>
127
+ <div class="file-input-uploader--list-item--actions">
128
+ <button @click="uploadFile(file)" type="button" class="file-input-uploader--list-item--btn" v-if="file.error">
129
+ <svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
130
+ <path
131
+ d="M1,12A11,11,0,0,1,17.882,2.7l1.411-1.41A1,1,0,0,1,21,2V6a1,1,0,0,1-1,1H16a1,1,0,0,1-.707-1.707l1.128-1.128A8.994,8.994,0,0,0,3,12a1,1,0,0,1-2,0Zm21-1a1,1,0,0,0-1,1,9.01,9.01,0,0,1-9,9,8.9,8.9,0,0,1-4.42-1.166l1.127-1.127A1,1,0,0,0,8,17H4a1,1,0,0,0-1,1v4a1,1,0,0,0,.617.924A.987.987,0,0,0,4,23a1,1,0,0,0,.707-.293L6.118,21.3A10.891,10.891,0,0,0,12,23,11.013,11.013,0,0,0,23,12,1,1,0,0,0,22,11Z"/>
132
+ </svg>
133
+ </button>
134
+ <button @click="deleteFile(file)" type="button" class="file-input-uploader--list-item--btn" v-if="file.path || file.error">
135
+ <svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
136
+ <path
137
+ d="M12,23A11,11,0,1,0,1,12,11.013,11.013,0,0,0,12,23ZM12,3a9,9,0,1,1-9,9A9.01,9.01,0,0,1,12,3ZM8.293,14.293,10.586,12,8.293,9.707A1,1,0,0,1,9.707,8.293L12,10.586l2.293-2.293a1,1,0,0,1,1.414,1.414L13.414,12l2.293,2.293a1,1,0,1,1-1.414,1.414L12,13.414,9.707,15.707a1,1,0,0,1-1.414-1.414Z"/>
138
+ </svg>
139
+ </button>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ </div>
144
+ </template>
@@ -1,7 +1,7 @@
1
1
  <script>
2
- import {inject} from 'vue';
2
+ import {defineComponent, inject} from 'vue';
3
3
 
4
- export default {
4
+ export default defineComponent({
5
5
  emits: ['update:modelValue'],
6
6
  props: {
7
7
  name: {
@@ -98,7 +98,7 @@ export default {
98
98
  isRTL: false,
99
99
  }
100
100
  }
101
- }
101
+ })
102
102
  </script>
103
103
  <template>
104
104
  <div class="star-rating">
@@ -1,13 +1,14 @@
1
1
  <script>
2
2
  import {Spinner} from 'vue3-bootstrap-components';
3
+ import {defineComponent} from "vue";
3
4
 
4
- export default {
5
+ export default defineComponent({
5
6
  components: {
6
7
  Spinner
7
8
  },
8
9
  inject: ['form'],
9
10
  props: {},
10
- }
11
+ })
11
12
  </script>
12
13
  <template>
13
14
  <button
package/src/TelInput.vue CHANGED
@@ -1,9 +1,9 @@
1
1
  <script>
2
2
  import {VueTelInput} from 'vue-tel-input';
3
3
  import 'vue-tel-input/vue-tel-input.css';
4
- import {inject} from "vue";
4
+ import {defineComponent, inject} from "vue";
5
5
 
6
- export default {
6
+ export default defineComponent({
7
7
  components: {
8
8
  VueTelInput
9
9
  },
@@ -44,7 +44,7 @@ export default {
44
44
  valid: null,
45
45
  }
46
46
  }
47
- }
47
+ })
48
48
  </script>
49
49
  <template>
50
50
  <div class="telephone-input input-group fanum" dir="ltr">
@@ -1,7 +1,7 @@
1
1
  <script>
2
- import {computed, inject} from "vue";
2
+ import {computed, defineComponent, inject} from "vue";
3
3
 
4
- export default {
4
+ export default defineComponent({
5
5
  props: {
6
6
  name: {
7
7
  type: String,
@@ -32,7 +32,7 @@ export default {
32
32
 
33
33
  return {modelValue, form, group};
34
34
  },
35
- }
35
+ })
36
36
  </script>
37
37
  <template>
38
38
  <textarea
package/src/TextInput.vue CHANGED
@@ -1,7 +1,7 @@
1
1
  <script>
2
- import {computed, inject} from "vue";
2
+ import {computed, inject, defineComponent} from "vue";
3
3
 
4
- export default {
4
+ export default defineComponent({
5
5
  props: {
6
6
  name: {
7
7
  type: String,
@@ -37,7 +37,7 @@ export default {
37
37
 
38
38
  return {modelValue, form, group};
39
39
  },
40
- }
40
+ })
41
41
  </script>
42
42
  <template>
43
43
  <input
@@ -84,7 +84,7 @@
84
84
  height: 0;
85
85
  width: 0;
86
86
  border-style: solid;
87
- border-color: #333 transparent transparent;
87
+ border-color: var(--bs-secondary-color, #333) transparent transparent;
88
88
  border-width: 5px;
89
89
  position: absolute;
90
90
  right: 11.5px;
@@ -94,7 +94,7 @@
94
94
  }
95
95
 
96
96
  .choices[data-type*=select-one].is-open::after {
97
- border-color: transparent transparent #333;
97
+ border-color: transparent transparent var(--bs-secondary-color, #333);
98
98
  margin-top: -7.5px
99
99
  }
100
100
 
@@ -137,7 +137,7 @@
137
137
  width: 100%;
138
138
  background-color: var(--bs-body-bg, #ffffff);
139
139
  padding: calc(.5rem - 4px) .75rem calc(.5rem - 4px) .75rem;
140
- border: 1px solid #ddd;
140
+ border: 1px solid var(--bs-border-color, #ddd);
141
141
  border-radius: var(--bs-border-radius);
142
142
  font-size: var(--bs-body-font-size);
143
143
  min-height: 44px;
@@ -148,15 +148,16 @@
148
148
  border-color: var(--bs-danger, #de0021);
149
149
  }
150
150
 
151
- .is-focused .choices__inner, .is-open .choices__inner {
151
+ .is-focused .choices__inner,
152
+ .is-open .choices__inner {
152
153
  border-color: #b7b7b7
153
154
  }
154
155
 
155
- .is-open .choices__inner {
156
+ .select2-controller:not(.select2-dropdown-hidden) .is-open .choices__inner {
156
157
  border-radius: var(--bs-border-radius) var(--bs-border-radius) 0 0
157
158
  }
158
159
 
159
- .is-flipped.is-open .choices__inner {
160
+ .select2-controller:not(.select2-dropdown-hidden) .is-flipped.is-open .choices__inner {
160
161
  border-radius: 0 0 var(--bs-border-radius) var(--bs-border-radius)
161
162
  }
162
163
 
@@ -195,8 +196,8 @@
195
196
  font-weight: 500;
196
197
  margin-right: 3.75px;
197
198
  margin-bottom: 3.75px;
198
- background-color: var(--bs-body-secondary, #999999);
199
- border: 1px solid var(--bs-body-secondary, #999999);
199
+ background-color: var(--bs-secondary-bg, #999999);
200
+ border: 1px solid var(--bs-secondary-bg, #999999);
200
201
  color: var(--bs-body-color, #ffffff);
201
202
  word-break: break-all;
202
203
  box-sizing: border-box
@@ -221,13 +222,17 @@
221
222
  border: 1px solid var(--bs-secondary, #003642)
222
223
  }
223
224
 
225
+ .select2-dropdown-hidden .choices__list--dropdown{
226
+ display: none !important;
227
+ }
228
+
224
229
  .choices__list--dropdown, .choices__list[aria-expanded] {
225
230
  display: none;
226
231
  z-index: 99999;
227
232
  position: absolute;
228
233
  width: 100%;
229
- background-color: var(--bs-secondary-bg, #ddd);
230
- border: 1px solid var(--bs-secondary-bg, #ddd);
234
+ background-color: var(--bs-body-bg, #ddd);
235
+ border: 1px solid var(--bs-body-bg, #ddd);
231
236
  top: 100%;
232
237
  margin-top: -1px;
233
238
  border-bottom-left-radius: var(--bs-border-radius);
@@ -295,7 +300,7 @@
295
300
  }
296
301
 
297
302
  .choices__list--dropdown .choices__item--selectable.is-highlighted, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted {
298
- background-color: #f2f2f2
303
+ background-color: var(--bs-secondary-bg, #ddd)
299
304
  }
300
305
 
301
306
  .choices__list--dropdown .choices__item--selectable.is-highlighted::after, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted::after {
@@ -348,7 +353,7 @@
348
353
  .choices__input {
349
354
  display: inline-block;
350
355
  vertical-align: baseline;
351
- background-color: #f9f9f9;
356
+ background-color: var(--bs-body-bg, #f7f7f7);
352
357
  font-size: var(--bs-body-font-size);
353
358
  border: 0;
354
359
  border-radius: 0;
@@ -0,0 +1,44 @@
1
+ .location-map-container {
2
+ position: relative;
3
+ width: 100%;
4
+ height: 300px;
5
+ overflow: hidden;
6
+ border-radius: var(--bs-border-radius);
7
+ }
8
+
9
+ .location-map-container.is-invalid {
10
+ border: 1px solid var(--bs-form-invalid-border-color);
11
+ }
12
+
13
+ .location-map-container[disabled],
14
+ .location-map-container.disabled:before {
15
+ content: "";
16
+ background-color: rgba(var(--bs-light-rgb), 0.4);
17
+ display: block;
18
+ position: absolute;
19
+ top: 0;
20
+ right: 0;
21
+ left: 0;
22
+ bottom: 0;
23
+ z-index: 9999;
24
+ }
25
+
26
+ .location-map-container {
27
+ .leaflet-pane,
28
+ .leaflet-tile,
29
+ .leaflet-marker-icon,
30
+ .leaflet-marker-shadow,
31
+ .leaflet-tile-container,
32
+ .leaflet-pane > svg,
33
+ .leaflet-pane > canvas,
34
+ .leaflet-zoom-box,
35
+ .leaflet-image-layer,
36
+ .leaflet-layer {
37
+ left: auto;
38
+ right: 0;
39
+ }
40
+
41
+ .leaflet-control-attribution.leaflet-control {
42
+ display: none;
43
+ }
44
+ }
@@ -0,0 +1,54 @@
1
+ .file-input-uploader .file-input-uploader--list .file-input-uploader--list-item {
2
+ background-color: var(--bs-secondary-bg);
3
+ border-radius: var(--bs-border-radius);
4
+ position: relative;
5
+ display: flex;
6
+ align-items: center;
7
+ margin: 5px 0;
8
+ padding: 5px 10px;
9
+ }
10
+
11
+ .file-input-uploader .file-input-uploader--list .file-input-uploader--list-item--size {
12
+ margin-left: auto;
13
+ font-size: 90%;
14
+ padding: 0 5px;
15
+ color: var(--bs-secondary-color);
16
+ }
17
+
18
+ .file-input-uploader .file-input-uploader--list-item--btn {
19
+ display: inline-block;
20
+ outline: none;
21
+ border: 0;
22
+ padding: 7px 2px;
23
+ }
24
+
25
+ .file-input-uploader .file-input-uploader--list-item--btn:not(:last-child){
26
+ margin-right: 5px;
27
+ }
28
+
29
+ .file-input-uploader .file-input-uploader--list-item--btn > svg {
30
+ height: 20px;
31
+ width: 20px;
32
+ vertical-align: middle;
33
+ }
34
+
35
+ .file-input-uploader .file-input-uploader--progress {
36
+ position: absolute;
37
+ top: 2px;
38
+ left: 5px;
39
+ right: 5px;
40
+ }
41
+
42
+ .file-input-uploader .file-input-uploader--progress > div {
43
+ background-color: #de0021;
44
+ height: 7px;
45
+ width: 0;
46
+ min-width: 1%;
47
+ border-radius: var(--bs-border-radius)
48
+ }
49
+
50
+ .file-input-uploader .file-input-uploader--list-error {
51
+ font-size: 90%;
52
+ margin: 0 5px;
53
+ color: var(--bs-danger, #de0021);
54
+ }
package/src/index.js CHANGED
@@ -22,6 +22,8 @@ import SubmitButton from "./SubmitButton.vue";
22
22
  import TelInput from "./TelInput.vue";
23
23
  import TextAreaInput from "./TextAreaInput.vue";
24
24
  import TextInput from "./TextInput.vue";
25
+ import DropzoneInput from "./DropzoneInput.vue";
26
+ import SimpleUploader from "./SimpleUploader.vue";
25
27
 
26
28
  export {
27
29
  AmountInput,
@@ -33,6 +35,8 @@ export {
33
35
  EmailInput,
34
36
  PersianDatePickerInput,
35
37
  EditorInput,
38
+ DropzoneInput,
39
+ SimpleUploader,
36
40
  GroupControl,
37
41
  FormContainer,
38
42
  LocationInput,