renusify 2.4.4 → 2.5.1

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,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="!noCloseOnClickOutside && 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,170 @@ 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,
75
+ noCloseOnClickOutside: Boolean,
58
76
  routeHistory: String,
59
- closebtn: {type: Boolean, default: true},
60
77
  color: String,
61
- animate: String
78
+ animation: String
62
79
  },
63
80
  emits: ['update:modelValue'],
64
81
  data() {
65
82
  return {
66
- state: null,
67
- run_animate: false,
68
- show: false,
83
+ mounted: false,
84
+ runAnimation: false
69
85
  }
70
86
  },
71
87
  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)
88
+ this.initFromRoute();
89
+ setTimeout(() => {
90
+ this.mounted = true;
91
+ }, 10);
81
92
  },
82
93
  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)
94
+ '$route': 'handleRouteChange',
95
+ modelValue: 'handleModelValueChange'
96
+ },
97
+ computed: {
98
+ computedAnimation() {
99
+ if (this.animation) return this.animation;
100
+
101
+ switch (this.position) {
102
+ case 'bottom':
103
+ return 'slide-up';
104
+ case 'top':
105
+ return 'slide-down';
106
+ case 'start':
107
+ return 'slide-end';
108
+ case 'end':
109
+ return 'slide-start';
110
+ default:
111
+ return 'scale';
92
112
  }
93
113
  },
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
114
+ modalClasses() {
115
+ return [
116
+ `${this.$r.prefix}modal`,
117
+ `modal-${this.position}`,
118
+ {
119
+ 'animate-modal-vibrate': this.runAnimation
113
120
  }
114
- }
121
+ ];
122
+ },
123
+ containerClasses() {
124
+ return [
125
+ this.color,
126
+ {
127
+ 'modal-full-width': this.fullWidth,
128
+ 'modal-full-height': this.fullHeight,
129
+ 'modal-mini': this.minWidth,
130
+ [`modal-${this.position}`]: this.position !== 'center'
131
+ }
132
+ ];
133
+ },
134
+ containerStyles() {
135
+ return {
136
+ 'max-width': this.maxWidth,
137
+ 'max-height': this.maxHeight
138
+ };
115
139
  }
116
140
  },
117
- computed: {
118
- c_animate() {
119
- if (this.animate) {
120
- return this.animate
141
+ methods: {
142
+ initFromRoute() {
143
+ if (!this.routeHistory) return;
144
+
145
+ const hashValues = this.$route.hash.replace('#', '').split('&');
146
+ if (hashValues.includes(this.routeHistory)) {
147
+ this.$emit('update:modelValue', true);
121
148
  }
122
- if (this.bottom) {
123
- return 'slide-up'
149
+ },
150
+ handleRouteChange(newRoute) {
151
+ if (!this.routeHistory) return;
152
+
153
+ const hashValues = newRoute.hash.replace('#', '').split('&');
154
+ this.$emit('update:modelValue', hashValues.includes(this.routeHistory));
155
+ },
156
+ handleModelValueChange(isOpen) {
157
+ if (isOpen) {
158
+ document.documentElement.style.overflow = 'hidden';
159
+ this.handleOpenState();
160
+ } else {
161
+ document.documentElement.style.overflow = null;
124
162
  }
125
- if (this.fullHeight) {
126
- return 'slide-up'
163
+ },
164
+ handleOpenState() {
165
+ if (!this.routeHistory) return;
166
+
167
+ const hashValues = this.$route.hash.replace('#', '').split('&');
168
+ if (!hashValues.includes(this.routeHistory)) {
169
+ const newHash = this.$route.hash
170
+ ? `${this.$route.hash}&${this.routeHistory}`
171
+ : `#${this.routeHistory}`;
172
+
173
+ this.$router.push({
174
+ path: this.$route.fullPath,
175
+ hash: newHash
176
+ });
127
177
  }
128
- return 'scale'
129
- }
130
- },
131
- methods: {
178
+ },
132
179
  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)
180
+ if (this.noClosable && !force) {
181
+ this.runAnimation = true;
182
+ setTimeout(() => this.runAnimation = false, 300);
183
+ return;
160
184
  }
185
+
186
+ if (this.routeHistory) {
187
+ this.handleRouteClose();
188
+ }
189
+
190
+ this.$emit('update:modelValue', false);
191
+ },
192
+ handleRouteClose() {
193
+ if (history.state.back) {
194
+ this.$router.back();
195
+ return;
196
+ }
197
+
198
+ let hashValues = this.$route.hash.replace('#', '').split('&');
199
+ hashValues = hashValues.filter(val => val !== this.routeHistory);
200
+
201
+ const newHash = hashValues.length
202
+ ? `#${hashValues.join('&')}`
203
+ : '';
204
+
205
+ this.$router.replace({
206
+ path: this.$route.fullPath,
207
+ hash: newHash
208
+ });
161
209
  }
162
210
  },
163
211
  beforeUnmount() {
164
- document.documentElement.style.overflow = null
212
+ document.documentElement.style.overflow = null;
165
213
  }
166
214
  }
167
- </script>
215
+ </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
+ }