@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,201 @@
1
+ <template>
2
+ <div :class="computedClass">
3
+
4
+ <TableViewHead v-if="header" :columns="columns" @resize="(idx, d) => $emit('resize', idx, d)"></TableViewHead>
5
+
6
+ <table cellpadding="0" cellspacing="0">
7
+
8
+ <thead>
9
+ <tr>
10
+ <th v-for="column in columns" :style="columnStyle(column)"></th>
11
+ <th :class="$style.spacer"></th>
12
+ </tr>
13
+ </thead>
14
+
15
+ <tbody>
16
+ <tr v-for="item in items" @click="activate($event.target.closest('tr'))">
17
+ <td v-for="column in columns" :style="tdStyle(column)">
18
+ <slot v-if="$slots[column.key]" :name="column.key" :column="column" :item="item"></slot>
19
+ <label v-else>{{ formatText(item[column.key], column) }}</label>
20
+ </td>
21
+ <td :class="$style.spacer">
22
+ <slot name="mobile" :item="item"></slot>
23
+ </td>
24
+ </tr>
25
+ </tbody>
26
+
27
+ </table>
28
+
29
+ <div v-if="hasNext" ref="loadNext" class="p-2 text-center">Load...</div>
30
+
31
+ </div>
32
+ </template>
33
+
34
+ <script>
35
+
36
+ import TableViewHead from "./TableViewHead.vue";
37
+ import dayjs from "dayjs";
38
+ import { h } from "vue";
39
+
40
+ const DEFAULT_COLUMN_WIDTH = 125
41
+
42
+ export default{
43
+
44
+ components: {
45
+ TableViewHead
46
+ },
47
+
48
+ props:{
49
+ columns: Array,
50
+ items: Array,
51
+ header: {
52
+ type: Boolean,
53
+ default: true
54
+ },
55
+ hasNext: {
56
+ type: Boolean,
57
+ default: false
58
+ },
59
+ mobileView: {
60
+ type: [ Boolean, String ],
61
+ default: false
62
+ }
63
+ },
64
+
65
+ computed:{
66
+
67
+ computedClass(){
68
+
69
+ return [
70
+ this.$style.comp,
71
+ Boolean(this.mobileView) ? this.$style.mobileView : ''
72
+ ]
73
+ .join(' ')
74
+ }
75
+
76
+ },
77
+
78
+ data(){
79
+ return {
80
+ activeTr: null
81
+ }
82
+ },
83
+
84
+ methods:{
85
+
86
+ activate(tr){
87
+ if(this.activeTr){
88
+ this.activeTr.classList.remove(this.$style.activeTr)
89
+ }
90
+ tr.classList.add(this.$style.activeTr)
91
+ this.activeTr = tr
92
+ },
93
+
94
+ columnStyle(column){
95
+
96
+ const width = parseInt(column.width)
97
+
98
+ return {
99
+ width: (!isNaN(width) ? width : DEFAULT_COLUMN_WIDTH) + 'px'
100
+ }
101
+ },
102
+
103
+ onNext(){
104
+ this.$emit('next')
105
+ },
106
+
107
+ formatText(text, column){
108
+
109
+ if(column.format){
110
+ const [ type, params ] = column.format.toString().split('|')
111
+
112
+ switch(type){
113
+
114
+ case 'currency':
115
+ text = parseInt(text)
116
+ if(isNaN(text)) text = '-'
117
+ text = text.toLocaleString()
118
+ break
119
+
120
+ case 'date':
121
+ const dateFormat = params ?? 'YYYY-MM-DD'
122
+ text = dayjs(text).format(dateFormat)
123
+ break
124
+ }
125
+ }
126
+
127
+ return text
128
+ },
129
+
130
+ tdStyle(column){
131
+
132
+ const style = {}
133
+
134
+ if(column.align){
135
+ style['textAlign'] = column.align
136
+ }
137
+
138
+ return style
139
+ },
140
+
141
+ },
142
+
143
+ watch:{
144
+
145
+ hasNext(to){
146
+ if(to){
147
+ this.$nextTick(() => {
148
+ if(this.$refs.loadNext){
149
+ this.$observe.always(this.$refs.loadNext, this.onNext)
150
+ }
151
+ })
152
+ }
153
+ }
154
+
155
+ }
156
+
157
+ }
158
+
159
+ </script>
160
+
161
+ <style module>
162
+
163
+ .comp{
164
+ @apply bg-base
165
+ }
166
+
167
+ .comp table{
168
+ @apply border-collapse bg-base;
169
+ table-layout: fixed;
170
+ width: 100%;
171
+ }
172
+
173
+ .comp tbody td{
174
+ @apply relative border-b-[1px] border-text-50;
175
+ }
176
+
177
+ .comp td,
178
+ .comp th{
179
+ vertical-align: top;
180
+ @apply hidden md:table-cell
181
+ }
182
+ .comp td.spacer{
183
+ @apply table-cell w-full md:hidden
184
+ }
185
+ .comp.mobileView td,
186
+ .comp.mobileView th{
187
+ @apply hidden
188
+ }
189
+ .comp.mobileView td.spacer{
190
+ @apply table-cell w-full
191
+ }
192
+
193
+ .comp td>label{
194
+ @apply p-2 block
195
+ }
196
+
197
+ .activeTr{
198
+ @apply bg-text-50
199
+ }
200
+
201
+ </style>
@@ -0,0 +1,159 @@
1
+ <template>
2
+ <div :class="computedClass">
3
+ <table cellpadding="0" cellspacing="0">
4
+
5
+ <thead>
6
+ <tr>
7
+ <th v-for="column in columns" :style="columnStyle(column)"></th>
8
+ <th :class="$style.spacer"></th>
9
+ </tr>
10
+ </thead>
11
+
12
+ <tbody>
13
+ <tr>
14
+ <td v-for="column in columns" :style="tdStyle(column)">
15
+ <div v-if="isHTML(column.title)" v-html="column.title"></div>
16
+ <label v-else>{{ column.title }}</label>
17
+ <div :class="$style.separator" ref="separators" @mousedown="onSeparator"></div>
18
+ </td>
19
+ <td :class="$style.spacer"></td>
20
+ </tr>
21
+ </tbody>
22
+
23
+ </table>
24
+ </div>
25
+ </template>
26
+
27
+ <script>
28
+
29
+ const DEFAULT_COLUMN_WIDTH = 125
30
+
31
+ export default{
32
+
33
+ props:{
34
+
35
+ columns: Array,
36
+
37
+ mobileView: {
38
+ type: [ Boolean, String ],
39
+ default: false
40
+ }
41
+
42
+ },
43
+
44
+ computed: {
45
+
46
+ computedClass(){
47
+ return [
48
+ this.$style.comp,
49
+ Boolean(this.mobileView) ? this.$style.mobileView : ''
50
+ ]
51
+ .join(' ')
52
+ }
53
+
54
+ },
55
+
56
+ methods:{
57
+
58
+ columnStyle(column){
59
+
60
+ const width = parseInt(column.width)
61
+
62
+ return {
63
+ width: (!isNaN(width) ? width : DEFAULT_COLUMN_WIDTH) + 'px'
64
+ }
65
+ },
66
+
67
+ tdStyle(column){
68
+
69
+ const style = {}
70
+
71
+ if(column.align){
72
+ style['textAlign'] = column.align
73
+ }
74
+
75
+ return style
76
+ },
77
+
78
+ isHTML(text){
79
+ return text.toString().indexOf('<') >= 0 &&
80
+ text.toString().indexOf('>') >= 0
81
+ },
82
+
83
+ onSeparator(e){
84
+
85
+ const comp = e.target
86
+ const idx = this.$refs.separators.indexOf(comp)
87
+
88
+ let x1 = e.touches ? e.touches[0].clientX : e.clientX
89
+ const onMouseMove = (e) => {
90
+ const x2 = e.touches ? e.touches[0].clientX : e.clientX
91
+ const d = x2 - x1
92
+ x1 = x2
93
+ this.$emit('resize', idx, d)
94
+ }
95
+
96
+ const onMouseUp = (e) => {
97
+ window.removeEventListener('mousemove', onMouseMove)
98
+ window.removeEventListener('mouseup', onMouseUp)
99
+ }
100
+
101
+ window.addEventListener('mousemove', onMouseMove)
102
+ window.addEventListener('mouseup', onMouseUp)
103
+
104
+ }
105
+
106
+ },
107
+
108
+ watch: {
109
+
110
+ column:{
111
+ handler(to){
112
+ console.log('column changed')
113
+ },
114
+ deep: true
115
+ }
116
+
117
+ }
118
+
119
+ }
120
+
121
+ </script>
122
+
123
+ <style module>
124
+
125
+ .comp{
126
+ @apply hidden md:block bg-base;
127
+ }
128
+ .comp.mobileView{
129
+ @apply hidden
130
+ }
131
+
132
+ .comp table{
133
+ @apply border-collapse;
134
+ table-layout: fixed;
135
+ width: 100%;
136
+ }
137
+
138
+ .comp tbody td{
139
+ @apply bg-base relative border-r-[1px] border-text-50;
140
+ vertical-align: top;
141
+ }
142
+
143
+ .comp td>label{
144
+ @apply p-2 block
145
+ }
146
+
147
+ .comp label{
148
+ @apply text-text-300
149
+ }
150
+
151
+ .separator{
152
+ @apply absolute top-0 right-0 bottom-0 w-[5px] cursor-e-resize;
153
+ }
154
+
155
+ .spacer{
156
+ @apply w-full
157
+ }
158
+
159
+ </style>
@@ -0,0 +1,74 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <button v-for="(item, index) in items" :class="tabClass(item)"
4
+ @click="onClick(item)" type="button" >
5
+ <slot v-if="$slots.tab" name="tab" :="{ item, index }"></slot>
6
+ <div v-else :class="$style.item">
7
+ {{ item.text }}
8
+ </div>
9
+ </button>
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+
15
+ export default{
16
+
17
+ emits: [ 'change', 'update:modelValue' ],
18
+
19
+ props: {
20
+ modelValue: undefined,
21
+ bodyClass: String,
22
+ items: Array
23
+ },
24
+
25
+ computed: {
26
+
27
+ },
28
+
29
+ methods: {
30
+
31
+ onClick(item){
32
+ this.$emit('update:modelValue', item.value)
33
+ this.$emit('change', item.value)
34
+ },
35
+
36
+ tabClass(item){
37
+ return [
38
+ this.bodyClass,
39
+ item.value === this.modelValue ? 'active' : ''
40
+ ]
41
+ .join(' ')
42
+ }
43
+
44
+ }
45
+
46
+ }
47
+
48
+ </script>
49
+
50
+ <style module>
51
+
52
+ .comp{
53
+ @apply overflow-x-auto;
54
+ @apply flex flex-row;
55
+ scrollbar-width: none;
56
+ }
57
+ .comp::-webkit-scrollbar {
58
+ display: none;
59
+ }
60
+
61
+ .comp>*{
62
+ @apply border-b-[2px] border-transparent;
63
+ @apply p-2;
64
+ }
65
+
66
+ .comp>*[class*="active"]{
67
+ @apply border-b-[2px] border-primary;
68
+ }
69
+
70
+ .item{
71
+ @apply whitespace-nowrap overflow-hidden;
72
+ }
73
+
74
+ </style>
@@ -0,0 +1,85 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <Textbox v-model="modelValue.text" @blur="$emit('change')" class="border-none"/>
4
+ <div class="bg-base-300 flex flex-row gap-2 border-t-[1px] border-text-200 px-2">
5
+ <Dropdown v-model="modelValue.tagName" size="sm" variant="transparent">
6
+ <option value="default">Default</option>
7
+ <option value="h1">Heading 1</option>
8
+ <option value="h2">Heading 2</option>
9
+ <option value="h3">Heading 3</option>
10
+ <option value="h4">Heading 4</option>
11
+ <option value="h5">Heading 5</option>
12
+ <option value="custom">Custom</option>
13
+ </Dropdown>
14
+ <Dropdown v-if="modelValue.style && modelValue.tagName === 'custom'"
15
+ v-model="modelValue.style.fontFamily" size="sm" variant="transparent">
16
+ <option value="default">Default</option>
17
+ <option value="Arial">Arial</option>
18
+ <option value="Arial Black">Arial Black</option>
19
+ <option value="Impact">Impact</option>
20
+ <option value="Helvetica">Helvetica</option>
21
+ </Dropdown>
22
+ <Dropdown v-if="modelValue.style && modelValue.tagName === 'custom'"
23
+ v-model="modelValue.style.fontSize" size="sm" variant="transparent">
24
+ <option value="default">Default</option>
25
+ <option value="48px">48px</option>
26
+ <option value="42px">42px</option>
27
+ <option value="36px">36px</option>
28
+ <option value="32px">32px</option>
29
+ <option value="28px">28px</option>
30
+ <option value="24px">24px</option>
31
+ <option value="22px">22px</option>
32
+ <option value="21px">21px</option>
33
+ <option value="20px">20px</option>
34
+ <option value="18px">18px</option>
35
+ <option value="16px">16px</option>
36
+ <option value="14px">14px</option>
37
+ <option value="13px">13px</option>
38
+ <option value="12px">12px</option>
39
+ <option value="11px">11px</option>
40
+ </Dropdown>
41
+ </div>
42
+ </div>
43
+ </template>
44
+
45
+ <script>
46
+
47
+ /**
48
+ * modelValue: { text:"", style:"", tagName:"" }
49
+ */
50
+
51
+ export default{
52
+
53
+ props: {
54
+
55
+ modelValue: Object
56
+
57
+ },
58
+
59
+ mounted() {
60
+ if(this.modelValue){
61
+ if(!this.modelValue.style){
62
+ this.modelValue.style = {
63
+ fontFamily: 'default',
64
+ fontSize: 'default',
65
+ }
66
+ }
67
+
68
+ if(!this.modelValue.tagName){
69
+ this.modelValue.tagName = 'default'
70
+ }
71
+ }
72
+ console.log('mounted', this.modelValue)
73
+ }
74
+
75
+ }
76
+
77
+ </script>
78
+
79
+ <style module>
80
+
81
+ .comp{
82
+ @apply flex flex-col border-[1px] border-text-200 bg-base-50 rounded-lg overflow-hidden;
83
+ }
84
+
85
+ </style>
@@ -0,0 +1,184 @@
1
+ <template>
2
+ <div :class="computedClass">
3
+ <slot name="start"></slot>
4
+ <textarea @keyup="onKeyUp"
5
+ :placeholder="placeholder" :rows="rows" ref="input" @blur="onBlur" @input="onInput"
6
+ :value="modelValue" />
7
+ <div v-if="state === -2 && !!(errors)">
8
+ <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
9
+ <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"/>
10
+ <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"/>
11
+ <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"/>
12
+ </svg>
13
+ </div>
14
+ <slot name="end"></slot>
15
+ </div>
16
+ </template>
17
+
18
+ <script>
19
+
20
+ export default{
21
+
22
+ name: 'Textarea',
23
+
24
+ props: {
25
+
26
+ align: {
27
+ type: String
28
+ },
29
+
30
+ customClass: String,
31
+
32
+ state: {
33
+ type: Number,
34
+ default: 1 // 1:normal, -1:disabled, -2:error
35
+ },
36
+
37
+ variant: {
38
+ type: String,
39
+ default: ''
40
+ },
41
+
42
+ size: {
43
+ type: String,
44
+ default: ''
45
+ },
46
+
47
+ errors:{
48
+ type: [ String, Array ],
49
+ default: ''
50
+ },
51
+
52
+ modelValue: [ String, Number ],
53
+
54
+ placeholder: String,
55
+ rows: String,
56
+
57
+ },
58
+
59
+ watch:{
60
+
61
+ modelValue(to, from){
62
+ this.$emit('update:modelValue', to)
63
+ this.$emit('change', to)
64
+ this.$nextTick(() => {
65
+ this.$el.style.height = '';
66
+ this.$el.style.height = this.$refs.input.scrollHeight + 'px'
67
+ })
68
+ }
69
+
70
+ },
71
+
72
+ emits: [ 'update:modelValue', 'change', 'submit', 'blur' ],
73
+
74
+ computed: {
75
+
76
+ computedState(){
77
+ if(this.errors){
78
+ return -2
79
+ }
80
+ else{
81
+ return this.state
82
+ }
83
+ },
84
+
85
+ computedClass(){
86
+ return this.customClass ?? [
87
+ this.$style.textarea,
88
+ this.$style['state-' + this.computedState],
89
+ this.isActive ? this.$style.active : '',
90
+ this.align ? this.$style['align-' + this.align] : '',
91
+ this.size ? this.$style['size-' + this.size] : ''
92
+ ].join(' ')
93
+ },
94
+
95
+ isDisabled(){
96
+
97
+ }
98
+
99
+ },
100
+
101
+ data(){
102
+ return {
103
+ isActive: false
104
+ }
105
+ },
106
+
107
+ mounted() {
108
+ },
109
+
110
+ methods:{
111
+
112
+ select(){
113
+ this.$refs.input.select()
114
+ },
115
+
116
+ onKeyUp(e){
117
+ if(e.keyCode === 13 && this.$refs.input.value.length > 0){
118
+ this.$emit('submit')
119
+ }
120
+ else if(e.keyCode === 27 && this.clearable){
121
+ this.$emit('clear')
122
+ }
123
+ },
124
+
125
+ onInput(e){
126
+ this.$emit('update:modelValue', e.target.value)
127
+ },
128
+
129
+ onBlur(){
130
+ this.isActive = false
131
+ this.$emit('blur')
132
+ }
133
+
134
+ }
135
+
136
+ }
137
+
138
+ </script>
139
+
140
+ <style module>
141
+
142
+ .textarea{
143
+ @apply min-h-[var(--h-cp)];
144
+ @apply flex items-start border-[1px] border-text-100 bg-base-50 rounded-lg overflow-hidden;
145
+ @apply !max-h-[200px];
146
+ }
147
+ .textarea textarea{
148
+ @apply flex-1 outline-none p-2 bg-transparent resize-none;
149
+ @apply self-stretch;
150
+ scrollbar-width: none;
151
+ }
152
+ .textarea>textarea::-webkit-scrollbar{
153
+ display: none;
154
+ }
155
+ .textarea>textarea::placeholder{
156
+ @apply text-text-200;
157
+ }
158
+
159
+ .size-sm{ @apply min-h-[var(--h-cp-sm)]; }
160
+ .size-sm textarea{ @apply text-sm; }
161
+
162
+ .size-lg{ @apply min-h-[var(--h-cp-lg)]; }
163
+ .size-lg textarea{ @apply text-lg p-3; }
164
+
165
+
166
+ .active{
167
+ @apply border-primary
168
+ }
169
+
170
+ .state--2{
171
+ @apply border-red-500
172
+ }
173
+
174
+ .align-left>input{
175
+ @apply text-left
176
+ }
177
+ .align-center>input{
178
+ @apply text-center
179
+ }
180
+ .align-right>input{
181
+ @apply text-right
182
+ }
183
+
184
+ </style>