@mixd-id/web-scaffold 0.1.2207220538 → 0.1.2207250711

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/.env ADDED
@@ -0,0 +1 @@
1
+ NODE_ENV=local
package/index.html ADDED
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" href="/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <meta name="description" content="/* default description */" />
8
+ <meta name="keywords" content="/* default keywords */" />
9
+ <meta name="author" content="/* default author */" />
10
+ <title><!-- default title --></title>
11
+ <script id="hydration">window.__hydration = JSON.parse('<!--serialize-pinia-->')</script>
12
+ <script>
13
+ document.querySelector('html').setAttribute('data-theme', localStorage.getItem('theme') ?? '')
14
+ </script>
15
+ <!--preload-links-->
16
+ </head>
17
+ <body>
18
+ <div><!--app-html--><div class="context-overlay"><!--context-overlay--></div></div>
19
+ <div class="alert-overlay"><!--alert-overlay--></div>
20
+ <div class="modal-overlay"><!--modal-overlay--></div>
21
+
22
+ <script type="module" src="/src/entry-client.js"></script>
23
+ </body>
24
+ </html>
package/package.json CHANGED
@@ -1,23 +1,17 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.2207220538",
4
+ "version": "0.1.2207250711",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
8
8
  "start": "node server.js"
9
9
  },
10
- "main": "./dist/webfxfy.umd.js",
10
+ "main": "./src/index.js",
11
11
  "exports": {
12
- ".": {
13
- "import": "./dist/webfxfy.es.js",
14
- "require": "./dist/webfxfy.umd.js"
15
- },
16
- "./style.css": "./dist/style.css"
12
+ ".": "./src/index.js",
13
+ "./themes/default": "./src/themes/index.js"
17
14
  },
18
- "files": [
19
- "dist"
20
- ],
21
15
  "dependencies": {
22
16
  "@faker-js/faker": "^7.3.0",
23
17
  "@tailwindcss/line-clamp": "^0.4.0",
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
package/server.js ADDED
@@ -0,0 +1,95 @@
1
+ // @ts-check
2
+ const fs = require('fs')
3
+ const path = require('path')
4
+ const express = require('express')
5
+ const cors = require('cors')
6
+ const cookieParser = require('cookie-parser')
7
+
8
+ const isTest = process.env.NODE_ENV === 'test' || !!process.env.VITE_TEST_BUILD
9
+
10
+ const root = process.cwd()
11
+
12
+ async function createServer() {
13
+ const resolve = (p) => path.resolve(__dirname, p)
14
+
15
+ const indexProd = ''
16
+
17
+ const manifest = {}
18
+
19
+ const app = express()
20
+ app.disable('x-powered-by')
21
+ app.use(cookieParser())
22
+
23
+ app.use(express.json())
24
+ app.use(cors())
25
+
26
+ const http = require('http').createServer(app)
27
+
28
+ const vite = await require('vite').createServer({
29
+ root,
30
+ logLevel: isTest ? 'error' : 'info',
31
+ server: {
32
+ middlewareMode: 'ssr',
33
+ watch: {
34
+ usePolling: true,
35
+ interval: 100
36
+ }
37
+ }
38
+ })
39
+ app.use(vite.middlewares)
40
+
41
+ app.use('*', async (req, res, next) => {
42
+
43
+ if(req.originalUrl.indexOf('socket.io') >= 0){
44
+ return next()
45
+ }
46
+
47
+ try {
48
+ const url = req.originalUrl
49
+
50
+ let template, render
51
+ template = fs.readFileSync(resolve('index.html'), 'utf-8')
52
+ template = await vite.transformIndexHtml(url, template)
53
+ render = (await vite.ssrLoadModule('/src/entry-server.js')).render
54
+
55
+ const [appHtml, preloadLinks, serializePinia, redirect, cookie, modalOverlay, alertOverlay, contextOverlay ] = await render(req, manifest)
56
+
57
+ if(cookie.length > 0){
58
+ for(var i in cookie){
59
+ res.cookie(cookie[i][0], cookie[i][1])
60
+ }
61
+ }
62
+
63
+ if(typeof redirect !== 'undefined'){
64
+ res.redirect(redirect)
65
+ }
66
+ else{
67
+ const html = template
68
+ .replace(`<!--preload-links-->`, preloadLinks)
69
+ .replace(`<!--app-html-->`, appHtml)
70
+ .replace(`<!--serialize-pinia-->`, serializePinia)
71
+ .replace(`<!--context-overlay-->`, contextOverlay)
72
+ .replace(`<!--modal-overlay-->`, modalOverlay)
73
+ .replace(`<!--alert-overlay-->`, alertOverlay)
74
+
75
+ res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
76
+ }
77
+ }
78
+ catch (e) {
79
+ vite && vite.ssrFixStacktrace(e)
80
+ console.log(e.stack)
81
+ res.status(500).end(e.stack)
82
+ }
83
+
84
+ })
85
+
86
+ return { http, app, vite }
87
+ }
88
+
89
+ createServer().then(({ http }) =>{
90
+
91
+ http.listen(3001, () => {
92
+ console.log('Listening on port ' + 3001)
93
+ })
94
+
95
+ })
package/src/App.vue ADDED
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <router-view></router-view>
3
+ </template>
@@ -0,0 +1,151 @@
1
+ const createAlert = () => {
2
+
3
+ let overlay = document.querySelector('.alert-overlay')
4
+ let alert = document.querySelector('.alert')
5
+
6
+ if(!overlay){
7
+ overlay = document.createElement("div")
8
+ overlay.className = "alert-overlay"
9
+ document.body.appendChild(overlay)
10
+ }
11
+
12
+ if(!alert){
13
+ alert = document.createElement("div")
14
+ alert.className = "alert"
15
+ alert.innerHTML = `
16
+ <div class="alert-body text-center">
17
+ <svg width="120" height="120" class="inline-block fill-red-600" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
18
+ <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"/>
19
+ <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"/>
20
+ <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"/>
21
+ </svg>
22
+ <div class="my-4">
23
+ <label class="text-xl alert-title font-bold text-xl"></label>
24
+ <p class="alert-desc text-lg"></p>
25
+ </div>
26
+ </div>
27
+ <div class="alert-foot"></div>`
28
+ overlay.appendChild(alert)
29
+ }
30
+
31
+ return {
32
+ overlay,
33
+ alert
34
+ }
35
+ }
36
+
37
+ const openAlert = (type) => {
38
+
39
+ const { alert, overlay } = createAlert()
40
+
41
+ overlay.appendChild(alert)
42
+
43
+ overlay.classList.add('on')
44
+
45
+ alert.classList.add('on')
46
+ window.setTimeout(() => {
47
+ alert.classList.add('active')
48
+ }, 30)
49
+
50
+ alert.classList.remove('alert-error')
51
+ alert.classList.remove('alert-confirm')
52
+ alert.classList.remove('alert-info')
53
+ alert.classList.add('alert-' + type)
54
+ }
55
+
56
+ const closeAlert = () => {
57
+
58
+ const { alert, overlay } = createAlert()
59
+
60
+ const transitionEnd = () => {
61
+
62
+ overlay.classList.remove('on')
63
+ alert.classList.remove('on')
64
+ alert.removeEventListener('transitionend', transitionEnd)
65
+ }
66
+
67
+ alert.addEventListener('transitionend', transitionEnd)
68
+ alert.classList.remove('active')
69
+
70
+ }
71
+
72
+ const showAlert = (text, callback) => {
73
+
74
+ const { alert } = createAlert()
75
+
76
+ let { title, description } = typeof text === 'object' ? text : { title:text }
77
+
78
+ if(!title) title = 'Error'
79
+ if(!description) description = ''
80
+
81
+ const eTitle = alert.querySelector('.alert-title')
82
+ const eDesc = alert.querySelector('.alert-desc')
83
+ const foot = alert.querySelector('.alert-foot')
84
+
85
+ if(eTitle) eTitle.innerHTML = title
86
+ if(eDesc) eDesc.innerHTML = description
87
+
88
+ if(foot){
89
+ foot.innerHTML = `<button class="alert-ok">OK</button>`
90
+ }
91
+
92
+ const alertOk = () => {
93
+ closeAlert()
94
+ if(typeof callback === 'function')
95
+ callback()
96
+ }
97
+
98
+ alert.querySelectorAll(".alert-ok").forEach((el) => {
99
+ el.addEventListener('click', alertOk)
100
+ })
101
+
102
+ openAlert('error')
103
+ }
104
+
105
+ const showInfo = () => {
106
+
107
+ }
108
+
109
+ const showConfirm = (text, callback) => {
110
+
111
+ const { alert } = createAlert()
112
+
113
+ let { title, description } = typeof text === 'object' ? text : { title:text }
114
+
115
+ if(!title) title = 'Confirm'
116
+ if(!description) description = ''
117
+
118
+ const eTitle = alert.querySelector('.alert-title')
119
+ const eDesc = alert.querySelector('.alert-desc')
120
+ const foot = alert.querySelector('.alert-foot')
121
+
122
+ if(eTitle) eTitle.innerHTML = title
123
+ if(eDesc) eDesc.innerHTML = description
124
+
125
+ if(foot){
126
+ foot.innerHTML = `<button class="alert-ok">OK</button>
127
+ <button class="alert-close">Cancel</button>`
128
+ }
129
+
130
+ const alertOk = () => {
131
+ closeAlert()
132
+ if(typeof callback === 'function')
133
+ callback()
134
+ }
135
+
136
+ alert.querySelectorAll(".alert-ok").forEach((el) => {
137
+ el.addEventListener('click', alertOk)
138
+ })
139
+
140
+ alert.querySelectorAll(".alert-close").forEach((el) => {
141
+ el.addEventListener('click', closeAlert)
142
+ })
143
+
144
+ openAlert('confirm')
145
+ }
146
+
147
+ export {
148
+ showAlert,
149
+ showInfo,
150
+ showConfirm
151
+ }
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <Teleport to=".alert-overlay">
3
+ <Transition name="alert-outer" @after-leave="onAfterLeave">
4
+ <div v-if="state" :class="$style.alert" ref="alert">
5
+ <Transition name="alert" @after-leave="onAfterLeave" appear>
6
+ <slot></slot>
7
+ </Transition>
8
+ </div>
9
+ </Transition>
10
+ </Teleport>
11
+ </template>
12
+
13
+ <script>
14
+
15
+ export default{
16
+
17
+ props: {
18
+ state: [ Boolean ],
19
+ default: 0
20
+ },
21
+
22
+ methods: {
23
+
24
+ onAfterLeave(){
25
+
26
+ }
27
+
28
+ }
29
+
30
+ }
31
+
32
+ </script>
33
+
34
+ <style module>
35
+
36
+ .alert{
37
+ @apply fixed top-0 left-0 flex w-screen h-screen items-center justify-center bg-black/70 backdrop-blur-md;
38
+ }
39
+
40
+ .alert>*{
41
+ @apply w-[480px] max-w-[80vw] max-h-[50vh] overflow-y-auto bg-base-600 rounded-xl;
42
+ }
43
+
44
+ </style>
45
+
46
+
47
+ <style>
48
+
49
+ .alert-outer-enter-active,
50
+ .alert-outer-leave-active {
51
+ transition: opacity 100ms cubic-bezier(0.25, 1, 0.5, 1);
52
+ }
53
+
54
+ .alert-outer-enter-from,
55
+ .alert-outer-leave-to {
56
+ opacity: 0;
57
+ }
58
+
59
+ .alert-enter-active,
60
+ .alert-leave-active {
61
+ transition: all 300ms cubic-bezier(0.25, 1, 0.5, 1);
62
+ transform: translate3d(0, 0, 0);
63
+ }
64
+
65
+ .alert-enter-from,
66
+ .alert-leave-to {
67
+ transform: translate3d(0, 50px, 0);
68
+ opacity: 0;
69
+ }
70
+
71
+ </style>
@@ -0,0 +1,146 @@
1
+ <template>
2
+ <button :class="computedClass" :disabled="state === -1">
3
+ <slot v-if="state !== 2"></slot>
4
+ <svg v-else-if="state === 2" class="animate-spin h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
5
+ <circle :class="$style.svgBg" cx="12" cy="12" r="10" stroke-width="4"></circle>
6
+ <path :class="$style.svgHg" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
7
+ </svg>
8
+ </button>
9
+ </template>
10
+
11
+ <script>
12
+
13
+ export default{
14
+
15
+ props: {
16
+
17
+ type: {
18
+ type: [ String, Number ],
19
+ default: "primary"
20
+ },
21
+
22
+ state: {
23
+ type: [ String, Number ],
24
+ default: 1
25
+ }
26
+
27
+ },
28
+
29
+ computed:{
30
+
31
+ computedClass(){
32
+
33
+ const className = []
34
+
35
+ switch(this.type){
36
+ case 1:
37
+ case 'primary':
38
+ className.push(this.$style.primary)
39
+ break
40
+
41
+ case 2:
42
+ case 'secondary':
43
+ className.push(this.$style.secondary)
44
+ break
45
+
46
+ case 3:
47
+ case 'outline':
48
+ className.push(this.$style.outline)
49
+ break
50
+ }
51
+
52
+ switch(this.state){
53
+ case 2:
54
+ case 'loading':
55
+ className.push(this.$style.loading)
56
+ break
57
+ }
58
+
59
+ return className.join(' ')
60
+ }
61
+
62
+ }
63
+
64
+ }
65
+
66
+ </script>
67
+
68
+ <style module>
69
+
70
+ .primary{
71
+ @apply bg-primary-500 p-2 text-white rounded-md border-[2px] border-primary-500;
72
+ @apply hover:bg-primary-600 hover:border-primary-600;
73
+ @apply active:top-[1px] active:left-[1px] active:relative;
74
+ @apply disabled:opacity-50 disabled:top-0 disabled:left-0 disabled:cursor-not-allowed;
75
+ }
76
+ .primary *{
77
+ @apply text-white fill-white;
78
+ }
79
+ .primary.loading{
80
+ @apply top-0 left-0 hover:bg-primary-500 hover:border-primary-500;
81
+ }
82
+ .primary.loading *{
83
+ fill: transparent;
84
+ }
85
+ .primary .svgBg{
86
+ stroke: var(--text);
87
+ stroke-opacity: 25%;
88
+ }
89
+ .primary .svgHg{
90
+ fill: #fff;
91
+ fill-opacity: 75%;
92
+ }
93
+
94
+ .outline{
95
+ @apply flex items-center justify-center;
96
+ @apply bg-transparent p-2 text-primary-500 rounded-md border-[2px] border-primary-500;
97
+ @apply hover:border-primary-300 hover:text-primary-300;
98
+ @apply active:top-[1px] active:left-[1px] active:relative;
99
+ @apply disabled:opacity-50 disabled:top-0 disabled:left-0 disabled:cursor-not-allowed;
100
+ @apply disabled:hover:text-primary-500 disabled:hover:border-primary-500;
101
+ }
102
+ .outline *{
103
+ @apply text-primary-500 fill-primary-500;
104
+ }
105
+ .outline.loading{
106
+ @apply top-0 left-0 hover:border-primary-500 hover:text-primary-500;
107
+ }
108
+ .outline.loading *{
109
+ fill: transparent;
110
+ }
111
+ .outline .svgBg{
112
+ stroke: var(--primary);
113
+ stroke-opacity: 25%;
114
+ }
115
+ .outline .svgHg{
116
+ fill: var(--primary);
117
+ fill-opacity: 75%;
118
+ }
119
+
120
+ .secondary{
121
+ @apply flex items-center justify-center;
122
+ @apply bg-secondary-500 p-2 px-4 text-white rounded-md border-[2px] border-secondary-500;
123
+ @apply hover:bg-secondary-600 hover:border-secondary-600;
124
+ @apply active:top-[1px] active:left-[1px] active:relative;
125
+ @apply disabled:opacity-50 disabled:top-0 disabled:left-0 disabled:cursor-not-allowed;
126
+ @apply disabled:hover:bg-secondary-500 disabled:hover:border-secondary-500;
127
+ }
128
+ .secondary *{
129
+ @apply text-white fill-white;
130
+ }
131
+ .secondary.loading{
132
+ @apply top-0 left-0 hover:bg-secondary-500 hover:border-secondary-500;
133
+ }
134
+ .secondary.loading *{
135
+ fill: transparent;
136
+ }
137
+ .secondary .svgBg{
138
+ stroke: var(--text);
139
+ stroke-opacity: 25%;
140
+ }
141
+ .secondary .svgHg{
142
+ fill: #fff;
143
+ fill-opacity: 75%;
144
+ }
145
+
146
+ </style>
@@ -0,0 +1,101 @@
1
+ <template>
2
+ <div class="button-group">
3
+ <div class="flex items-center" @click="showPopup">
4
+ <div class="flex-1">
5
+ {{ text }}
6
+ </div>
7
+ <div>
8
+ <slot name="icon"></slot>
9
+ </div>
10
+ </div>
11
+ <div class="bg-popup">
12
+ <slot></slot>
13
+ </div>
14
+ </div>
15
+ </template>
16
+
17
+ <script>
18
+
19
+ export default {
20
+
21
+ name: "ButtonGroup",
22
+
23
+ props: {
24
+ text: {
25
+ type: String,
26
+ default: ""
27
+ },
28
+ anchor: {
29
+ type: String,
30
+ default: "left"
31
+ }
32
+ },
33
+
34
+ methods: {
35
+
36
+ hidePopup(){
37
+
38
+ const popup = this.$el.querySelector('.bg-popup')
39
+ const transitionEnd = () => {
40
+ popup.classList.remove('on')
41
+ popup.removeEventListener('transitionend', transitionEnd)
42
+ window.removeEventListener('click', this.hidePopup)
43
+ }
44
+
45
+ popup.addEventListener('transitionend', transitionEnd)
46
+ popup.classList.remove('active')
47
+
48
+ },
49
+
50
+ showPopup(e){
51
+
52
+ e.preventDefault()
53
+ e.stopPropagation()
54
+
55
+ const popup = this.$el.querySelector('.bg-popup')
56
+ popup.style.top = (this.$el.clientHeight + 10) + "px"
57
+ popup.style.left = this.anchor === 'left' ? 0 : ''
58
+ popup.style.right = this.anchor === 'right' ? 0 : ''
59
+ popup.classList.add('on')
60
+
61
+ window.setTimeout(() => {
62
+ popup.classList.add('active')
63
+ }, 100)
64
+
65
+ window.addEventListener('click', this.hidePopup)
66
+ }
67
+
68
+ }
69
+
70
+ }
71
+
72
+ </script>
73
+
74
+ <style>
75
+
76
+ .button-group{
77
+ position: relative;
78
+ @apply inline-block;
79
+ @apply cursor-pointer;
80
+ }
81
+
82
+ .bg-popup{
83
+ display: none;
84
+ position: absolute;
85
+ background: #fff;
86
+ }
87
+ .bg-popup.on{
88
+ display: block;
89
+ opacity: 0;
90
+ transform: translate3d(0, -10%, 0);
91
+ transition: all 200ms cubic-bezier(0.25, 1, 0.5, 1);
92
+ }
93
+ .bg-popup.active {
94
+ opacity: 1;
95
+ transform: translate3d(0, 0, 0);
96
+ }
97
+ .bg-popup button{
98
+ white-space: nowrap;
99
+ }
100
+
101
+ </style>