@mixd-id/web-scaffold 0.2.250801012 → 0.2.250801014

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 (171) hide show
  1. package/docs/components/AIDashboard.md +472 -0
  2. package/docs/components/WebPageBuilder.md +125 -0
  3. package/package.json +8 -30
  4. package/src/components/AIChat.vue +479 -0
  5. package/src/components/AIChatItem.vue +168 -0
  6. package/src/components/AIChatTextbox.vue +56 -0
  7. package/src/components/AIDashboard.vue +1113 -0
  8. package/src/components/AccountIcon.vue +19 -0
  9. package/src/components/Ahref.vue +200 -0
  10. package/src/components/Alert.vue +257 -0
  11. package/src/components/Article.vue +387 -0
  12. package/src/components/BarChart.vue +87 -0
  13. package/src/components/Block.vue +31 -0
  14. package/src/components/Button.vue +258 -0
  15. package/src/components/Card.vue +255 -0
  16. package/src/components/Carousel.vue +404 -0
  17. package/src/components/Cart.vue +192 -0
  18. package/src/components/CartIcon.vue +89 -0
  19. package/src/components/Chart.vue +486 -0
  20. package/src/components/ChatTyping.vue +69 -0
  21. package/src/components/Checkbox.vue +200 -0
  22. package/src/components/CodeEditor.vue +158 -0
  23. package/src/components/CollapsiblePanel.vue +70 -0
  24. package/src/components/ColorPicker.vue +653 -0
  25. package/src/components/Confirm.vue +180 -0
  26. package/src/components/ContextMenu.vue +265 -0
  27. package/src/components/ContextMenuItem.vue +53 -0
  28. package/src/components/CopyToClipboard.vue +34 -0
  29. package/src/components/Countdown.vue +264 -0
  30. package/src/components/Dashboard.vue +1151 -0
  31. package/src/components/Datepicker.vue +412 -0
  32. package/src/components/Datetimepicker.vue +355 -0
  33. package/src/components/DoughnutChart.vue +68 -0
  34. package/src/components/Dropdown.vue +314 -0
  35. package/src/components/FilterCard.vue +177 -0
  36. package/src/components/Flex.vue +44 -0
  37. package/src/components/Gmaps.vue +251 -0
  38. package/src/components/Grid.vue +35 -0
  39. package/src/components/HTMLEditor.vue +786 -0
  40. package/src/components/IconMenu2.vue +89 -0
  41. package/src/components/Image.vue +311 -0
  42. package/src/components/ImagePreview.vue +93 -0
  43. package/src/components/ImageUploader.vue +111 -0
  44. package/src/components/LineChart.vue +104 -0
  45. package/src/components/Link.vue +95 -0
  46. package/src/components/List.vue +1549 -0
  47. package/src/components/ListItem.vue +160 -0
  48. package/src/components/MarkdownEdit.vue +346 -0
  49. package/src/components/MarkdownPreview.vue +102 -0
  50. package/src/components/MenuItem1.vue +36 -0
  51. package/src/components/Metric.vue +105 -0
  52. package/src/components/MultiDropdown.vue +124 -0
  53. package/src/components/OTPField.vue +139 -0
  54. package/src/components/Paragraph.vue +40 -0
  55. package/src/components/PieChart.vue +67 -0
  56. package/src/components/PresetSelectorFilterItem.vue +204 -0
  57. package/src/components/Radio.vue +109 -0
  58. package/src/components/SearchModal.vue +153 -0
  59. package/src/components/Slider.vue +407 -0
  60. package/src/components/Svg.vue +33 -0
  61. package/src/components/SvgEditor.vue +173 -0
  62. package/src/components/Switch.vue +101 -0
  63. package/src/components/Table.vue +56 -0
  64. package/src/components/Tabs.vue +131 -0
  65. package/src/components/Testimonial.vue +86 -0
  66. package/src/components/Text.vue +34 -0
  67. package/src/components/TextBlock.vue +50 -0
  68. package/src/components/TextWithTag.vue +298 -0
  69. package/src/components/Textarea.vue +195 -0
  70. package/src/components/Textbox.vue +216 -0
  71. package/src/components/Thumbnail.vue +27 -0
  72. package/src/components/Timepicker.vue +223 -0
  73. package/src/components/Toast.vue +117 -0
  74. package/src/components/TreeMenu.vue +122 -0
  75. package/src/components/TreeView.vue +107 -0
  76. package/src/components/TreeViewItem.vue +452 -0
  77. package/src/components/Uploader.vue +45 -0
  78. package/src/components/Video.vue +119 -0
  79. package/src/components/VirtualGrid.vue +296 -0
  80. package/src/components/VirtualTable.vue +1047 -0
  81. package/src/components/YoutubeVideo.vue +196 -0
  82. package/src/configs/web-page-builder.js +118 -0
  83. package/src/directives/intersect.js +26 -0
  84. package/src/hooks/device.js +14 -0
  85. package/src/index.css +3 -0
  86. package/src/index.js +635 -0
  87. package/src/instructions/dashboard.js +203 -0
  88. package/src/mixin/component.js +306 -0
  89. package/src/themes/default/index.js +303 -0
  90. package/src/utils/ai-chat-answer.mjs +240 -0
  91. package/src/utils/ai-chat.js +167 -0
  92. package/src/utils/ai-dashboard-chat.mjs +371 -0
  93. package/src/utils/ai-dashboard.js +321 -0
  94. package/src/utils/ai-list-chat.mjs +407 -0
  95. package/src/utils/dashboard.js +317 -0
  96. package/src/utils/helpers.js +635 -0
  97. package/src/utils/helpers.mjs +722 -0
  98. package/src/utils/list.mjs +1564 -0
  99. package/src/utils/preset-selector.mjs +390 -0
  100. package/src/utils/selection.js +43 -0
  101. package/src/utils/wss.js +311 -0
  102. package/src/utils/wss.mjs +286 -0
  103. package/src/widgets/AhrefSetting.vue +97 -0
  104. package/src/widgets/ArticleSetting.vue +457 -0
  105. package/src/widgets/BackgroundColorSetting.vue +149 -0
  106. package/src/widgets/BlockSetting.vue +49 -0
  107. package/src/widgets/BorderColorSetting.vue +53 -0
  108. package/src/widgets/ButtonSetting.vue +113 -0
  109. package/src/widgets/CarouselSetting.vue +181 -0
  110. package/src/widgets/CartSetting.vue +46 -0
  111. package/src/widgets/CollapsiblePanelSetting.vue +46 -0
  112. package/src/widgets/ColumnSelector.vue +93 -0
  113. package/src/widgets/ComponentSetting.vue +2220 -0
  114. package/src/widgets/ComponentSetting2.vue +927 -0
  115. package/src/widgets/ContactForm.vue +193 -0
  116. package/src/widgets/ContactFormSetting.vue +395 -0
  117. package/src/widgets/CountdownSetting.vue +76 -0
  118. package/src/widgets/DataListSetting.vue +102 -0
  119. package/src/widgets/EmbeddedVideo.vue +60 -0
  120. package/src/widgets/EmbeddedVideoSetting.vue +50 -0
  121. package/src/widgets/FAQ.vue +98 -0
  122. package/src/widgets/FAQSetting.vue +94 -0
  123. package/src/widgets/FeatureList.vue +131 -0
  124. package/src/widgets/FeatureListSetting.vue +233 -0
  125. package/src/widgets/FlexSetting.vue +174 -0
  126. package/src/widgets/GridSetting.vue +165 -0
  127. package/src/widgets/Header2.vue +65 -0
  128. package/src/widgets/Header2Setting.vue +193 -0
  129. package/src/widgets/IconList.vue +51 -0
  130. package/src/widgets/IconListSetting.vue +188 -0
  131. package/src/widgets/ImageSetting.vue +119 -0
  132. package/src/widgets/LLMChat.vue +327 -0
  133. package/src/widgets/LinkSetting.vue +209 -0
  134. package/src/widgets/LinkSettingModal.vue +173 -0
  135. package/src/widgets/MenuItem1Setting.vue +78 -0
  136. package/src/widgets/ModalSetting.vue +94 -0
  137. package/src/widgets/MultiValueSetting.vue +121 -0
  138. package/src/widgets/MultiValueSetting2.vue +147 -0
  139. package/src/widgets/OGSettingModal.vue +103 -0
  140. package/src/widgets/ParagraphSetting.vue +89 -0
  141. package/src/widgets/PositionSetting.vue +209 -0
  142. package/src/widgets/PresetBar.vue +1011 -0
  143. package/src/widgets/PresetBarPivot.vue +330 -0
  144. package/src/widgets/PresetBarPivotColumnEdit.vue +186 -0
  145. package/src/widgets/PresetBarPivotValueEdit.vue +172 -0
  146. package/src/widgets/PresetSelector.vue +713 -0
  147. package/src/widgets/Review.vue +131 -0
  148. package/src/widgets/ReviewSetting.vue +201 -0
  149. package/src/widgets/SearchModalSetting.vue +70 -0
  150. package/src/widgets/Share.vue +164 -0
  151. package/src/widgets/ShareSetting.vue +99 -0
  152. package/src/widgets/SvgSetting.vue +133 -0
  153. package/src/widgets/TableSetting.vue +172 -0
  154. package/src/widgets/TestimonialSetting.vue +161 -0
  155. package/src/widgets/TextBlockSetting.vue +81 -0
  156. package/src/widgets/ThumbnailSetting.vue +49 -0
  157. package/src/widgets/WebComponentSelector.vue +205 -0
  158. package/src/widgets/WebDatasourceSelector.vue +153 -0
  159. package/src/widgets/WebLayoutSelector.vue +139 -0
  160. package/src/widgets/WebPageBuilder.vue +1962 -0
  161. package/src/widgets/YoutubeVideoSetting.vue +68 -0
  162. package/docs/components/ArrayList.md +0 -39
  163. package/docs/components/Box.md +0 -15
  164. package/docs/components/ChartBar.md +0 -34
  165. package/docs/components/DayTimeRange.md +0 -20
  166. package/docs/components/ErrorText.md +0 -15
  167. package/docs/components/FBLogin.md +0 -21
  168. package/docs/components/GHeatMaps.md +0 -16
  169. package/docs/components/GSignIn.md +0 -21
  170. package/docs/components/GmapsDirection.md +0 -20
  171. package/docs/components/IconMenu.md +0 -20
@@ -0,0 +1,168 @@
1
+ <template>
2
+ <div :class="['flex w-full', message.direction === 1 ? 'justify-end' : 'justify-start']">
3
+
4
+ <!-- Typing indicator (assistant, no content yet) -->
5
+ <div v-if="message.isLoading && !message.display"
6
+ class="rounded-3xl px-5 py-4">
7
+ <div class="flex gap-1.5 items-center">
8
+ <span v-for="d in 3" :key="d" class="w-2 h-2 rounded-full bg-text-300 animate-bounce"
9
+ :style="`animation-delay:${(d - 1) * 160}ms`" />
10
+ </div>
11
+ </div>
12
+
13
+ <!-- User bubble -->
14
+ <div v-else-if="message.direction === 1" class="max-w-[85%] flex flex-col items-end gap-2">
15
+ <!-- Image attachments -->
16
+ <div v-if="images.length" class="grid gap-2" :class="images.length > 1 ? 'grid-cols-2' : 'grid-cols-1'">
17
+ <img v-for="(img, n) in images" :key="n" :src="img" loading="lazy"
18
+ class="rounded-2xl max-h-60 w-full object-cover" />
19
+ </div>
20
+ <div v-if="message.body"
21
+ class="bg-base-500 rounded-3xl rounded-br-lg px-5 py-3 whitespace-pre-wrap md:text-lg leading-relaxed">
22
+ {{ message.body }}
23
+ </div>
24
+ </div>
25
+
26
+ <!-- Assistant bubble (markdown + streaming) -->
27
+ <div v-else class="max-w-full w-full">
28
+ <div :class="$style.md" class="md:text-lg leading-relaxed" v-html="renderedContent" />
29
+ <span v-if="message.isLoading" :class="$style.caret">▍</span>
30
+
31
+ <!-- Image attachments -->
32
+ <div v-if="images.length" class="mt-3 grid gap-2" :class="images.length > 1 ? 'grid-cols-2' : 'grid-cols-1 max-w-md'">
33
+ <img v-for="(img, n) in images" :key="n" :src="img" loading="lazy"
34
+ class="rounded-2xl w-full object-cover" />
35
+ </div>
36
+
37
+ <!-- File attachments -->
38
+ <div v-if="files.length" class="mt-3 flex flex-wrap gap-2">
39
+ <a v-for="(url, n) in files" :key="n" :href="url" target="_blank" rel="noopener"
40
+ class="flex items-center gap-2 p-2 pr-3 rounded-xl bg-base-300 hover:bg-base-500 transition-colors no-underline max-w-[260px]">
41
+ <span class="shrink-0 px-2 py-1 rounded-lg text-[10px] font-bold uppercase text-white" :style="{ background: fileColor(url) }">{{ fileExt(url) }}</span>
42
+ <span class="text-sm text-text truncate">{{ fileName(url) }}</span>
43
+ </a>
44
+ </div>
45
+
46
+ <!-- Footer meta -->
47
+ <div v-if="!message.isLoading && (message.ellapsed || message.model)"
48
+ class="mt-2 flex items-center gap-1.5 text-xs text-text-300">
49
+ <span v-if="message.ellapsed">{{ message.ellapsed }}ms</span>
50
+ <span v-if="message.ellapsed && message.model">·</span>
51
+ <span v-if="message.model">{{ message.model }}</span>
52
+ </div>
53
+ </div>
54
+
55
+ </div>
56
+ </template>
57
+
58
+ <script setup>
59
+ import { computed } from 'vue'
60
+ import { Marked } from 'marked'
61
+ import hljs from 'highlight.js'
62
+
63
+ const { message } = defineProps({
64
+ message: { type: Object, required: true },
65
+ })
66
+
67
+ // Local Marked instance — avoids mutating global marked state on each mount.
68
+ const markdown = new Marked({
69
+ gfm: true,
70
+ breaks: true,
71
+ renderer: {
72
+ code({ text, lang }) {
73
+ const language = lang && hljs.getLanguage(lang) ? lang : 'plaintext'
74
+ const html = hljs.highlight(text, { language }).value
75
+ return `<pre><code class="hljs language-${language}">${html}</code></pre>`
76
+ },
77
+ },
78
+ })
79
+
80
+ const renderedContent = computed(() => markdown.parse(message.display ?? message.body ?? ''))
81
+
82
+ /* ---------- Attachments ---------- */
83
+ const attachments = computed(() => message.attachments ?? [])
84
+ const images = computed(() =>
85
+ attachments.value.filter(a => a.type === 'image').map(a => a.url ?? a.image),
86
+ )
87
+ const files = computed(() =>
88
+ attachments.value.filter(a => a.type === 'file' || a.type === 'url').map(a => a.url),
89
+ )
90
+
91
+ function fileName(url) {
92
+ return (url || '').split('/').pop() || url
93
+ }
94
+ function fileExt(url) {
95
+ return ((url || '').split('.').pop() || 'file').slice(0, 4)
96
+ }
97
+
98
+ const EXT_COLORS = {
99
+ pdf: '#c0392b', doc: '#2b5fa8', docx: '#2b5fa8',
100
+ xls: '#1d6f42', xlsx: '#1d6f42', csv: '#1d6f42',
101
+ zip: '#7f8c8d', png: '#8e44ad', jpg: '#8e44ad',
102
+ }
103
+ function fileColor(url) {
104
+ return EXT_COLORS[fileExt(url).toLowerCase()] ?? '#444'
105
+ }
106
+ </script>
107
+
108
+ <style module>
109
+ /* Animated caret shown while the assistant is streaming */
110
+ .caret {
111
+ @apply inline-block ml-0.5 text-text-300;
112
+ animation: blink 1s steps(2, start) infinite;
113
+ }
114
+ @keyframes blink {
115
+ to { visibility: hidden; }
116
+ }
117
+
118
+ /* Markdown layout. Explicit !important is required because tailwind.config.js
119
+ uses `important: true`, which makes preflight resets beat these rules. */
120
+ .md :global(p) { margin: 0.5em 0 !important; }
121
+ .md :global(p:first-child){ margin-top: 0 !important; }
122
+ .md :global(p:last-child) { margin-bottom: 0 !important; }
123
+ .md :global(ul) { list-style-type: disc !important; padding-left: 1.5em !important; margin: 0.6em 0 !important; }
124
+ .md :global(ol) { list-style-type: decimal !important; padding-left: 1.5em !important; margin: 0.6em 0 !important; }
125
+ .md :global(li) { display: list-item !important; margin: 0.2em 0 !important; }
126
+ .md :global(strong) { font-weight: 700 !important; }
127
+ .md :global(em) { font-style: italic !important; }
128
+ .md :global(a) { color: #89b4fa !important; text-decoration: underline !important; }
129
+ .md :global(h1), .md :global(h2),
130
+ .md :global(h3), .md :global(h4) { font-weight: 700 !important; margin: 0.8em 0 0.3em !important; line-height: 1.3 !important; }
131
+ .md :global(h1) { font-size: 1.5em !important; }
132
+ .md :global(h2) { font-size: 1.3em !important; }
133
+ .md :global(h3) { font-size: 1.1em !important; }
134
+ .md :global(table) { border-collapse: collapse !important; width: 100% !important; margin: 0.8em 0 !important; display: block; overflow-x: auto; }
135
+ .md :global(th), .md :global(td) { border: 1px solid rgba(128,128,128,0.35) !important; padding: 0.4em 0.7em !important; text-align: left !important; }
136
+ .md :global(th) { font-weight: 600 !important; background: rgba(128,128,128,0.1) !important; }
137
+ .md :global(blockquote) { border-left: 3px solid rgba(128,128,128,0.4) !important; padding-left: 1em !important; margin: 0.6em 0 !important; opacity: 0.8; }
138
+ .md :global(hr) { border-color: rgba(128,128,128,0.3) !important; margin: 1em 0 !important; }
139
+ .md :global(:not(pre) > code) {
140
+ background: rgba(128,128,128,0.18) !important;
141
+ padding: 0.12em 0.4em !important;
142
+ border-radius: 0.3em !important;
143
+ font-size: 0.88em !important;
144
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace !important;
145
+ }
146
+
147
+ /* highlight.js — Catppuccin Mocha. !important needed for the same reason. */
148
+ .md :global(code.hljs) {
149
+ display: block !important;
150
+ overflow-x: auto !important;
151
+ padding: 1rem !important;
152
+ border-radius: 0.5rem !important;
153
+ margin: 0.5rem 0 !important;
154
+ font-size: 0.85em !important;
155
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace !important;
156
+ background: #1e1e2e !important;
157
+ color: #cdd6f4 !important;
158
+ }
159
+ .md :global(code.hljs *) { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace !important; }
160
+ .md :global(.hljs-keyword), .md :global(.hljs-selector-tag), .md :global(.hljs-title) { color: #cba6f7 !important; }
161
+ .md :global(.hljs-string), .md :global(.hljs-attr) { color: #a6e3a1 !important; }
162
+ .md :global(.hljs-number), .md :global(.hljs-literal) { color: #fab387 !important; }
163
+ .md :global(.hljs-comment) { color: #6c7086 !important; font-style: italic; }
164
+ .md :global(.hljs-built_in), .md :global(.hljs-name) { color: #89b4fa !important; }
165
+ .md :global(.hljs-variable), .md :global(.hljs-template-variable) { color: #f38ba8 !important; }
166
+ .md :global(.hljs-type) { color: #f9e2af !important; }
167
+ .md :global(.hljs-tag) { color: #f38ba8 !important; }
168
+ </style>
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <div class="flex items-end gap-2 bg-base-500 rounded-3xl border-[1px] border-border-50 p-2 pl-4 focus-within:border-border-200 transition-colors">
3
+ <textarea ref="textarea"
4
+ v-model="draft"
5
+ rows="1"
6
+ class="resize-none flex-1 bg-transparent outline-none py-2 md:text-lg leading-relaxed max-h-[40vh]"
7
+ placeholder="Message AI…"
8
+ @input="resize"
9
+ @keydown="onKeydown" />
10
+ <button type="button"
11
+ class="shrink-0 w-9 h-9 rounded-full flex items-center justify-center transition-colors"
12
+ :class="canSend ? 'bg-primary hover:opacity-90' : 'bg-base-200 opacity-50 cursor-default'"
13
+ :disabled="!canSend"
14
+ @click="sending ? emit('cancel') : submit()">
15
+ <svg v-if="!sending" width="15" height="15" class="fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M214.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 141.2V448c0 17.7 14.3 32 32 32s32-14.3 32-32V141.2L329.4 246.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160z"/></svg>
16
+ <svg v-else width="13" height="13" class="fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M0 128C0 92.7 28.7 64 64 64H320c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128z"/></svg>
17
+ </button>
18
+ </div>
19
+ </template>
20
+
21
+ <script setup>
22
+ import { computed, nextTick, ref, useTemplateRef } from 'vue'
23
+
24
+ const { sending } = defineProps({
25
+ sending: { type: Boolean, default: false },
26
+ })
27
+
28
+ const emit = defineEmits(['send', 'cancel'])
29
+
30
+ const draft = ref('')
31
+ const textarea = useTemplateRef('textarea')
32
+
33
+ const canSend = computed(() => sending || draft.value.trim().length > 0)
34
+
35
+ function resize() {
36
+ const el = textarea.value
37
+ if (!el) return
38
+ el.style.height = 'auto'
39
+ el.style.height = `${el.scrollHeight}px`
40
+ }
41
+
42
+ function onKeydown(e) {
43
+ if (e.key === 'Enter' && !e.shiftKey) {
44
+ e.preventDefault()
45
+ submit()
46
+ }
47
+ }
48
+
49
+ function submit() {
50
+ const content = draft.value.trim()
51
+ if (!content || sending) return
52
+ draft.value = ''
53
+ nextTick(resize)
54
+ emit('send', content)
55
+ }
56
+ </script>