@mixd-id/web-scaffold 0.1.230406099 → 0.1.230406101
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.
package/package.json
CHANGED
package/src/components/Modal.vue
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
<div>
|
|
3
3
|
<Teleport to=".bW9k">
|
|
4
4
|
<Transition :name="transition" @after-leave="onAfterLeave" @after-enter="$emit('show')">
|
|
5
|
-
<div v-if="computedState" :class="computedClass" ref="modal" :style="computedStyle"
|
|
5
|
+
<div v-if="computedState" :class="computedClass" ref="modal" :style="computedStyle"
|
|
6
|
+
:data-state="computedState ? 1 : 0">
|
|
6
7
|
<form v-if="useForm" @submit.prevent="$emit('submit')">
|
|
7
8
|
<div class="modal-head">
|
|
8
9
|
<slot name="head" :context="context"></slot>
|
|
@@ -160,7 +161,7 @@ export default{
|
|
|
160
161
|
let hasTrueState = false
|
|
161
162
|
|
|
162
163
|
for(let i = 0 ; i < overlay.children.length ; i++){
|
|
163
|
-
if(overlay.children[i].
|
|
164
|
+
if(overlay.children[i].getAttribute('data-state') === '1'){
|
|
164
165
|
hasTrueState = true
|
|
165
166
|
}
|
|
166
167
|
}
|
|
@@ -174,9 +175,8 @@ export default{
|
|
|
174
175
|
},
|
|
175
176
|
|
|
176
177
|
onDismiss(e){
|
|
177
|
-
if(this.dismissable && this.$refs.modal && e.target.classList.contains('bW9k')){
|
|
178
|
+
if(this.computedState && this.dismissable && this.$refs.modal && e.target.classList.contains('bW9k')){
|
|
178
179
|
this.$emit('dismiss')
|
|
179
|
-
this.close()
|
|
180
180
|
}
|
|
181
181
|
},
|
|
182
182
|
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<Teleport to=".bW9k">
|
|
4
|
+
<div :class="computedClass" ref="modal" :style="computedStyle"
|
|
5
|
+
:data-state="computedState ? 1 : 0">
|
|
6
|
+
<form v-if="useForm" @submit.prevent="$emit('submit')">
|
|
7
|
+
<div class="modal-head">
|
|
8
|
+
<slot name="head" :context="context"></slot>
|
|
9
|
+
</div>
|
|
10
|
+
<div :class="modalBodyClass">
|
|
11
|
+
<slot :context="context"></slot>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="modal-foot">
|
|
14
|
+
<slot name="foot" :context="context"></slot>
|
|
15
|
+
</div>
|
|
16
|
+
<div v-if="isDisabled" :class="$style.overlay"></div>
|
|
17
|
+
</form>
|
|
18
|
+
<div v-else class="flex-1 min-h-0 flex flex-col relative">
|
|
19
|
+
<div class="modal-head">
|
|
20
|
+
<slot name="head" :context="context"></slot>
|
|
21
|
+
</div>
|
|
22
|
+
<div :class="modalBodyClass">
|
|
23
|
+
<slot :context="context"></slot>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="modal-foot">
|
|
26
|
+
<slot name="foot" :context="context"></slot>
|
|
27
|
+
</div>
|
|
28
|
+
<div v-if="isDisabled" :class="$style.overlay"></div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</Teleport>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script>
|
|
36
|
+
|
|
37
|
+
let modals = []
|
|
38
|
+
|
|
39
|
+
const registerModal = (modal) => {
|
|
40
|
+
|
|
41
|
+
modals.forEach((_) => {
|
|
42
|
+
_.isDisabled = 1
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
modals.push(modal)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const unRegisterModal = (modal) => {
|
|
49
|
+
|
|
50
|
+
modals = modals.filter((_) => _ !== modal)
|
|
51
|
+
|
|
52
|
+
if(modals.length > 0)
|
|
53
|
+
modals[modals.length - 1].isDisabled = 0
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default{
|
|
57
|
+
|
|
58
|
+
emits: [ 'submit', 'dismiss', 'show', 'hide' ],
|
|
59
|
+
|
|
60
|
+
props:{
|
|
61
|
+
bodyClass:{ type: String, default: '' },
|
|
62
|
+
class:{ type: String, default: '' },
|
|
63
|
+
dismissable: undefined,
|
|
64
|
+
height: String,
|
|
65
|
+
position: {
|
|
66
|
+
type: String,
|
|
67
|
+
default: 'bottom'
|
|
68
|
+
},
|
|
69
|
+
state: [ Number, Boolean, String ],
|
|
70
|
+
transition: { type: String, default: 'slideup' },
|
|
71
|
+
width: String,
|
|
72
|
+
useForm: {
|
|
73
|
+
type: Boolean,
|
|
74
|
+
default: false
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
computed:{
|
|
79
|
+
|
|
80
|
+
modalBodyClass(){
|
|
81
|
+
return [
|
|
82
|
+
this.$style.modalBody,
|
|
83
|
+
this.bodyClass
|
|
84
|
+
]
|
|
85
|
+
.join(' ')
|
|
86
|
+
.trim()
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
computedClass(){
|
|
90
|
+
return [
|
|
91
|
+
this.$style.modal,
|
|
92
|
+
this.$style['modal-' + this.position],
|
|
93
|
+
this.class,
|
|
94
|
+
this.computedState ? this.$style.open : ''
|
|
95
|
+
]
|
|
96
|
+
.join(' ')
|
|
97
|
+
.trim()
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
computedStyle(){
|
|
101
|
+
return {
|
|
102
|
+
width: parseInt(this.width) + 'px',
|
|
103
|
+
height: parseInt(this.height) + 'px',
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
computedState(){
|
|
108
|
+
return this.state ? Boolean(this.state) : this._state
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
data(){
|
|
114
|
+
return {
|
|
115
|
+
isDisabled: 0,
|
|
116
|
+
_state: false,
|
|
117
|
+
context: null
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
watch:{
|
|
122
|
+
|
|
123
|
+
computedState(to, from){
|
|
124
|
+
|
|
125
|
+
if(to){
|
|
126
|
+
let overlay = document.querySelector('.bW9k')
|
|
127
|
+
if(overlay){
|
|
128
|
+
overlay.classList.add('bW9l')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
this.$emit('show')
|
|
132
|
+
registerModal(this)
|
|
133
|
+
}
|
|
134
|
+
else{
|
|
135
|
+
this.$nextTick(() => {
|
|
136
|
+
this.onAfterLeave()
|
|
137
|
+
unRegisterModal(this)
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
mounted() {
|
|
145
|
+
document.querySelector('.bW9k').addEventListener('click', this.onDismiss)
|
|
146
|
+
window,addEventListener('keydown', this.onKeyDown)
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
methods: {
|
|
150
|
+
|
|
151
|
+
open(context = {}){
|
|
152
|
+
this.context = context
|
|
153
|
+
this._state = true
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
close(){
|
|
157
|
+
this._state = false
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
onAfterLeave(){
|
|
161
|
+
let overlay = document.querySelector('.bW9k')
|
|
162
|
+
if(overlay){
|
|
163
|
+
|
|
164
|
+
let hasTrueState = false
|
|
165
|
+
|
|
166
|
+
for(let i = 0 ; i < overlay.children.length ; i++){
|
|
167
|
+
if(overlay.children[i].getAttribute('data-state') === '1'){
|
|
168
|
+
hasTrueState = true
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if(!hasTrueState){
|
|
173
|
+
overlay.classList.remove('bW9l')
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
this.$emit('hide')
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
onDismiss(e){
|
|
181
|
+
if(this.computedState && this.dismissable && this.$refs.modal && e.target.classList.contains('bW9k')){
|
|
182
|
+
this.$emit('dismiss')
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
onKeyDown(e){
|
|
187
|
+
if(this.dismissable && this.$refs.modal && e.keyCode === 27){
|
|
188
|
+
this.$emit('dismiss')
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
</script>
|
|
196
|
+
|
|
197
|
+
<style>
|
|
198
|
+
|
|
199
|
+
.bW9k{
|
|
200
|
+
@apply fixed z-20 top-0 left-0 bottom-0 right-0 hidden items-center justify-center;
|
|
201
|
+
@apply bg-black/50 backdrop-blur-md;
|
|
202
|
+
}
|
|
203
|
+
.bW9l{
|
|
204
|
+
@apply flex;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
</style>
|
|
208
|
+
|
|
209
|
+
<style module>
|
|
210
|
+
|
|
211
|
+
.modal{
|
|
212
|
+
@apply fixed;
|
|
213
|
+
@apply bg-base-400;
|
|
214
|
+
@apply border-[1px] border-text-50 z-20 flex max-h-[90vh];
|
|
215
|
+
@apply rounded-xl overflow-hidden;
|
|
216
|
+
transform: scale(0);
|
|
217
|
+
}
|
|
218
|
+
.modal.open{
|
|
219
|
+
transform: scale(1);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.modal form{
|
|
223
|
+
@apply flex-1 min-h-0 flex flex-col relative;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.modalBody{
|
|
227
|
+
@apply flex-1 min-h-0 overflow-y-auto flex bg-base-400 dark:bg-base-300;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.overlay{
|
|
231
|
+
@apply absolute z-20 left-0 bottom-0 top-0 right-0 bg-white/50 backdrop-blur-sm;
|
|
232
|
+
}
|
|
233
|
+
html[data-theme='dark'] .overlay{
|
|
234
|
+
@apply bg-black/50;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@media screen and (max-width: 640px) {
|
|
238
|
+
|
|
239
|
+
.modal {
|
|
240
|
+
max-height: 90vh;
|
|
241
|
+
width: 100vw !important;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.modal-center{
|
|
245
|
+
align-self: center;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.modal-bottom{
|
|
249
|
+
align-self: end;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@media screen and (min-width: 640px) {
|
|
255
|
+
|
|
256
|
+
.modal {
|
|
257
|
+
max-width: 90vw;
|
|
258
|
+
width: 480px;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
</style>
|
|
264
|
+
|
|
265
|
+
<style>
|
|
266
|
+
|
|
267
|
+
.slideup-enter-active,
|
|
268
|
+
.slideup-leave-active {
|
|
269
|
+
transition: all 300ms cubic-bezier(0.25, 1, 0.5, 1);
|
|
270
|
+
}
|
|
271
|
+
.slideup-enter-active,
|
|
272
|
+
.slideup-leave-active {
|
|
273
|
+
transform: translate3d(0, 0, 0);
|
|
274
|
+
}
|
|
275
|
+
.slideup-enter-from,
|
|
276
|
+
.slideup-leave-to {
|
|
277
|
+
opacity: 0;
|
|
278
|
+
transform: translate3d(0, 10px, 0);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
</style>
|
package/src/index.js
CHANGED
|
@@ -320,6 +320,7 @@ export default{
|
|
|
320
320
|
app.component('Flex', defineAsyncComponent(() => import("./components/Flex.vue")))
|
|
321
321
|
app.component('Grid', defineAsyncComponent(() => import("./components/Grid.vue")))
|
|
322
322
|
app.component('Modal', defineAsyncComponent(() => import("./components/Modal.vue")))
|
|
323
|
+
app.component('Modal2', defineAsyncComponent(() => import("./components/Modal2.vue")))
|
|
323
324
|
app.component('OTPField', defineAsyncComponent(() => import("./components/OTPField.vue")))
|
|
324
325
|
app.component('PageBuilder', defineAsyncComponent(() => import("./components/PageBuilder.vue")))
|
|
325
326
|
app.component('Radio', defineAsyncComponent(() => import("./components/Radio.vue")))
|
|
@@ -12,12 +12,6 @@
|
|
|
12
12
|
<div class="mt-1">
|
|
13
13
|
<Textbox v-if="field.type === 'name'" v-model="form[field.type]" class="bg-white text-xl" :readonly="completed" />
|
|
14
14
|
|
|
15
|
-
<Textbox v-else-if="field.type === 'university'" v-model="form[field.type]"
|
|
16
|
-
class="bg-white text-xl" :readonly="completed" />
|
|
17
|
-
|
|
18
|
-
<Textbox v-else-if="field.type === 'ktpNumber'" maxlength="16" type="tel" v-model="form[field.type]"
|
|
19
|
-
class="bg-white text-xl font-mono" :readonly="completed" />
|
|
20
|
-
|
|
21
15
|
<Textbox v-else-if="field.type === 'email'" v-model="form[field.type]"
|
|
22
16
|
class="bg-white text-xl md:w-[300px] max-w-full" :readonly="completed" />
|
|
23
17
|
|
|
@@ -27,38 +21,7 @@
|
|
|
27
21
|
<Textbox v-else-if="field.type === 'referralCode'" v-model="form[field.type]"
|
|
28
22
|
class="bg-white text-xl md:w-[200px] max-w-full" :readonly="completed" />
|
|
29
23
|
|
|
30
|
-
<div v-else-if="field.type === 'birthDate'" class="flex flex-col md:flex-row gap-2">
|
|
31
|
-
<Textbox v-model="form['birthPlace']" class="bg-base cursor-pointer" @click="$refs.citySelector.open()" readonly="true"
|
|
32
|
-
placeholder="Kota">
|
|
33
|
-
<template #end>
|
|
34
|
-
<div class="p-3">
|
|
35
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" class="fill-text-200" viewBox="0 0 320 512"><path d="M287.968 160H32.038c-28.425 0-42.767 34.488-22.627 54.627l127.962 128c12.496 12.496 32.758 12.497 45.255 0l127.968-128C330.695 194.528 316.45 160 287.968 160zM160 320L32 192h256L160 320z"/></svg>
|
|
36
|
-
</div>
|
|
37
|
-
</template>
|
|
38
|
-
</Textbox>
|
|
39
|
-
<Datepicker v-model="form['birthDate']" class="w-[200px] text-lg" default-value="2000-01-01" :readonly="completed" />
|
|
40
|
-
</div>
|
|
41
|
-
|
|
42
|
-
<Dropdown v-else-if="field.type === 'position'" v-model="form[field.type]" class="text-xl">
|
|
43
|
-
<option v-for="item in field.items" :value="item.text">{{ item.text }}</option>
|
|
44
|
-
</Dropdown>
|
|
45
|
-
|
|
46
|
-
<Dropdown v-else-if="field.type === 'provinceName'" v-model="form[field.type]" class="text-xl">
|
|
47
|
-
<option disabled selected value="">Propinsi</option>
|
|
48
|
-
<option v-for="item in field.provinces" :value="item.alias">{{ item.alias }}</option>
|
|
49
|
-
</Dropdown>
|
|
50
|
-
|
|
51
|
-
<Dropdown v-else-if="field.type === 'education'" v-model="form[field.type]" class="text-xl">
|
|
52
|
-
<option v-for="item in field.items" :value="item.text">{{ item.text }}</option>
|
|
53
|
-
</Dropdown>
|
|
54
|
-
|
|
55
|
-
<Dropdown v-else-if="field.type === 'major'" v-model="form[field.type]" class="text-xl">
|
|
56
|
-
<option v-for="item in field.items" :value="item.text">{{ item.text }}</option>
|
|
57
|
-
</Dropdown>
|
|
58
|
-
|
|
59
24
|
<Textarea v-else-if="field.type === 'remark'" v-model="form[field.type]" rows="2" :readonly="completed"></Textarea>
|
|
60
|
-
|
|
61
|
-
<pre v-else>{{ field.type }}</pre>
|
|
62
25
|
</div>
|
|
63
26
|
</div>
|
|
64
27
|
</div>
|
|
@@ -214,13 +214,6 @@ export default{
|
|
|
214
214
|
{ type:'email', label:'Email' },
|
|
215
215
|
{ type:'remark', label:'Pertanyaan' },
|
|
216
216
|
{ type:'referralCode', label:'Kode Referral (optional)' },
|
|
217
|
-
{ type:'ktpNumber', label:'Nomor KTP' },
|
|
218
|
-
{ type:'birthDate', label:'Tempat/Tanggal Lahir' },
|
|
219
|
-
{ type:'position', label:'Jabatan yang Dilamar', _edit:'positionEdit', items:[] },
|
|
220
|
-
{ type:'provinceName', label:'Propinsi Domisili' },
|
|
221
|
-
{ type:'education', label:'Pendidikan Terakhir', _edit:'positionEdit', items:[] },
|
|
222
|
-
{ type:'major', label:'Jurusan', _edit:'positionEdit', items:[] },
|
|
223
|
-
{ type:'university', label:'Nama Sekolah/Institusi/Universitas', _edit:'positionEdit', items:[] },
|
|
224
217
|
]
|
|
225
218
|
}
|
|
226
219
|
},
|