renusify 2.5.0 → 2.5.2

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,5 +1,5 @@
1
1
  <template>
2
- <r-modal :closebtn="false" :model-value="modelValue">
2
+ <r-modal :model-value="modelValue" no-close-btn>
3
3
  <r-container class="container-fluid">
4
4
  <r-row>
5
5
  <r-col class="col-12 text-center">
@@ -2,7 +2,7 @@
2
2
  <r-input class="mt-5" :model-value="modelValue" hide labelControlClass="label-active"
3
3
  :class="`${$r.prefix}color-picker`">
4
4
  <div :style="{'background-color':modelValue||'#ffffff'}" class="shower" @click.prevent="open=true"></div>
5
- <r-modal v-model="open" :closebtn="false" class="color-picker-modal" closable maxWidth="260px">
5
+ <r-modal v-model="open" class="color-picker-modal" maxWidth="260px" no-close-btn>
6
6
  <picker :color="modelValue" @changeColor="emit"></picker>
7
7
  <div class="d-flex h-space-between">
8
8
  <r-btn class="color-success flex-grow-1 me-1" outlined @click.prevent="close()">
@@ -2,20 +2,24 @@ export const color = {
2
2
  methods: {
3
3
  setColorValue(color) {
4
4
  let rgba = {r: 0, g: 0, b: 0, a: 1}
5
- if (/#/.test(color)) {
5
+ const rgbRegex = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*([01]?\.\d+)?\s*)?\)$/;
6
+ const hexRegex = /^#([a-f0-9]{6}|[a-f0-9]{8})$/i;
7
+ if (hexRegex.test(color)) {
6
8
  rgba = this.hex2rgba(color)
7
- } else if (/rgb/.test(color)) {
9
+ } else if (rgbRegex.test(color)) {
8
10
  rgba = this.rgb2rgba(color)
9
11
  } else if (Object.prototype.toString.call(color) === '[object Object]') {
10
12
  rgba = color
13
+ } else {
14
+ return
11
15
  }
12
16
  this.r = rgba.r
13
17
  this.g = rgba.g
14
18
  this.b = rgba.b
15
- if (rgba.a >= 0) {
19
+ if (rgba.a >= 0 && rgba.a <= 1) {
16
20
  this.a = rgba.a
17
21
  } else {
18
- this.a = rgba.a || 1
22
+ this.a = 1
19
23
  }
20
24
 
21
25
  this.set_hsv(rgba)
@@ -56,20 +60,35 @@ export const color = {
56
60
  ctx.fillStyle = gradient
57
61
  ctx.fillRect(0, 0, width, height)
58
62
  },
59
- rgb2hex({r, g, b}, toUpper) {
60
- const change = (val) => ('0' + Number(val).toString(16)).slice(-2)
61
- const color = `#${change(r)}${change(g)}${change(b)}`
62
- return toUpper ? color.toUpperCase() : color
63
+ rgb2hex({r, g, b, a}, toUpper = false) {
64
+ const change = (val) => {
65
+ const hex = Math.round(val).toString(16);
66
+ return hex.length === 1 ? '0' + hex : hex;
67
+ };
68
+
69
+ let color = `#${change(r)}${change(g)}${change(b)}`;
70
+
71
+ if (a !== undefined && a !== 1) {
72
+ const alpha = Math.round(a * 255);
73
+ color += change(alpha);
74
+ }
75
+
76
+ return toUpper ? color.toUpperCase() : color;
63
77
  },
64
78
  hex2rgba(hex) {
65
79
  hex = hex.slice(1)
66
- const change = (val) => parseInt(val, 16) || 0 // Avoid NaN situations
67
- return {
68
- r: change(hex.slice(0, 2)),
69
- g: change(hex.slice(2, 4)),
70
- b: change(hex.slice(4, 6)),
71
- a: 1
80
+ const change = (val) => parseInt(val, 16) || 0;
81
+ const r = change(hex.slice(0, 2));
82
+ const g = change(hex.slice(2, 4));
83
+ const b = change(hex.slice(4, 6));
84
+
85
+ let a = 1;
86
+ if (hex.length === 8) {
87
+ const alphaHex = hex.slice(6, 8);
88
+ a = parseFloat((parseInt(alphaHex, 16) / 255).toFixed(2));
72
89
  }
90
+
91
+ return {r, g, b, a};
73
92
  },
74
93
  rgb2rgba(rgba) {
75
94
  rgba = (/rgba?\((.*?)\)/.exec(rgba) || ['', '0,0,0,1'])[1].split(',')
@@ -129,9 +129,6 @@ export default {
129
129
  },
130
130
  inputHex(color) {
131
131
  const value = color.target.value
132
- if (value.length !== 7) {
133
- return
134
- }
135
132
  this.setColorValue(value)
136
133
  this.$nextTick(() => {
137
134
 
@@ -4,7 +4,7 @@
4
4
  {{ modelValue ? $d(modelValueDate, withTime ? 'long' : 'medium', locale) : null }}
5
5
  </div>
6
6
  </r-input>
7
- <r-modal :model-value="show" @update:model-value="close()" :closebtn="false" closable class="text-center">
7
+ <r-modal :model-value="show" class="text-center" no-close-btn @update:model-value="close()">
8
8
  <div v-if="!showTime" :class="`${$r.prefix}date-input`">
9
9
  <div>
10
10
  <r-container>
@@ -5,7 +5,7 @@
5
5
  :active="active"
6
6
  inputControlClass="v-center"
7
7
  >
8
- <r-btn @click.prevent.stop="minus" class="minus" icon :text="btnText">
8
+ <r-btn :disabled="min!==undefined&&number<=min" :text="btnText" class="minus" icon @click.prevent.stop="minus">
9
9
  <r-icon v-html="$r.icons.minus"></r-icon>
10
10
  </r-btn>
11
11
  <input @input="emit"
@@ -18,7 +18,7 @@
18
18
  autocomplete="no"
19
19
  v-model="number"
20
20
  />
21
- <r-btn @click.prevent.stop="plus" class="plus" icon :text="btnText">
21
+ <r-btn :disabled="max!==undefined&&number>=max" :text="btnText" class="plus" icon @click.prevent.stop="plus">
22
22
  <r-icon v-html="$r.icons.plus"></r-icon>
23
23
  </r-btn>
24
24
  </r-input>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div :class="`${$r.prefix}input-tel`">
3
3
  <r-btn :disabled="!select||readonly"
4
- :rounded="!c_tile" class="btn-country ltr ms-1" outlined @click.stop="toggleDropdown">
4
+ :rounded="!c_tile" class="btn-country ltr mr-1" outlined @click.stop="toggleDropdown">
5
5
  <div :class="activeCountry.iso2.toLowerCase()" class="iti-flag"></div>
6
6
  <span class="country-code pa-1"> +{{ activeCountry.dialCode }} </span>
7
7
  <span class="dropdown-arrow">{{ open ? "▲" : "▼" }}</span>
@@ -152,7 +152,7 @@ export default {
152
152
 
153
153
  .#{base.$prefix}input-tel {
154
154
  display: flex;
155
- align-items: baseline;
155
+ align-items: end;
156
156
  direction: ltr;
157
157
  flex-wrap: wrap;
158
158
  .btn-country {
@@ -75,8 +75,7 @@
75
75
  </r-col>
76
76
  </r-row>
77
77
  <r-modal v-model="show"
78
- :closable="false"
79
- :closebtn="false">
78
+ no-closable no-close-btn>
80
79
  <r-form v-model="valid1">
81
80
  <r-container>
82
81
  <r-row>
@@ -109,8 +108,7 @@
109
108
  </r-form>
110
109
  </r-modal>
111
110
  <r-modal v-model="showImg"
112
- :closable="false"
113
- :closebtn="false">
111
+ no-closable no-close-btn>
114
112
  <r-form v-model="valid2">
115
113
  <r-container>
116
114
  <r-file-input v-model="image"
@@ -144,8 +142,7 @@
144
142
  </r-form>
145
143
  </r-modal>
146
144
  <r-modal v-model="showVideo"
147
- :closable="false"
148
- :closebtn="false">
145
+ no-closable no-close-btn>
149
146
  <r-form v-model="valid2">
150
147
  <r-container>
151
148
  <r-file-input v-model="video"
@@ -178,8 +175,7 @@
178
175
  </r-form>
179
176
  </r-modal>
180
177
  <r-modal v-model="showPre"
181
- :closable="false"
182
- :closebtn="false">
178
+ no-closable no-close-btn>
183
179
  <r-form v-model="valid2">
184
180
  <r-container>
185
181
  <r-text-input v-model="code_name" :label="$t('name','renusify')"></r-text-input>
@@ -206,8 +202,7 @@
206
202
  </r-form>
207
203
  </r-modal>
208
204
  <r-modal v-model="showTable"
209
- :closable="false"
210
- :closebtn="false">
205
+ no-closable no-close-btn>
211
206
  <r-form v-model="valid2">
212
207
  <r-container>
213
208
  <r-select-input v-model="table_form.headers"
@@ -19,7 +19,7 @@
19
19
  <r-modal
20
20
  class="modal-timepicker"
21
21
  v-model="show_modal"
22
- :closebtn="false"
22
+ no-close-btn
23
23
  :no-overlay="noOverlay"
24
24
  >
25
25
  <div class="pt-3 pb-1">
@@ -18,7 +18,7 @@
18
18
  <r-modal
19
19
  class="modal-timepicker"
20
20
  v-model="show_modal"
21
- :closebtn="false"
21
+ no-close-btn
22
22
  :no-overlay="noOverlay"
23
23
  >
24
24
  <div class="pt-3">
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <div ref="container"
3
+ class="ltr"
3
4
  :class="{ [$r.prefix+'img-preview-container']:true}">
4
5
  <div
5
6
  :style="wrapperStyle"
@@ -1,34 +1,35 @@
1
1
  <template>
2
- <teleport v-if="show" :to="`.${$r.prefix}app`">
3
- <div v-if="modelValue&&!noOverlay" :class="{
4
- [`${$r.prefix}modal-overlay`]:true
5
- }"></div>
6
- <transition :name="c_animate">
7
- <div v-if="modelValue" :class="{
8
- [`${$r.prefix}modal`]:true,
9
- 'h-end': bottom||fullHeight,
10
- 'animate-modal-vibrate': run_animate,
11
- }" v-bind="$attrs" @click.self="close"
12
- >
13
- <div class="modal-container" :style="{'max-width':maxWidth,'max-height':maxHeight}" :class="{
14
- 'modal-bottom':bottom,
15
- [color]:color,
16
- 'modal-full-width':fullWidth,
17
- 'modal-full-height':fullHeight,
18
- 'modal-mini':minWidth,
19
- 'modal-flat':flat
2
+ <teleport v-if="mounted" :to="`.${$r.prefix}app`">
3
+ <div
4
+ v-if="modelValue && !noOverlay"
5
+ :class="`${$r.prefix}modal-overlay`"
6
+ ></div>
20
7
 
21
- }">
8
+ <transition :name="computedAnimation">
9
+ <div
10
+ v-if="modelValue"
11
+ :class="modalClasses"
12
+ v-bind="$attrs"
13
+ @click.self="close()"
14
+ >
15
+ <div
16
+ :class="containerClasses"
17
+ :style="containerStyles"
18
+ class="modal-container"
19
+ >
22
20
  <div class="modal-btn text-end">
23
- <r-btn class="color-error-text"
24
- text
25
- @click.prevent="close(true)"
26
- fab
27
- size="small"
28
- v-if="closebtn">
21
+ <r-btn
22
+ v-if="!noCloseBtn"
23
+ class="color-error-text"
24
+ fab
25
+ size="small"
26
+ text
27
+ @click.prevent="close(true)"
28
+ >
29
29
  <r-icon v-html="$r.icons.close"></r-icon>
30
30
  </r-btn>
31
31
  </div>
32
+
32
33
  <div class="modal-content">
33
34
  <slot></slot>
34
35
  </div>
@@ -45,123 +46,169 @@ export default {
45
46
  name: 'r-modal',
46
47
  inheritAttrs: false,
47
48
  props: {
48
- modelValue: Boolean,
49
- bottom: Boolean,
49
+ modelValue: {
50
+ type: Boolean,
51
+ required: true
52
+ },
53
+ position: {
54
+ type: String,
55
+ default: 'center',
56
+ validator: (value) => ['center', 'bottom', 'start', 'end', 'top'].includes(value)
57
+ },
50
58
  noOverlay: Boolean,
51
59
  fullWidth: Boolean,
52
60
  fullHeight: Boolean,
53
- maxWidth: String,
54
- maxHeight: String,
55
- minWidth: {type: Boolean, default: true},
56
- flat: Boolean,
57
- closable: Boolean,
61
+ maxWidth: {
62
+ type: String,
63
+ default: null
64
+ },
65
+ maxHeight: {
66
+ type: String,
67
+ default: null
68
+ },
69
+ minWidth: {
70
+ type: Boolean,
71
+ default: true
72
+ },
73
+ noClosable: Boolean,
74
+ noCloseBtn: Boolean,
58
75
  routeHistory: String,
59
- closebtn: {type: Boolean, default: true},
60
76
  color: String,
61
- animate: String
77
+ animation: String
62
78
  },
63
79
  emits: ['update:modelValue'],
64
80
  data() {
65
81
  return {
66
- state: null,
67
- run_animate: false,
68
- show: false,
82
+ mounted: false,
83
+ runAnimation: false
69
84
  }
70
85
  },
71
86
  created() {
72
- if (this.routeHistory) {
73
- const h = this.$route.hash.replace('#', '').split('&')
74
- if (h.includes(this.routeHistory)) {
75
- this.$emit('update:modelValue', true)
76
- }
77
- }
78
- setTimeout(()=>{
79
- this.show=true
80
- },10)
87
+ this.initFromRoute();
88
+ setTimeout(() => {
89
+ this.mounted = true;
90
+ }, 10);
81
91
  },
82
92
  watch: {
83
- '$route': function (n) {
84
- let h = []
85
- if (this.$route.hash) {
86
- h = this.$route.hash.replace('#', '').split('&')
87
- }
88
- if (!h.includes(this.routeHistory)) {
89
- this.$emit('update:modelValue', false)
90
- } else {
91
- this.$emit('update:modelValue', true)
93
+ '$route': 'handleRouteChange',
94
+ modelValue: 'handleModelValueChange'
95
+ },
96
+ computed: {
97
+ computedAnimation() {
98
+ if (this.animation) return this.animation;
99
+
100
+ switch (this.position) {
101
+ case 'bottom':
102
+ return 'slide-up';
103
+ case 'top':
104
+ return 'slide-down';
105
+ case 'start':
106
+ return 'slide-end';
107
+ case 'end':
108
+ return 'slide-start';
109
+ default:
110
+ return 'scale';
92
111
  }
93
112
  },
94
- modelValue: {
95
- // immediate: true, watch at created component
96
- handler: function (newVal, oldVal) {
97
- if (newVal === true) {
98
- document.documentElement.style.overflow = 'hidden'
99
- if (this.routeHistory) {
100
- const routeHashs = this.$route.hash.replace('#', '').split('&')
101
- if (!routeHashs.includes(this.routeHistory)) {
102
- let h = ''
103
- if (this.$route.hash) {
104
- h = this.$route.hash + '&' + this.routeHistory
105
- } else {
106
- h = '#' + this.routeHistory
107
- }
108
- this.$router.push({path: this.$route.fullPath, hash: h})
109
- }
110
- }
111
- } else {
112
- document.documentElement.style.overflow = null
113
+ modalClasses() {
114
+ return [
115
+ `${this.$r.prefix}modal`,
116
+ `modal-${this.position}`,
117
+ {
118
+ 'animate-modal-vibrate': this.runAnimation
113
119
  }
114
- }
120
+ ];
121
+ },
122
+ containerClasses() {
123
+ return [
124
+ this.color,
125
+ {
126
+ 'modal-full-width': this.fullWidth,
127
+ 'modal-full-height': this.fullHeight,
128
+ 'modal-mini': this.minWidth,
129
+ [`modal-${this.position}`]: this.position !== 'center'
130
+ }
131
+ ];
132
+ },
133
+ containerStyles() {
134
+ return {
135
+ 'max-width': this.maxWidth,
136
+ 'max-height': this.maxHeight
137
+ };
115
138
  }
116
139
  },
117
- computed: {
118
- c_animate() {
119
- if (this.animate) {
120
- return this.animate
140
+ methods: {
141
+ initFromRoute() {
142
+ if (!this.routeHistory) return;
143
+
144
+ const hashValues = this.$route.hash.replace('#', '').split('&');
145
+ if (hashValues.includes(this.routeHistory)) {
146
+ this.$emit('update:modelValue', true);
121
147
  }
122
- if (this.bottom) {
123
- return 'slide-up'
148
+ },
149
+ handleRouteChange(newRoute) {
150
+ if (!this.routeHistory) return;
151
+
152
+ const hashValues = newRoute.hash.replace('#', '').split('&');
153
+ this.$emit('update:modelValue', hashValues.includes(this.routeHistory));
154
+ },
155
+ handleModelValueChange(isOpen) {
156
+ if (isOpen) {
157
+ document.documentElement.style.overflow = 'hidden';
158
+ this.handleOpenState();
159
+ } else {
160
+ document.documentElement.style.overflow = null;
124
161
  }
125
- if (this.fullHeight) {
126
- return 'slide-up'
162
+ },
163
+ handleOpenState() {
164
+ if (!this.routeHistory) return;
165
+
166
+ const hashValues = this.$route.hash.replace('#', '').split('&');
167
+ if (!hashValues.includes(this.routeHistory)) {
168
+ const newHash = this.$route.hash
169
+ ? `${this.$route.hash}&${this.routeHistory}`
170
+ : `#${this.routeHistory}`;
171
+
172
+ this.$router.push({
173
+ path: this.$route.fullPath,
174
+ hash: newHash
175
+ });
127
176
  }
128
- return 'scale'
129
- }
130
- },
131
- methods: {
177
+ },
132
178
  close(force = false) {
133
- if (this.closable || force === true) {
134
- if (this.routeHistory) {
135
- if (history.state.back) {
136
- this.$router.back()
137
- } else {
138
- let h = ''
139
- if (this.$route.hash) {
140
- h = this.$route.hash.replace('#', '').split('&')
141
- h.splice(h.indexOf(this.routeHistory), 1)
142
- let s = ''
143
- let first = true
144
- h.forEach((item) => {
145
- if (item) {
146
- s += (first ? '#' : '&') + item
147
- }
148
- })
149
- h = s
150
- }
151
- this.$router.replace({'path': this.$route.fullPath, hash: h})
152
- }
153
- }
154
- this.$emit('update:modelValue', false)
155
- } else {
156
- this.run_animate = true
157
- setTimeout(() => {
158
- this.run_animate = false
159
- }, 300)
179
+ if (this.noClosable && !force) {
180
+ this.runAnimation = true;
181
+ setTimeout(() => this.runAnimation = false, 300);
182
+ return;
160
183
  }
184
+
185
+ if (this.routeHistory) {
186
+ this.handleRouteClose();
187
+ }
188
+
189
+ this.$emit('update:modelValue', false);
190
+ },
191
+ handleRouteClose() {
192
+ if (history.state.back) {
193
+ this.$router.back();
194
+ return;
195
+ }
196
+
197
+ let hashValues = this.$route.hash.replace('#', '').split('&');
198
+ hashValues = hashValues.filter(val => val !== this.routeHistory);
199
+
200
+ const newHash = hashValues.length
201
+ ? `#${hashValues.join('&')}`
202
+ : '';
203
+
204
+ this.$router.replace({
205
+ path: this.$route.fullPath,
206
+ hash: newHash
207
+ });
161
208
  }
162
209
  },
163
210
  beforeUnmount() {
164
- document.documentElement.style.overflow = null
211
+ document.documentElement.style.overflow = null;
165
212
  }
166
213
  }
167
- </script>
214
+ </script>
@@ -5,36 +5,45 @@
5
5
 
6
6
 
7
7
  .#{base.$prefix}modal-overlay {
8
- width: 100%;
9
- height: 100%;
10
8
  position: fixed;
11
- left: 0;
12
- right: 0;
13
- top:0;
9
+ inset: 0;
14
10
  z-index: map.get(base.$z-index, 'important');
15
11
  background-color: var(--color-overlay);
16
12
  backdrop-filter: blur(3px) grayscale(30%);
17
13
  }
18
14
 
19
15
  .#{base.$prefix}modal {
20
- align-items: center;
21
- flex-direction: column;
22
- display: flex;
23
- left: 0;
24
- top: 0;
25
- width: 100%;
26
- height: 100%;
27
- justify-content: center;
28
16
  position: fixed;
17
+ inset: 0;
18
+ display: flex;
29
19
  z-index: map.get(base.$z-index, 'important');
30
20
  outline: none;
31
21
 
32
- .modal-content {
33
- border: 1px solid var(--color-sheet-container-low);
34
- background-color: var(--color-sheet-container-low);
35
- color: var(--color-on-sheet)
22
+ // Position variants
23
+ &.modal-center {
24
+ align-items: center;
25
+ justify-content: center;
26
+ }
27
+
28
+ &.modal-bottom {
29
+ align-items: flex-end;
30
+ justify-content: center;
31
+ }
32
+
33
+ &.modal-top {
34
+ align-items: flex-start;
35
+ justify-content: center;
36
+ }
37
+
38
+ &.modal-start {
39
+ align-items: center;
40
+ justify-content: flex-start;
36
41
  }
37
42
 
43
+ &.modal-end {
44
+ align-items: center;
45
+ justify-content: flex-end;
46
+ }
38
47
 
39
48
  .modal-btn {
40
49
  width: 100%;
@@ -43,10 +52,12 @@
43
52
  .#{base.$prefix}btn {
44
53
  position: absolute;
45
54
  bottom: -40px;
46
- z-index: map.get(base.$z-index, 'important')+1;
55
+ z-index: map.get(base.$z-index, 'important') + 1;
56
+
47
57
  @include mixins.rtl() {
48
58
  left: 5px;
49
59
  }
60
+
50
61
  @include mixins.ltr() {
51
62
  right: 5px;
52
63
  }
@@ -58,18 +69,48 @@
58
69
  max-width: 100vw;
59
70
  max-height: 90vh;
60
71
  z-index: map.get(base.$z-index, 'important');
72
+ background-color: var(--color-sheet-container-low);
73
+ color: var(--color-on-sheet);
74
+ border: 1px solid var(--color-sheet-container-low);
75
+ border-radius: base.$border-modal;
76
+ overflow: hidden;
77
+ display: flex;
78
+ flex-direction: column;
79
+
80
+ &.modal-bottom,
81
+ &.modal-top {
82
+ width: 100%;
83
+ border-radius: base.$border-modal base.$border-modal 0 0;
84
+
85
+ &:not(.modal-full-width) {
86
+ max-width: map.get(base.$container-max-widths, 'lg');
87
+ }
88
+ }
89
+
90
+ &.modal-start,
91
+ &.modal-end {
92
+ height: 100%;
93
+ max-height: 100vh;
94
+ border-radius: 0 base.$border-modal base.$border-modal 0;
95
+
96
+ &:not(.modal-full-height) {
97
+ max-height: 90vh;
98
+ }
99
+ }
100
+
101
+ &.modal-start {
102
+ border-radius: base.$border-modal 0 0 base.$border-modal;
103
+ }
61
104
  }
62
105
 
63
106
  .modal-content {
64
- position: relative;
65
- border-radius: base.$border-modal;
107
+ flex: 1;
66
108
  overflow-y: auto;
67
109
  overflow-x: hidden;
68
- height: 100%;
69
110
  }
70
111
 
71
112
  @include mixins2.media-breakpoint-up('md') {
72
- .modal-container {
113
+ .modal-container:not(.modal-full-width):not(.modal-mini) {
73
114
  width: 75%;
74
115
  max-width: 75vw;
75
116
  }
@@ -79,44 +120,27 @@
79
120
  max-width: 500px;
80
121
  }
81
122
 
82
- .modal-flat {
83
- border-radius: 0;
84
- }
85
-
86
123
  .modal-full-width {
87
124
  width: 100%;
88
- max-width: 100vw !important;
125
+ max-width: 100vw;
89
126
  }
90
127
 
91
128
  .modal-full-height {
92
129
  height: 100%;
93
- }
94
-
95
- .modal-bottom {
96
- border-radius: base.$border-modal base.$border-modal 0 0;
97
-
98
- &:not(.modal-full-width) {
99
- max-width: map.get(base.$container-max-widths, 'lg');
100
- }
130
+ max-height: 100vh;
101
131
  }
102
132
  }
103
133
 
134
+ // Animations
104
135
  .animate-modal-vibrate {
105
- animation-duration: .15s !important;
106
- animation-name: animate-modal-vibrate !important;
107
- animation-timing-function: map.get(base.$transition, 'fast-in-fast-out') !important;
136
+ animation: animate-modal-vibrate 0.15s map.get(base.$transition, 'fast-in-fast-out');
137
+
108
138
  @keyframes animate-modal-vibrate {
109
- 0% {
110
- transform: scale(1)
139
+ 0%, 100% {
140
+ transform: scale(1);
111
141
  }
112
142
  50% {
113
- transform: scale(1.03)
114
- }
115
- 100% {
116
- transform: scale(1)
143
+ transform: scale(1.03);
117
144
  }
118
145
  }
119
- }
120
-
121
-
122
-
146
+ }
@@ -205,10 +205,15 @@ export default {
205
205
  line-height: 20px;
206
206
  padding: 12px;
207
207
  max-width: 100%;
208
- min-width: 0px;
208
+ min-width: 0;
209
209
  caret-color: var(--color-on-sheet);
210
210
  }
211
211
 
212
+ input::placeholder {
213
+ color: var(--color-on-sheet);
214
+ opacity: 1;
215
+ }
216
+
212
217
  .card-search {
213
218
  position: absolute;
214
219
  left: 0;
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div :class="`${$r.prefix}table-manage`">
3
- <r-modal v-model="showForm" bottom full-width>
3
+ <r-modal v-model="showForm" full-width position="bottom">
4
4
  <slot :autoSend="autoSend"
5
5
  :method="method"
6
6
  :modelValue="editedItem"
@@ -19,7 +19,7 @@
19
19
  ></r-form-creator>
20
20
  </slot>
21
21
  </r-modal>
22
- <r-modal v-model="showCopy" bottom full-width>
22
+ <r-modal v-model="showCopy" full-width position="bottom">
23
23
  <div class="pa-3">
24
24
  <div v-for="(item,key) in table.option" :key="key"
25
25
  class="mb-5">
@@ -1,118 +1,123 @@
1
1
  <template>
2
- <r-container ref="tree" :class="classes" full-width>
3
- <r-row v-if="searchLink">
4
- <r-col>
5
- <r-select-input
6
- :label="$t('search','renusify')"
7
- :model-value="search"
8
- :searchLink="searchLink"
9
- @update:model-value="change($event)"
10
- ></r-select-input>
11
- </r-col>
12
- </r-row>
13
- <r-float v-if="show" :minZoom="0.01" :zoom="0.7" bordered>
14
- <template v-slot="{move,ease,transform}">
15
- <div :class="{
2
+ <r-container ref="tree" :class="classes" full-width>
3
+ <r-row v-if="searchLink">
4
+ <r-col>
5
+ <r-select-input
6
+ :label="$t('search','renusify')"
7
+ :model-value="search"
8
+ :searchLink="searchLink"
9
+ @update:model-value="change($event)"
10
+ ></r-select-input>
11
+ </r-col>
12
+ </r-row>
13
+ <r-float v-if="show" :minZoom="0.01" :zoom="0.7" bordered>
14
+ <template v-slot="{move,ease,transform}">
15
+ <div :class="{
16
16
  'tree-rotate':rotate
17
17
  }">
18
- <r-tree-element @update:model-value="$emit('update:modelValue',$event)"
19
- :link="link"
20
- :model-value="node"
21
- @expand="handleExpand(ease,move,transform,$event)"
22
- :expand="expand"
23
- :openAll="openAll"
24
- @select="handleSelect"
25
- >
26
- <template v-slot="{ item,nodeKey }">
27
- <slot :item="item" :nodeKey="nodeKey">{{item}}</slot>
28
- </template>
29
- </r-tree-element>
30
- </div>
18
+ <r-tree-element :expand="expand"
19
+ :link="link"
20
+ :model-value="node"
21
+ :openAll="openAll"
22
+ :sortBy="sortBy"
23
+ @expand="handleExpand(ease,move,transform,$event)"
24
+ @select="handleSelect"
25
+ @update:model-value="$emit('update:modelValue',$event)"
26
+ >
27
+ <template v-slot="{ item,nodeKey }">
28
+ <slot :item="item" :nodeKey="nodeKey">{{ item }}</slot>
31
29
  </template>
32
- </r-float>
33
- </r-container>
30
+ </r-tree-element>
31
+ </div>
32
+ </template>
33
+ </r-float>
34
+ </r-container>
34
35
 
35
36
  </template>
36
37
  <script>
37
38
 
38
39
  export default {
39
- name: 'r-tree',
40
- props: {
41
- modelValue: Object,
42
- link: String,
43
- searchLink: String,
44
- gen: String,
45
- selected: String,
46
- rotate: Boolean,
47
- expand: {
48
- type: Boolean,
49
- default: false
50
- },
51
- childsName: {
52
- type: String,
53
- default: 'childs'
54
- },
55
- openAll: Boolean,
56
- headers: Object
40
+ name: 'r-tree',
41
+ props: {
42
+ modelValue: Object,
43
+ link: String,
44
+ searchLink: String,
45
+ sortBy: {
46
+ type: String,
47
+ default: 'gen'
57
48
  },
58
- emits: ['update:modelValue', 'select-node'],
59
- data() {
60
- return {
61
- show: false,
62
- search: null,
63
- nodeParent: this.gen,
64
- node: this.modelValue
65
- }
49
+ gen: String,
50
+ selected: String,
51
+ rotate: Boolean,
52
+ expand: {
53
+ type: Boolean,
54
+ default: false
66
55
  },
67
- created() {
68
- if (this.modelValue) {
69
- this.show = true
70
- } else if (this.link) {
71
- this.get()
72
- }
56
+ childsName: {
57
+ type: String,
58
+ default: 'childs'
73
59
  },
74
- watch: {
75
- modelValue: function (newVal) {
76
- this.node = newVal
77
- }
60
+ openAll: Boolean,
61
+ headers: Object
62
+ },
63
+ emits: ['update:modelValue', 'select-node'],
64
+ data() {
65
+ return {
66
+ show: false,
67
+ search: null,
68
+ nodeParent: this.gen,
69
+ node: this.modelValue
70
+ }
71
+ },
72
+ created() {
73
+ if (this.modelValue) {
74
+ this.show = true
75
+ } else if (this.link) {
76
+ this.get()
77
+ }
78
+ },
79
+ watch: {
80
+ modelValue: function (newVal) {
81
+ this.node = newVal
82
+ }
83
+ },
84
+ computed: {
85
+ classes() {
86
+ let a = {'tree-searchable': this.searchLink}
87
+ a[`${this.$r.prefix}tree`] = true
88
+ return a
89
+ }
90
+ },
91
+ methods: {
92
+ change(e) {
93
+ if (e && "value" in e) {
94
+ this.nodeParent = e.value
95
+ this.show = false
96
+ this.get()
97
+ }
78
98
  },
79
- computed: {
80
- classes() {
81
- let a = {'tree-searchable': this.searchLink}
82
- a[`${this.$r.prefix}tree`] = true
83
- return a
84
- }
99
+ get() {
100
+ this.$axios.get(this.link + this.nodeParent, {headers: this.headers})
101
+ .then(({data}) => {
102
+ this.node = data
103
+ this.show = true
104
+ })
105
+ },
106
+ handleExpand(ease, move, transform, $event) {
107
+ const el = $event[1].getBoundingClientRect()
108
+ ease()
109
+ const node_info = $event[1].querySelector('.node-info').getBoundingClientRect()
110
+ const card_h = node_info.height
111
+ const card_w = node_info.width
112
+ const parent = this.$refs.tree.$el
113
+ const bb = this.$refs.tree.$el.getBoundingClientRect()
114
+ move(parent.offsetWidth / 2 - (el.left - bb.left + ($event[0] ? el.width / 2 : el.width - card_w / 2)),
115
+ parent.offsetHeight / 2 - (el.top - bb.top + (this.rotate ? el.height - card_h : card_h / 2)))
85
116
  },
86
- methods: {
87
- change(e) {
88
- if (e && "value" in e) {
89
- this.nodeParent = e.value
90
- this.show = false
91
- this.get()
92
- }
93
- },
94
- get() {
95
- this.$axios.get(this.link + this.nodeParent, {headers: this.headers})
96
- .then(({data}) => {
97
- this.node = data
98
- this.show = true
99
- })
100
- },
101
- handleExpand(ease, move, transform, $event) {
102
- const el = $event[1].getBoundingClientRect()
103
- ease()
104
- const node_info = $event[1].querySelector('.node-info').getBoundingClientRect()
105
- const card_h = node_info.height
106
- const card_w = node_info.width
107
- const parent = this.$refs.tree.$el
108
- const bb = this.$refs.tree.$el.getBoundingClientRect()
109
- move(parent.offsetWidth / 2 - (el.left - bb.left + ($event[0] ? el.width / 2 : el.width - card_w / 2)),
110
- parent.offsetHeight / 2 - (el.top - bb.top + (this.rotate ? el.height - card_h : card_h / 2)))
111
- },
112
- handleSelect(e) {
113
- this.$emit('select-node', e)
114
- }
117
+ handleSelect(e) {
118
+ this.$emit('select-node', e)
115
119
  }
120
+ }
116
121
  }
117
122
  </script>
118
123
  <style lang="scss">
@@ -120,31 +125,31 @@ export default {
120
125
 
121
126
  $distance: 20px;
122
127
  .#{base.$prefix}tree {
123
- position: relative;
124
- width: 100%;
125
- height: 100%;
128
+ position: relative;
129
+ width: 100%;
130
+ height: 100%;
126
131
 
127
- &.tree-searchable {
128
- .#{base.$prefix}float {
129
- height: calc(100% - 70px)
130
- }
132
+ &.tree-searchable {
133
+ .#{base.$prefix}float {
134
+ height: calc(100% - 70px)
131
135
  }
136
+ }
132
137
 
133
138
  .#{base.$prefix}float {
134
- direction: ltr;
135
- }
139
+ direction: ltr;
140
+ }
136
141
 
137
- .tree-rotate {
138
- transform: rotateX(180deg);
142
+ .tree-rotate {
143
+ transform: rotateX(180deg);
139
144
 
140
- .node-info {
141
- transform: rotateX(-180deg);
142
- }
145
+ .node-info {
146
+ transform: rotateX(-180deg);
147
+ }
143
148
 
144
- .tree-btn-expand {
145
- transform: rotateX(-180deg);
146
- }
149
+ .tree-btn-expand {
150
+ transform: rotateX(-180deg);
147
151
  }
152
+ }
148
153
 
149
154
  }
150
155
  </style>
@@ -29,6 +29,7 @@
29
29
  @expand="handleExpand"
30
30
  :expand="expand"
31
31
  :openAll="openAll"
32
+ :sort-by="sortBy"
32
33
  @select="$emit('select',$event)"
33
34
  >
34
35
  <template v-slot="{ item,nodeKey }">
@@ -107,10 +108,17 @@ export default {
107
108
  }
108
109
  const sortBy = this.sortBy
109
110
  s.sort(function (a, b) {
110
- if (a['value'][sortBy]) {
111
- return a['value'][sortBy].localeCompare(b['value'][sortBy]);
111
+ if (a['value'][sortBy] !== undefined) {
112
+ if (b['value'][sortBy] !== undefined) {
113
+ if (typeof a['value'][sortBy] === 'number' && typeof b['value'][sortBy] === 'number') {
114
+ return a['value'][sortBy] - b['value'][sortBy];
115
+ } else {
116
+ return String(a['value'][sortBy]).localeCompare(String(b['value'][sortBy]));
117
+ }
118
+ }
119
+ return -1;
112
120
  }
113
- return 1
121
+ return b['value'][sortBy] !== undefined ? 1 : 0;
114
122
  });
115
123
  const lng = s.length
116
124
  for (let i = 0; i < lng; i++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "renusify",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "description": "Vue3 Framework",
5
5
  "keywords": [
6
6
  "vuejs",