@mixd-id/web-scaffold 0.1.230406001

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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/package.json +71 -0
  4. package/public/images/mixd-logo2.png +0 -0
  5. package/src/App.vue +17 -0
  6. package/src/components/Ahref.vue +34 -0
  7. package/src/components/Alert.vue +160 -0
  8. package/src/components/Button.vue +253 -0
  9. package/src/components/ButtonGroup.vue +101 -0
  10. package/src/components/Carousel.vue +293 -0
  11. package/src/components/ChatTyping.vue +69 -0
  12. package/src/components/Checkbox.vue +152 -0
  13. package/src/components/ContextMenu.vue +261 -0
  14. package/src/components/CopyToClipboard.vue +59 -0
  15. package/src/components/Countdown.vue +213 -0
  16. package/src/components/Datepicker.vue +312 -0
  17. package/src/components/Dropdown.vue +198 -0
  18. package/src/components/DynamicTemplate.vue +44 -0
  19. package/src/components/ErrorText.vue +36 -0
  20. package/src/components/Feed.vue +118 -0
  21. package/src/components/Gmaps.vue +227 -0
  22. package/src/components/Grid.vue +29 -0
  23. package/src/components/GridColumn.vue +31 -0
  24. package/src/components/HTMLEditor.vue +396 -0
  25. package/src/components/Image.vue +207 -0
  26. package/src/components/Image360.vue +140 -0
  27. package/src/components/ImageFullScreen.vue +101 -0
  28. package/src/components/ImagePreview.vue +71 -0
  29. package/src/components/ImportModal.vue +247 -0
  30. package/src/components/ListItem.vue +147 -0
  31. package/src/components/ListPage1.vue +1331 -0
  32. package/src/components/ListPage1Filter.vue +170 -0
  33. package/src/components/Modal.vue +253 -0
  34. package/src/components/OTPField.vue +126 -0
  35. package/src/components/Radio.vue +134 -0
  36. package/src/components/SearchButton.vue +57 -0
  37. package/src/components/Slider.vue +285 -0
  38. package/src/components/SplitPane.vue +129 -0
  39. package/src/components/Switch.vue +89 -0
  40. package/src/components/TabView.vue +106 -0
  41. package/src/components/TableView.vue +201 -0
  42. package/src/components/TableViewHead.vue +159 -0
  43. package/src/components/Tabs.vue +74 -0
  44. package/src/components/TextEditor.vue +85 -0
  45. package/src/components/Textarea.vue +184 -0
  46. package/src/components/Textbox.vue +200 -0
  47. package/src/components/Timepicker.vue +108 -0
  48. package/src/components/Toast.vue +93 -0
  49. package/src/components/VirtualScroll.vue +215 -0
  50. package/src/components/VirtualTable.vue +497 -0
  51. package/src/entry-client.js +27 -0
  52. package/src/entry-server.js +73 -0
  53. package/src/index.css +3 -0
  54. package/src/index.js +255 -0
  55. package/src/main.js +38 -0
  56. package/src/router.js +57 -0
  57. package/src/themes/default/index.js +200 -0
  58. package/src/utils/helpers.js +185 -0
  59. package/src/utils/helpers.mjs +197 -0
  60. package/src/utils/importer.js +156 -0
  61. package/src/utils/listpage1.js +1371 -0
  62. package/src/utils/selection.js +64 -0
@@ -0,0 +1,170 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <div class="flex flex-row items-center gap-2">
4
+ <Checkbox v-model="filter.enabled" @change="onFilterChange(item)"/>
5
+ <div class="flex-1">
6
+ <strong class="block text-ellipsis overflow-x-hidden whitespace-nowrap">{{ filter.label }}</strong>
7
+ </div>
8
+ <div class="w-[60px]">
9
+ <Dropdown v-model="filter.operand" @change="onFilterChange(item)">
10
+ <option value="">And</option>
11
+ <option value="or">Or</option>
12
+ </Dropdown>
13
+ </div>
14
+ <button @click.stop="removeFilter(filter)" class="text-primary">
15
+ <svg width="21" height="21" class="fill-text-100 hover:fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
16
+ <path class="secondary" fill-rule="evenodd" d="M15.78 14.36a1 1 0 0 1-1.42 1.42l-2.82-2.83-2.83 2.83a1 1 0 1 1-1.42-1.42l2.83-2.82L7.3 8.7a1 1 0 0 1 1.42-1.42l2.83 2.83 2.82-2.83a1 1 0 0 1 1.42 1.42l-2.83 2.83 2.83 2.82z"/>
17
+ </svg>
18
+ </button>
19
+ </div>
20
+ <div class="flex flex-col gap-3 py-3">
21
+
22
+ <div v-for="(item, idx) in filter.filters">
23
+
24
+ <div v-if="column && column.type === 'date'">
25
+
26
+ <div class="flex flex-row items-start gap-2">
27
+ <Dropdown v-model="item.operator" @change="onFilterChange(item)" class="flex-1 min-w-[100px]">
28
+ <option value="">Select</option>
29
+ <option value="today">Today</option>
30
+ <option value="thisWeek">This Week</option>
31
+ <option value="weekAgo">1 Week Ago</option>
32
+ <option value="thisMonth">This Month</option>
33
+ <option value="monthAgo">1 Month Ago</option>
34
+ <option value="lastMonth">Last Month</option>
35
+ <option value="thisMonth">This Year</option>
36
+ <option value="lastYear">Last Year</option>
37
+ <option value="between">Between</option>
38
+ </Dropdown>
39
+ <Datepicker v-if="item.operator === 'between'" v-model="item.value[0]" mode="popup" @change="onFilterChange(item)"/>
40
+ <Datepicker v-if="item.operator === 'between'" v-model="item.value[1]" mode="popup" @change="onFilterChange(item)"/>
41
+ <button v-if="filter.filters.length > 1" @click.stop="filter.filters.splice(filter.filters.indexOf(item), 1);onFilterChange(item)"
42
+ class="py-2">
43
+ <svg width="21" height="21" class="fill-text-100 hover:fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
44
+ <path class="secondary" fill-rule="evenodd" d="M15.78 14.36a1 1 0 0 1-1.42 1.42l-2.82-2.83-2.83 2.83a1 1 0 1 1-1.42-1.42l2.83-2.82L7.3 8.7a1 1 0 0 1 1.42-1.42l2.83 2.83 2.82-2.83a1 1 0 0 1 1.42 1.42l-2.83 2.83 2.83 2.82z"/>
45
+ </svg>
46
+ </button>
47
+ </div>
48
+
49
+ </div>
50
+
51
+ <div v-else-if="column && column.type === 'enum'" class="flex flex-col">
52
+ <Checkbox v-for="(obj, idx) in filter.typeParams" :value="obj.value" v-model="item.value"
53
+ @change="onFilterChange(item)">
54
+ {{ obj.text }}
55
+ </Checkbox>
56
+ </div>
57
+
58
+ <div v-else-if="column && [ 'currency', 'number' ].includes(column.type)">
59
+
60
+ <div class="flex flex-row items-start gap-2">
61
+ <Dropdown v-model="item.operator" @change="onFilterChange(item)">
62
+ <option value="">Select</option>
63
+ <option value="=">=</option>
64
+ <option value=">">&gt;</option>
65
+ <option value=">=">&gt;=</option>
66
+ <option value="<">&lt;</option>
67
+ <option value="<=">&lt;=</option>
68
+ </Dropdown>
69
+ <Textbox class="flex-1" v-model="item.value" @keyup.enter="onFilterChange(item)"/>
70
+ <button v-if="filter.filters.length > 1" @click.stop="filter.filters.splice(filter.filters.indexOf(item), 1);onFilterChange(item)"
71
+ class="py-2">
72
+ <svg width="21" height="21" class="fill-text-100 hover:fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
73
+ <path class="secondary" fill-rule="evenodd" d="M15.78 14.36a1 1 0 0 1-1.42 1.42l-2.82-2.83-2.83 2.83a1 1 0 1 1-1.42-1.42l2.83-2.82L7.3 8.7a1 1 0 0 1 1.42-1.42l2.83 2.83 2.82-2.83a1 1 0 0 1 1.42 1.42l-2.83 2.83 2.83 2.82z"/>
74
+ </svg>
75
+ </button>
76
+ </div>
77
+
78
+ </div>
79
+
80
+ <div v-else>
81
+
82
+ <div class="flex flex-row items-start gap-2">
83
+ <Dropdown v-model="item.operator" @change="onFilterChange(item)" class="flex-1 min-w-[100px]">
84
+ <option value="">{{ $t('Select') }}</option>
85
+ <option value="startsWith">{{ $t('Starts with') }}</option>
86
+ <option value="endsWith">{{ $t('Ends with') }}</option>
87
+ <option value="contains">{{ $t('Contains') }}</option>
88
+ <option value="=">{{ $t('Equal') }}</option>
89
+ <option value="empty">{{ $t('Empty')}}</option>
90
+ <option value="notEmpty">{{ $t('Not empty')}}</option>
91
+ <option value="regex">{{ $t('Regexp')}}</option>
92
+ </Dropdown>
93
+ <Textbox v-if="![ 'empty', 'notEmpty' ].includes(item.operator)" class="w-[150px]" v-model="item.value" @keyup.enter="onFilterChange(item)"/>
94
+ <button v-if="filter.filters.length > 1" @click.stop="filter.filters.splice(filter.filters.indexOf(item), 1);onFilterChange(item)"
95
+ class="py-2">
96
+ <svg width="21" height="21" class="fill-text-100 hover:fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
97
+ <path class="secondary" fill-rule="evenodd" d="M15.78 14.36a1 1 0 0 1-1.42 1.42l-2.82-2.83-2.83 2.83a1 1 0 1 1-1.42-1.42l2.83-2.82L7.3 8.7a1 1 0 0 1 1.42-1.42l2.83 2.83 2.82-2.83a1 1 0 0 1 1.42 1.42l-2.83 2.83 2.83 2.82z"/>
98
+ </svg>
99
+ </button>
100
+ </div>
101
+
102
+ </div>
103
+
104
+ </div>
105
+
106
+ <div class="text-center">
107
+ <button @click="addMore" class="text-primary">{{ $t('Add More') }}</button>
108
+ </div>
109
+
110
+ </div>
111
+
112
+ </div>
113
+ </template>
114
+
115
+ <script>
116
+
117
+ export default{
118
+
119
+ emits: [ 'remove', 'change' ],
120
+
121
+ props:{
122
+ column: Object,
123
+ filter: Object
124
+ },
125
+
126
+ methods: {
127
+
128
+ addMore(){
129
+ switch(this.filter.type){
130
+
131
+ case 'date':
132
+ case 'enum':
133
+ this.filter.filters.push({
134
+ value: []
135
+ })
136
+ break
137
+
138
+ default:
139
+ this.filter.filters.push({
140
+ })
141
+ break
142
+ }
143
+ },
144
+
145
+ removeFilter(filter){
146
+ this.$emit('remove', filter)
147
+ this.$emit('change')
148
+ },
149
+
150
+ onFilterChange(item){
151
+ this.$emit('change')
152
+ }
153
+
154
+ },
155
+
156
+ watch: {
157
+
158
+ }
159
+
160
+ }
161
+
162
+ </script>
163
+
164
+ <style module>
165
+
166
+ .comp{
167
+ @apply py-4;
168
+ }
169
+
170
+ </style>
@@ -0,0 +1,253 @@
1
+ <template>
2
+ <div>
3
+ <Teleport to=".bW9k">
4
+ <Transition :name="transition" @after-leave="onAfterLeave" @after-enter="$emit('show')">
5
+ <div v-if="computedState" :class="computedClass" ref="modal" :style="computedStyle">
6
+ <form @submit.prevent="$emit('submit')">
7
+ <div class="modal-head">
8
+ <slot name="head"></slot>
9
+ </div>
10
+ <div :class="modalBodyClass">
11
+ <slot></slot>
12
+ </div>
13
+ <div class="modal-foot">
14
+ <slot name="foot"></slot>
15
+ </div>
16
+ <div v-if="isDisabled" :class="$style.overlay"></div>
17
+ </form>
18
+ </div>
19
+ </Transition>
20
+ </Teleport>
21
+ </div>
22
+ </template>
23
+
24
+ <script>
25
+
26
+ let modals = []
27
+
28
+ const registerModal = (modal) => {
29
+
30
+ modals.forEach((_) => {
31
+ _.isDisabled = 1
32
+ })
33
+
34
+ modals.push(modal)
35
+ }
36
+
37
+ const unRegisterModal = (modal) => {
38
+
39
+ modals = modals.filter((_) => _ !== modal)
40
+
41
+ if(modals.length > 0)
42
+ modals[modals.length - 1].isDisabled = 0
43
+ }
44
+
45
+ export default{
46
+
47
+ emits: [ 'submit', 'dismiss', 'show', 'hide' ],
48
+
49
+ props:{
50
+ bodyClass:{ type: String, default: '' },
51
+ class:{ type: String, default: '' },
52
+ dismissable: undefined,
53
+ height: String,
54
+ position: String,
55
+ state: [ Number, Boolean, String ],
56
+ transition: { type: String, default: 'slideup' },
57
+ width: String
58
+ },
59
+
60
+ computed:{
61
+
62
+ modalBodyClass(){
63
+ return [
64
+ this.$style.modalBody,
65
+ this.bodyClass
66
+ ]
67
+ .join(' ')
68
+ .trim()
69
+ },
70
+
71
+ computedClass(){
72
+ return [
73
+ this.$style.modal,
74
+ this.$style['modal-' + this.position],
75
+ this.class
76
+ ]
77
+ .join(' ')
78
+ .trim()
79
+ },
80
+
81
+ computedStyle(){
82
+ return {
83
+ width: parseInt(this.width) + 'px',
84
+ height: parseInt(this.height) + 'px',
85
+ }
86
+ },
87
+
88
+ computedState(){
89
+ return this.state ? Boolean(this.state) : this._state
90
+ }
91
+
92
+ },
93
+
94
+ data(){
95
+ return {
96
+ isDisabled: 0,
97
+ _state: false
98
+ }
99
+ },
100
+
101
+ watch:{
102
+
103
+ computedState(to, from){
104
+
105
+ if(to){
106
+ let overlay = document.querySelector('.bW9k')
107
+ if(overlay){
108
+ overlay.classList.add('bW9l')
109
+ }
110
+
111
+ registerModal(this)
112
+ }
113
+ else{
114
+ unRegisterModal(this)
115
+ }
116
+ }
117
+
118
+ },
119
+
120
+ mounted() {
121
+ document.querySelector('.bW9k').addEventListener('click', this.onDismiss)
122
+ window,addEventListener('keydown', this.onKeyDown)
123
+ },
124
+
125
+ methods: {
126
+
127
+ open(){
128
+ this._state = true
129
+ },
130
+
131
+ close(){
132
+ this._state = false
133
+ },
134
+
135
+ onAfterLeave(){
136
+ let overlay = document.querySelector('.bW9k')
137
+ if(overlay){
138
+
139
+ let hasTrueState = false
140
+
141
+ for(let i = 0 ; i < overlay.children.length ; i++){
142
+ if(overlay.children[i].style.display !== 'none'){
143
+ hasTrueState = true
144
+ }
145
+ }
146
+
147
+ if(!hasTrueState){
148
+ overlay.classList.remove('bW9l')
149
+ }
150
+
151
+ this.$emit('hide')
152
+ }
153
+ },
154
+
155
+ onDismiss(e){
156
+ if(this.dismissable && this.$refs.modal && e.target.classList.contains('bW9k')){
157
+ this.$emit('dismiss')
158
+ this.close()
159
+ }
160
+ },
161
+
162
+ onKeyDown(e){
163
+ if(this.dismissable && this.$refs.modal && e.keyCode === 27){
164
+ this.$emit('dismiss')
165
+ }
166
+ }
167
+ }
168
+
169
+ }
170
+
171
+ </script>
172
+
173
+ <style>
174
+
175
+ .bW9k{
176
+ @apply fixed z-20 top-0 left-0 bottom-0 right-0 hidden items-center justify-center;
177
+ @apply bg-black/50 backdrop-blur-md;
178
+ }
179
+ .bW9l{
180
+ @apply flex;
181
+ }
182
+
183
+ </style>
184
+
185
+ <style module>
186
+
187
+ .modal{
188
+ @apply fixed;
189
+ @apply bg-base-500 border-[1px] border-text-50 z-20 flex max-h-[90vh];
190
+ @apply rounded-xl overflow-hidden;
191
+ transition: all 300ms cubic-bezier(0.25, 1, 0.5, 1);
192
+ }
193
+
194
+ .modal form{
195
+ @apply flex-1 min-h-0 flex flex-col relative;
196
+ }
197
+
198
+ .modalBody{
199
+ @apply flex-1 min-h-0 overflow-y-auto flex;
200
+ }
201
+
202
+ .overlay{
203
+ @apply absolute z-20 left-0 bottom-0 top-0 right-0 bg-white/50 backdrop-blur-sm;
204
+ }
205
+ html[data-theme='dark'] .overlay{
206
+ @apply bg-black/50;
207
+ }
208
+
209
+ @media screen and (max-width: 640px) {
210
+
211
+ .modal {
212
+ max-height: 90vh;
213
+ width: 100vw !important;
214
+ }
215
+
216
+ .modal-center{
217
+ align-self: center;
218
+ }
219
+
220
+ .modal-bottom{
221
+ align-self: end;
222
+ }
223
+
224
+ }
225
+
226
+ @media screen and (min-width: 640px) {
227
+
228
+ .modal {
229
+ max-width: 90vw;
230
+ width: 480px;
231
+ }
232
+
233
+ }
234
+
235
+ </style>
236
+
237
+ <style>
238
+
239
+ .slideup-enter-active,
240
+ .slideup-leave-active {
241
+ transition: all 300ms cubic-bezier(0.25, 1, 0.5, 1);
242
+ }
243
+ .slideup-enter-active,
244
+ .slideup-leave-active {
245
+ transform: translate3d(0, 0, 0);
246
+ }
247
+ .slideup-enter-from,
248
+ .slideup-leave-to {
249
+ opacity: 0;
250
+ transform: translate3d(0, 10px, 0);
251
+ }
252
+
253
+ </style>
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <div :class="computedClass">
4
+ <input :class="$style.input" maxlength="1" type="tel"
5
+ ref="verify" @keydown="verifyKeyDown" v-for="i in parseInt(length)"
6
+ :value="typeof modelValue === 'string' ? modelValue.split('')[i - 1] : ''"
7
+ @paste="verifyPaste" @keyup="verifyKeyUp($event, i - 1)" />
8
+ </div>
9
+ <ErrorText :error="error" :errorKey="errorKey" @dismissError="$emit('dismissError')"
10
+ :class="$style.errorText + (errorClass ? ' ' + errorClass : '')"/>
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+
16
+ export default{
17
+
18
+ props: {
19
+ error: Object,
20
+ errorKey: String,
21
+ errorClass: String,
22
+
23
+ modelValue: String,
24
+
25
+ length: {
26
+ type: [ String, Number ],
27
+ default: 4
28
+ },
29
+
30
+ size: String
31
+ },
32
+
33
+ computed: {
34
+
35
+ computedClass(){
36
+ return [
37
+ this.$style.inner,
38
+ this.$style['length-' + this.length],
39
+ this.size ? this.$style['size-' + this.size] : '',
40
+ ]
41
+ .join(' ')
42
+ },
43
+
44
+ verify(){
45
+ return this.modelValue.split('')
46
+ }
47
+
48
+ },
49
+
50
+ methods: {
51
+
52
+ verifyKeyDown(e){
53
+ if(((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105) ||
54
+ [ 8, 13 ].includes(e.keyCode)) && !e.ctrlKey && !e.metaKey && !e.shiftKey && !e.altKey);
55
+ else if([ 65, 86 ].includes(e.keyCode) && (e.ctrlKey || e.metaKey));
56
+ else{
57
+ e.preventDefault()
58
+ }
59
+ },
60
+
61
+ verifyKeyUp(e, idx){
62
+ if(e.keyCode === 8 && this.$refs.verify[idx].value === '' && idx > 0){
63
+ this.$refs.verify[idx - 1].select()
64
+ }
65
+ else if(this.$refs.verify[idx].value.length > 0 && idx < this.$refs.verify.length - 1){
66
+ this.$refs.verify[idx + 1].select()
67
+ }
68
+
69
+ const value = this.$refs.verify.map((ctl) => ctl.value).join('')
70
+ if(value.length === parseInt(this.length)){
71
+ this.$emit('update:modelValue', value)
72
+ }
73
+ },
74
+
75
+ verifyPaste(e){
76
+ e.stopPropagation()
77
+ e.preventDefault()
78
+ const clipboardData = e.clipboardData || window.clipboardData
79
+ const text = clipboardData.getData('Text')
80
+
81
+ if((new RegExp('^\\d{' + this.size + '}$')).test(text)){
82
+ this.$emit('update:modelValue', text)
83
+ }
84
+ }
85
+
86
+ }
87
+
88
+ }
89
+
90
+ </script>
91
+
92
+ <style module>
93
+
94
+ .comp{
95
+
96
+ }
97
+
98
+ .inner{
99
+ @apply h-[var(--h-cp)] overflow-hidden;
100
+ @apply grid gap-4;
101
+ }
102
+
103
+ .size-sm{ @apply h-[var(--h-cp-sm)]; }
104
+ .size-sm input{ @apply text-sm; }
105
+
106
+ .size-lg{ @apply h-[var(--h-cp-lg)]; }
107
+ .size-lg input{ @apply text-lg; }
108
+
109
+ .length-3{ @apply grid-cols-3; }
110
+ .length-4{ @apply grid-cols-4; }
111
+ .length-5{ @apply grid-cols-5; }
112
+ .length-6{ @apply grid-cols-6; }
113
+
114
+ .input{
115
+ @apply outline-none text-center bg-base-50 text-lg;
116
+ @apply border-[1px] border-text-200 rounded-lg;
117
+ }
118
+ .input:focus{
119
+ @apply border-primary;
120
+ }
121
+
122
+ .errorText{
123
+ @apply mt-2;
124
+ }
125
+
126
+ </style>
@@ -0,0 +1,134 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <input :id="id" type="radio" :name="name" :checked="computedChecked" @change="onChange" />
4
+ <label :for="id">
5
+ <div :class="$style.indicator">
6
+ <div>
7
+ <svg width="14" height="14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>
8
+ </div>
9
+ </div>
10
+ <slot></slot>
11
+ </label>
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+
17
+ import { parseBoolean } from "../utils/helpers.mjs";
18
+
19
+ export default{
20
+
21
+ props:{
22
+ name: String,
23
+ checked: undefined,
24
+ value: undefined,
25
+
26
+ modelValue: undefined,
27
+ trueValue: undefined,
28
+ falseValue: undefined,
29
+
30
+ customClass: String,
31
+ variant: String, // default
32
+ },
33
+
34
+ computed: {
35
+
36
+ id(){
37
+ return this.$style.comp + this.uniqid()
38
+ },
39
+
40
+ computedChecked(){
41
+ let checked
42
+ if(this.modelValue){
43
+ if(this.value){
44
+ checked = this.modelValue === this.value
45
+ }
46
+ else if(this.trueValue){
47
+ checked = this.trueValue === this.value
48
+ }
49
+ else{
50
+ checked = parseBoolean(this.modelValue)
51
+ }
52
+ }
53
+ else{
54
+ checked = !!this.checked
55
+ }
56
+
57
+ return checked
58
+ }
59
+
60
+ },
61
+
62
+ methods: {
63
+
64
+ onChange(e){
65
+ let value
66
+ if(e.target.checked){
67
+ if(this.value) value = this.value
68
+ else if(this.trueValue) value = this.trueValue
69
+ else value = true
70
+
71
+ if(this.modelValue && Array.isArray(this.modelValue)){
72
+ value = [ ...this.modelValue, value ].filter((v, idx, arr) => {
73
+ return arr.indexOf(v) === idx
74
+ })
75
+ }
76
+ }
77
+ else{
78
+ if(this.value) value = null
79
+ else if(this.falseValue) value = this.falseValue
80
+ else value = false
81
+
82
+
83
+
84
+ if(this.modelValue && Array.isArray(this.modelValue)){
85
+ value = this.modelValue.filter((v) => {
86
+ return v !== this.value ?? (this.falseValue ?? false)
87
+ })
88
+ }
89
+ }
90
+ this.$emit('update:modelValue', value)
91
+ }
92
+
93
+ }
94
+
95
+ }
96
+
97
+ </script>
98
+
99
+ <style module>
100
+
101
+ .comp{
102
+ @apply h-[var(--h-cp)] flex items-center;
103
+ }
104
+
105
+ .comp label{
106
+ @apply flex flex-row items-center gap-2;
107
+ }
108
+
109
+ .comp input{
110
+ @apply hidden;
111
+ }
112
+
113
+ .indicator{
114
+ @apply w-[21px] h-[21px] border-[1px] rounded-full border-text-200 bg-base-50;
115
+ @apply flex items-center justify-center overflow-hidden;
116
+ transition: border 300ms cubic-bezier(0.25, 1, 0.5, 1);
117
+ }
118
+ .comp:hover .indicator{
119
+ @apply border-primary;
120
+ }
121
+
122
+ .indicator>div{
123
+ @apply w-[21px] h-[21px] flex rounded-full items-center justify-center bg-primary;
124
+ transition: all 300ms cubic-bezier(0.25, 1, 0.5, 1);
125
+ transform: scale(0);
126
+ }
127
+ .indicator>div>*{
128
+ @apply fill-white;
129
+ }
130
+ .comp input:checked + label>.indicator>div{
131
+ transform: scale(1);
132
+ }
133
+
134
+ </style>