@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,200 @@
1
+ <template>
2
+ <div :class="computedClass">
3
+ <slot name="start"></slot>
4
+ <input :type="type" :disabled="isDisabled" @focus="isActive = true" @blur="onBlur"
5
+ :placeholder="placeholder" :maxlength="maxlength" ref="input" autocomplete="new-password"
6
+ :value="modelValue ?? value" @input="onInput" :readonly="Boolean(readonly)"
7
+ @keydown="onKeyDown"/>
8
+ <div v-if="!!(errors)">
9
+ <svg :class="$style.svg" width="24" height="24" class="fill-red-500" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
10
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12 13.75C12.4142 13.75 12.75 13.4142 12.75 13V8.00001C12.75 7.5858 12.4142 7.25001 12 7.25001C11.5858 7.25001 11.25 7.5858 11.25 8.00001V13C11.25 13.4142 11.5858 13.75 12 13.75Z"/>
11
+ <path d="M13 16C13 16.5523 12.5523 17 12 17C11.4477 17 11 16.5523 11 16C11 15.4477 11.4477 15 12 15C12.5523 15 13 15.4477 13 16Z"/>
12
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12 20.5C16.6944 20.5 20.5 16.6944 20.5 12C20.5 7.30558 16.6944 3.5 12 3.5C7.30558 3.5 3.5 7.30558 3.5 12C3.5 16.6944 7.30558 20.5 12 20.5ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"/>
13
+ </svg>
14
+ </div>
15
+ <button class="mr-2" v-if="[ '1', 1, true, 'true' ].includes(clearable) && state >= 1 && modelValue" type="button" @click="$emit('clear')">
16
+ <svg :class="$style.svg" width="19" height="19" viewBox="0 0 24 24" class="fill-text-200" xmlns="http://www.w3.org/2000/svg">
17
+ <path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
18
+ </svg>
19
+ </button>
20
+ <slot name="end"></slot>
21
+ </div>
22
+ </template>
23
+
24
+ <script>
25
+
26
+ export default{
27
+
28
+ emits: [ 'update:modelValue', 'change', 'clear', 'submit', 'blur' ],
29
+
30
+ props: {
31
+
32
+ align: {
33
+ type: String
34
+ },
35
+
36
+ clearable: [ Boolean, String, Number ],
37
+
38
+ customClass: String,
39
+
40
+ state: {
41
+ type: Number,
42
+ default: 1 // 1:normal, -1:disabled, -2:error
43
+ },
44
+
45
+ variant: {
46
+ type: String,
47
+ default: ''
48
+ },
49
+
50
+ size: {
51
+ type: String,
52
+ default: ''
53
+ },
54
+
55
+ errors:{
56
+ type: [ String, Array ],
57
+ default: ''
58
+ },
59
+
60
+ modelValue: [ String, Number ],
61
+
62
+ value: String,
63
+
64
+ placeholder: [ String, Number ],
65
+ readonly: undefined,
66
+ maxlength: String,
67
+ type: String,
68
+
69
+ },
70
+
71
+ watch:{
72
+
73
+ modelValue(to, from){
74
+ this.$emit('update:modelValue', to)
75
+ this.$emit('change', to)
76
+ }
77
+
78
+ },
79
+
80
+ computed: {
81
+
82
+ computedState(){
83
+ if(this.errors){
84
+ return -2
85
+ }
86
+ else{
87
+ return this.state
88
+ }
89
+ },
90
+
91
+ computedClass(){
92
+ return this.customClass ?? [
93
+ this.$style.textbox,
94
+ this.$style['state-' + this.computedState],
95
+ this.isActive && !this.readonly ? this.$style.active : '',
96
+ this.align ? this.$style['align-' + this.align] : '',
97
+ this.size ? this.$style['size-' + this.size] : ''
98
+ ].join(' ')
99
+ },
100
+
101
+ isDisabled(){
102
+ return this.state === 2
103
+ }
104
+
105
+ },
106
+
107
+ mounted() {
108
+ this.$refs.input.addEventListener('keyup', this.onKeyUp)
109
+ },
110
+
111
+ data(){
112
+ return {
113
+ isActive: false
114
+ }
115
+ },
116
+
117
+ methods:{
118
+
119
+ select(){
120
+ this.$refs.input.select()
121
+ },
122
+
123
+ onKeyUp(e){
124
+ if(e.keyCode === 13){
125
+ this.$emit('submit')
126
+ }
127
+ else if(e.keyCode === 27 && this.clearable){
128
+ this.$emit('clear')
129
+ }
130
+ },
131
+
132
+ onInput(e){
133
+ this.$emit('update:modelValue', e.target.value)
134
+ this.$emit('change', e.target.value)
135
+ },
136
+
137
+ onBlur(e){
138
+ this.isActive = false
139
+ this.$emit('blur', e.target.value)
140
+ },
141
+
142
+ onKeyDown(e){
143
+ if([ 'number', 'tel' ].includes(this.type)){
144
+ if(((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105) ||
145
+ [ 8, 13 ].includes(e.keyCode)) && !e.ctrlKey && !e.metaKey && !e.shiftKey && !e.altKey);
146
+ else if(e.keyCode === 65 && (e.ctrlKey || e.metaKey));
147
+ else{
148
+ e.preventDefault()
149
+ }
150
+ }
151
+ }
152
+
153
+ }
154
+
155
+ }
156
+
157
+ </script>
158
+
159
+ <style module>
160
+
161
+ .textbox{
162
+ @apply min-h-[var(--h-cp)];
163
+ @apply flex items-center border-[1px] border-text-200 bg-base-50 rounded-lg overflow-hidden;
164
+ }
165
+
166
+ .textbox input:read-only{
167
+ @apply bg-text-50;
168
+ }
169
+
170
+ .size-sm{ @apply min-h-[var(--h-cp-sm)]; }
171
+ .size-sm input{ @apply text-sm; }
172
+
173
+ .size-lg{ @apply min-h-[var(--h-cp-lg)]; }
174
+
175
+ .textbox>input{
176
+ @apply flex-1 outline-none p-2 bg-transparent
177
+ }
178
+
179
+ .active{
180
+ @apply border-primary
181
+ }
182
+
183
+ .state--2{
184
+ @apply border-red-500
185
+ }
186
+ .state--2 .svg{
187
+ @apply fill-red-500
188
+ }
189
+
190
+ .align-left>input{
191
+ @apply text-left
192
+ }
193
+ .align-center>input{
194
+ @apply text-center
195
+ }
196
+ .align-right>input{
197
+ @apply text-right
198
+ }
199
+
200
+ </style>
@@ -0,0 +1,108 @@
1
+ <template>
2
+ <span :class="computedClass">
3
+ <div>
4
+ <slot></slot>
5
+ </div>
6
+ <div class="flex-1">
7
+ <select @change="onChanged" ref="hour">
8
+ <option v-for="_hour in 24" :value="(_hour - 1).toString().padStart(2, '0')"
9
+ :selected="(_hour - 1) === computedHour">
10
+ {{ (_hour - 1).toString().padStart(2, '0') }}
11
+ </option>
12
+ </select>
13
+ </div>
14
+ <div>
15
+ <label>:</label>
16
+ </div>
17
+ <div class="flex-1">
18
+ <select @change="onChanged" ref="minute">
19
+ <option v-for="_minute in 60" :value="(_minute - 1).toString().padStart(2, '0')"
20
+ :selected="(_minute - 1) === computedMinute">
21
+ {{ (_minute - 1).toString().padStart(2, '0') }}
22
+ </option>
23
+ </select>
24
+ </div>
25
+ </span>
26
+ </template>
27
+
28
+ <script>
29
+ export default{
30
+
31
+ props:{
32
+
33
+ modelValue: {
34
+ default: '00:00'
35
+ },
36
+
37
+ size:{
38
+ type: String,
39
+ default: ''
40
+ },
41
+
42
+ },
43
+
44
+ computed:{
45
+
46
+ computedClass(){
47
+ return [
48
+ 'timepicker',
49
+ this.size !== '' ? 'timepicker-' + this.size : ''
50
+ ]
51
+ .join(' ').trim()
52
+ },
53
+
54
+ computedHour(){
55
+ return parseInt(this.modelValue.split(':')[0])
56
+ },
57
+
58
+ computedMinute(){
59
+ return parseInt(this.modelValue.split(':')[1])
60
+ }
61
+
62
+ },
63
+
64
+ emits: [ "update:modelValue" ],
65
+
66
+ methods:{
67
+
68
+ onChanged(){
69
+ const time = this.$refs.hour.value + ':' + this.$refs.minute.value
70
+ this.$emit('update:modelValue', time)
71
+ }
72
+
73
+ }
74
+
75
+ }
76
+ </script>
77
+
78
+ <style>
79
+
80
+ .timepicker{
81
+ @apply inline-flex flex-row items-center bg-base-50;
82
+ }
83
+
84
+ .timepicker label{
85
+ @apply inline-block p-2;
86
+ }
87
+
88
+ .timepicker select{
89
+ @apply w-full p-2 appearance-none bg-transparent outline-none;
90
+ @apply border-[1px] border-text-200 hover:border-text-300 rounded-lg;
91
+ @apply text-center;
92
+ }
93
+
94
+ .timepicker.timepicker-sm select{
95
+ @apply text-sm p-1;
96
+ }
97
+ .timepicker.timepicker-sm label{
98
+ @apply text-sm p-1;
99
+ }
100
+
101
+ .timepicker.timepicker-lg select{
102
+ @apply text-lg p-3;
103
+ }
104
+ .timepicker.timepicker-lg label{
105
+ @apply text-lg p-3;
106
+ }
107
+
108
+ </style>
@@ -0,0 +1,93 @@
1
+ <template>
2
+
3
+ <Teleport to=".dG9h">
4
+ <Transition name="dG9i">
5
+ <div v-if="state" :class="$style.toast" @mouseover="onMouseOver">
6
+ <slot></slot>
7
+ </div>
8
+ </Transition>
9
+ </Teleport>
10
+
11
+ </template>
12
+
13
+ <script>
14
+
15
+ export default{
16
+
17
+ props: {
18
+
19
+ state: [ Boolean, Number, String ],
20
+
21
+ dismissAfter: {
22
+ type: [ Number, String ],
23
+ default: 3000
24
+ }
25
+
26
+ },
27
+
28
+ emits: [ 'dismiss' ],
29
+
30
+ data(){
31
+ return {
32
+ intervalId: null
33
+ }
34
+ },
35
+
36
+ methods: {
37
+
38
+ onMouseOver(){
39
+ if(this.intervalId){
40
+ window.clearTimeout(this.intervalId)
41
+ this.intervalId = null
42
+ }
43
+ }
44
+
45
+ },
46
+
47
+ watch:{
48
+
49
+ state(to){
50
+ if(to){
51
+ this.intervalId = window.setTimeout(() => {
52
+ if(this.state){
53
+ this.$emit('dismiss')
54
+ }
55
+ }, parseInt(this.dismissAfter))
56
+ }
57
+ }
58
+
59
+ }
60
+
61
+ }
62
+
63
+ </script>
64
+
65
+ <style>
66
+
67
+ .dG9h{
68
+ @apply fixed top-0 left-0 right-0;
69
+ z-index: 61;
70
+ }
71
+
72
+ .dG9i-enter-active,
73
+ .dG9i-leave-active {
74
+ transition: all 300ms cubic-bezier(0.25, 1, 0.5, 1);
75
+ }
76
+
77
+ .dG9i-enter-from,
78
+ .dG9i-leave-to {
79
+ opacity: 0;
80
+ transform: translate3d(0, -10vh, 0);
81
+ }
82
+
83
+ </style>
84
+
85
+ <style module>
86
+
87
+ .toast{
88
+ @apply max-w-[90vw] md:max-w-[640px] bg-base-400 mt-4 mx-auto rounded-xl border-[1px] border-text-50;
89
+ @apply min-h-[var(--h-cp)];
90
+ z-index: 61;
91
+ }
92
+
93
+ </style>
@@ -0,0 +1,215 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <div ref="scroller" :class="$style.scroller" :style="scrollerStyle">
4
+ <div v-if="visibleItems && visibleItems.length > 0" :class="$style.spacer" ref="spacer" :style="spacerStyle">
5
+ <div v-for="(item, index) in visibleItems" :key="item" :data-id="item.id"
6
+ @click="select(item, index)"
7
+ :class="[ $style.item, selectedIndex === ((item && item.id) ? item.id : visibleStartIndex + index) ? $style.trSelected : '', item._highlight ? $style.highlight : '' ].join(' ')">
8
+ <slot name="item" :item="item" :index="index"></slot>
9
+ </div>
10
+ </div>
11
+ <div v-else class="flex p-8 justify-center items-center">
12
+ <slot v-if="$slots['empty']" name="empty"></slot>
13
+ <div v-else>No data</div>
14
+ </div>
15
+ </div>
16
+ <div :class="$style.calc" v-if="items && items.length > 0" ref="calc">
17
+ <slot name="item" :item="items[0]" :index="0"></slot>
18
+ </div>
19
+ </div>
20
+ </template>
21
+
22
+ <script>
23
+
24
+ import throttle from "lodash/throttle";
25
+
26
+ export default{
27
+
28
+ emits: [ 'scroll-end' ],
29
+
30
+ props:{
31
+
32
+ items:{
33
+ type: Array, Object
34
+ }
35
+
36
+ },
37
+
38
+ computed:{
39
+
40
+ visibleStartIndex(){
41
+ return Math.round(this.scrollTop / this.itemHeight)
42
+ },
43
+
44
+ visibleItems(){
45
+ if(this.itemHeight <= 0) return []
46
+ return this.items ? this.items.slice(this.visibleStartIndex, this.visibleStartIndex + this.maxVisibleItems) : []
47
+ },
48
+
49
+ spacerStyle(){
50
+ return {
51
+ transform: "translateY(" + (this.visibleStartIndex * this.itemHeight) + "px)"
52
+ }
53
+ },
54
+
55
+ scrollerStyle(){
56
+ if(!this.items || this.items.length < 1)
57
+ return {}
58
+
59
+ const height = (this.items.length * this.itemHeight)
60
+ //console.log('scrollerStyle', height)
61
+
62
+ return {
63
+ height: height + 'px'
64
+ }
65
+ }
66
+
67
+ },
68
+
69
+ data(){
70
+ return {
71
+ scrollTop: 0,
72
+ itemHeight: 0,
73
+ maxVisibleItems: 0,
74
+ isOnEndScroll: false,
75
+ selectedIndex: -1
76
+ }
77
+ },
78
+
79
+ mounted() {
80
+ this.init()
81
+ },
82
+
83
+ methods:{
84
+
85
+ init(){
86
+ this.$el.addEventListener(
87
+ "scroll",
88
+ this.handleScroll,
89
+ this.passiveScrollSupported() ? { passive: true } : false
90
+ )
91
+
92
+ this.resize()
93
+ },
94
+
95
+ select(item, index){
96
+ this.selectedIndex = (item && item.id) ? item.id : this.visibleStartIndex + index
97
+ if(item._highlight){
98
+ delete item._highlight
99
+ }
100
+ },
101
+
102
+ handleScroll: throttle(function(){
103
+ this.scrollTop = this.$el.scrollTop
104
+
105
+ if(this.scrollTop > this.$refs.scroller.offsetHeight - this.$el.clientHeight - this.itemHeight){
106
+ if(!this.isOnEndScroll){
107
+ this.$emit('scroll-end')
108
+ this.isOnEndScroll = true
109
+ }
110
+ }
111
+ else{
112
+ if(this.isOnEndScroll){
113
+ this.isOnEndScroll = false
114
+ }
115
+ }
116
+ }, 10),
117
+
118
+ passiveScrollSupported() {
119
+ let passiveSupported = false;
120
+
121
+ try {
122
+ const options = {
123
+ get passive() {
124
+ passiveSupported = true;
125
+ return false;
126
+ }
127
+ };
128
+ window.addEventListener("test", null, options);
129
+ window.removeEventListener("test", null, options);
130
+ } catch (err) {
131
+ passiveSupported = false;
132
+ }
133
+ return passiveSupported;
134
+ },
135
+
136
+ async resize(){
137
+
138
+ this.$nextTick(() => {
139
+ if(this.$refs.calc){
140
+ const elHeight = parseInt(window.getComputedStyle(this.$el).height !== '0px' ?
141
+ window.getComputedStyle(this.$el).height :
142
+ window.getComputedStyle(this.$el).maxHeight)
143
+ this.itemHeight = parseInt(window.getComputedStyle(this.$refs.calc).height)
144
+ this.maxVisibleItems = elHeight > 0 ? Math.ceil(elHeight / this.itemHeight) + 1 : this.items.length
145
+ //console.log('Virtual scroll resize', { elHeight, itemHeight:this.itemHeight, maxVisibleItems:this.maxVisibleItems })
146
+
147
+ if(this.itemHeight <= 0){
148
+ console.error('[VirtualScroll] Unable to calculate item height, make sure not async component.')
149
+ }
150
+ }
151
+ })
152
+
153
+ }
154
+
155
+ },
156
+
157
+ watch: {
158
+
159
+ items: {
160
+ deep: true,
161
+ handler(){
162
+ this.resize()
163
+ }
164
+ }
165
+
166
+ }
167
+
168
+ }
169
+
170
+ </script>
171
+
172
+ <style module>
173
+
174
+ .comp{
175
+ @apply relative overflow-auto max-h-[100vh];
176
+ }
177
+
178
+ .scroller{
179
+ position: relative;
180
+ overflow: hidden;
181
+ will-change: auto;
182
+ }
183
+
184
+ .spacer{
185
+ will-change: auto;
186
+ position: relative;
187
+ }
188
+
189
+ .item:hover{
190
+ @apply bg-primary-50;
191
+ }
192
+
193
+ .item.trSelected{
194
+ @apply bg-primary-200;
195
+ }
196
+
197
+ .highlight{
198
+ animation: highlight 1s 1 forwards;
199
+ }
200
+ @keyframes highlight {
201
+ 0% {
202
+ @apply bg-primary-50;
203
+ }
204
+
205
+ 100% {
206
+ @apply bg-primary-100;
207
+ }
208
+ }
209
+
210
+ .calc{
211
+ @apply absolute invisible;
212
+ top: -10000px;
213
+ }
214
+
215
+ </style>