Compare commits
2 Commits
6984ed9ffa
...
624344672b
Author | SHA1 | Date |
---|---|---|
yutent | 624344672b | |
yutent | 9391743acc |
|
@ -1,4 +1,4 @@
|
||||||
dist
|
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
*.sublime-project
|
*.sublime-project
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"enabled": true,
|
||||||
|
"port": 8080,
|
||||||
|
"root": "./dist"
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2023/11/14 18:52:57
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { createApp } from 'wkitd'
|
||||||
|
import { css, html } from 'wkit'
|
||||||
|
|
||||||
|
import 'es.shim'
|
||||||
|
// import '//jscdn.ink/@bd/ui/latest/form/input.js'
|
||||||
|
// import '//jscdn.ink/@bd/ui/latest/form/button.js'
|
||||||
|
// import '//jscdn.ink/@bd/ui/latest/form/checkbox.js'
|
||||||
|
// import '//jscdn.ink/@bd/ui/latest/form/switch.js'
|
||||||
|
// import '//jscdn.ink/@bd/ui/latest/form/link.js'
|
||||||
|
// import '//jscdn.ink/@bd/ui/latest/layer/index.js'
|
||||||
|
// // import 'http://127.0.0.1:8090/dist/layer/index.js'
|
||||||
|
// import '//jscdn.ink/@bd/ui/latest/pager/index.js'
|
||||||
|
// import '//jscdn.ink/@bytedo/wcui/1.0.12/form/dropdown.js'
|
||||||
|
|
||||||
|
// import App from './app.vue'
|
||||||
|
|
||||||
|
import router from './router.js'
|
||||||
|
import store from './store.js'
|
||||||
|
import fetch from '/lib/fetch.js'
|
||||||
|
|
||||||
|
import './components/header.js'
|
||||||
|
import './components/footer.js'
|
||||||
|
|
||||||
|
const app = createApp({
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<wc-header></wc-header>
|
||||||
|
<div class="main-body"><router-view></router-view></div>
|
||||||
|
<wc-footer></wc-footer>
|
||||||
|
`
|
||||||
|
},
|
||||||
|
|
||||||
|
styles: css`
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.main-body {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
var user = localStorage.getItem('user')
|
||||||
|
var checked = sessionStorage.getItem('session_checked')
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
if (checked) {
|
||||||
|
return (this.$store.user = JSON.parse(user))
|
||||||
|
}
|
||||||
|
fetch('/login/check')
|
||||||
|
.then(r => {
|
||||||
|
localStorage.setItem('token', r.data.token)
|
||||||
|
sessionStorage.setItem('session_checked', 1)
|
||||||
|
this.$store.user = JSON.parse(user)
|
||||||
|
})
|
||||||
|
.catch(r => {
|
||||||
|
localStorage.removeItem('token')
|
||||||
|
localStorage.removeItem('user')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.use(router).use(store).mount('.app')
|
|
@ -0,0 +1,22 @@
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
background: var(--color-plain-3);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--color-dark-a);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--color-dark-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
line-height: 1.5;
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--color-dark-1);
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,35 @@
|
||||||
|
import { html, css, Component } from 'wkit'
|
||||||
|
|
||||||
|
class Footer extends Component {
|
||||||
|
static styles = css`
|
||||||
|
.copyright {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 128px;
|
||||||
|
background: var(--color-plain-1);
|
||||||
|
color: var(--color-grey-2);
|
||||||
|
|
||||||
|
.link {
|
||||||
|
margin-left: 6px;
|
||||||
|
color: var(--color-blue-1);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<footer class="copyright">
|
||||||
|
<span>©Copyright 2022 jscdn.ink Power by</span>
|
||||||
|
<a class="link" target="_blank" href="https://git.wkit.fun/bytedo/wkitd"
|
||||||
|
>wkitd</a
|
||||||
|
>
|
||||||
|
</footer>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Footer.reg('footer')
|
|
@ -0,0 +1,172 @@
|
||||||
|
import { html, css, Component, classMap } from 'wkit'
|
||||||
|
|
||||||
|
import fetch from '/lib/fetch.js'
|
||||||
|
|
||||||
|
class Header extends Component {
|
||||||
|
static props = {
|
||||||
|
input: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
.common-header {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 240px;
|
||||||
|
background: var(--color-red-1);
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 1024px;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navibar {
|
||||||
|
height: 36px;
|
||||||
|
margin-top: 24px;
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 26px;
|
||||||
|
|
||||||
|
& img {
|
||||||
|
display: block;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.navi {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
& router-link {
|
||||||
|
margin: 0 16px;
|
||||||
|
padding: 3px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background 0.2s ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.router-link-active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner {
|
||||||
|
width: 640px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
display: none;
|
||||||
|
width: 520px;
|
||||||
|
color: #fff;
|
||||||
|
--bg-color: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.search-show {
|
||||||
|
height: 320px;
|
||||||
|
.search {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 48px;
|
||||||
|
font-size: 16px;
|
||||||
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
content: '免费、快速、开放的 CDN 服务';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 1024px) {
|
||||||
|
.common-header {
|
||||||
|
.navibar {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 32px;
|
||||||
|
}
|
||||||
|
.wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
search() {
|
||||||
|
let id = this.input.trim()
|
||||||
|
if (id) {
|
||||||
|
fetch('/package/search/' + encodeURIComponent(id)).then(r => {
|
||||||
|
let dict = { versions: [], id }
|
||||||
|
let last = null
|
||||||
|
for (let it of r.data) {
|
||||||
|
let tmp = it.split('/')
|
||||||
|
let v = tmp.shift()
|
||||||
|
let n = tmp.join('/')
|
||||||
|
if (last === v) {
|
||||||
|
dict[last].push(n)
|
||||||
|
} else {
|
||||||
|
last = v
|
||||||
|
dict.versions.push(last)
|
||||||
|
dict[last] = [n]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$store.result = dict
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$store.result = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<div
|
||||||
|
class="common-header noselect"
|
||||||
|
:class=${classMap({ 'search-show': this.$store.searchShow })}
|
||||||
|
>
|
||||||
|
<header class="navibar">
|
||||||
|
<div class="wrapper">
|
||||||
|
<a class="logo"><img src="/assets/logo.svg" /></a>
|
||||||
|
|
||||||
|
<nav class="navi">
|
||||||
|
<router-link :to=${{ path: '/' }}>首 页</router-link>
|
||||||
|
<router-link :to=${{ path: '/request' }}>收 录</router-link>
|
||||||
|
<router-link :to=${{ path: '/about' }}>关 于</router-link>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<cite class="banner">
|
||||||
|
<p>
|
||||||
|
我们的目标是提供这样一个仓库,让它尽可能全面收录优秀的支持ESM访问的开源库,并免费为之提供
|
||||||
|
CDN加速服务,使之有更好的访问速度和稳定的环境。
|
||||||
|
</p>
|
||||||
|
<p>同时我们也提供自主提交开源库的收录(前提是在npm上发布的)</p>
|
||||||
|
</cite>
|
||||||
|
|
||||||
|
<wc-input
|
||||||
|
class="search"
|
||||||
|
no-border
|
||||||
|
placeholder="请输入开源库的名字~~"
|
||||||
|
clearable
|
||||||
|
value=${this.input}
|
||||||
|
@submit=${this.search}
|
||||||
|
></wc-input>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Header.reg('header')
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,27 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
||||||
|
<title>免费、快速、开放的 CDN 服务</title>
|
||||||
|
<meta name="keywords" content="免费、快速、开放的 CDN 服务">
|
||||||
|
<meta name="description" content="免费、快速、开放的 CDN 服务">
|
||||||
|
<link rel="stylesheet" href="//jscdn.ink/@bd/ui/latest/css/reset-basic.css">
|
||||||
|
<link rel="stylesheet" href="/assets/app.css">
|
||||||
|
<script async src="//jscdn.ink/es-module-shims/1.6.3/es-module-shims.wasm.js"></script>
|
||||||
|
<script type="importmap">{
|
||||||
|
"imports":{
|
||||||
|
"es.shim": "//jscdn.ink/es.shim/2.1.0/index.js",
|
||||||
|
"fetch": "//jscdn.ink/@bytedo/fetch/latest/next.js",
|
||||||
|
"wkit": "//jscdn.ink/wkit/latest/index.js",
|
||||||
|
"wkitd": "//jscdn.ink/wkitd/latest/index.js",
|
||||||
|
"@ui/": "/assets/lib/ui/"
|
||||||
|
}
|
||||||
|
}</script>
|
||||||
|
<script type="module" src="/app.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<wc-app></wc-app>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,81 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent.io@gmail.com)
|
||||||
|
* @date 2014-10-10 00:45:09
|
||||||
|
*
|
||||||
|
* CSS规范
|
||||||
|
*
|
||||||
|
* 不能出现大写,以连字符风格命名
|
||||||
|
*
|
||||||
|
* 样式规则的出现顺序
|
||||||
|
* 1 display float position overflow z-index 表示定位/布局的属性
|
||||||
|
* 2 width height margin padding border 表示盒子模型的属性
|
||||||
|
* 3 line-height font-size vertical-align text-align user-select outline ....排版相关的属性
|
||||||
|
* 4 color background opacity cursor ...表示装饰相关的属性
|
||||||
|
* 5 content list-style quotes ... 内容生成相关的属性
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
* {margin: 0;padding: 0;vertical-align: baseline;box-sizing: border-box;}
|
||||||
|
::before, ::after {box-sizing: border-box;}
|
||||||
|
/* HTML5 display-role reset for older browsers */
|
||||||
|
article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section,content {display: block;}
|
||||||
|
img {border: 0;display: inline-block;}
|
||||||
|
ol,ul {list-style: none;}
|
||||||
|
blockquote, q {quotes: none;}
|
||||||
|
blockquote::before, blockquote::after, q::before, q::after {content: '';content: none;}
|
||||||
|
table {border-collapse: collapse;border-spacing: 0;}
|
||||||
|
a:focus,input,textarea,button:focus,input:focus,textarea:focus {outline: none;}
|
||||||
|
::-moz-focus-inner {border: none;outline: none;}
|
||||||
|
|
||||||
|
body {font-family: 'Helvetica Neue', Arial, 'WenQuanYi Micro Hei', 'PingFang SC', 'Hiragino Sans GB', 'Segoe UI', 'Microsoft Yahei', sans-serif;-webkit-font-smoothing: antialiased;text-size-adjust: 100%;-webkit-tap-highlight-color: transparent;}
|
||||||
|
code, pre, samp {font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;white-space:pre-wrap;}
|
||||||
|
|
||||||
|
.noselect {-webkit-touch-callout: none;-webkit-user-select: none;-moz-user-select: none;user-select: none;}
|
||||||
|
.noselect img, .noselect a {-webkit-user-drag: none;}
|
||||||
|
.text-ell {overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
|
||||||
|
.text-thin {-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* primary */
|
||||||
|
--color-teal-a: rgba(72, 201, 176, 0.35);
|
||||||
|
--color-teal-1: rgb(72, 201, 176);
|
||||||
|
--color-teal-2: rgb(26, 188, 156);
|
||||||
|
--color-teal-3: rgb(22, 160, 133);
|
||||||
|
/* success */
|
||||||
|
--color-green-a: rgba(70, 221, 126, 0.35);
|
||||||
|
--color-green-1: rgb(70, 221, 126);
|
||||||
|
--color-green-2: rgb(47, 208, 105);
|
||||||
|
--color-green-3: rgb(26, 196, 88);
|
||||||
|
/* info */
|
||||||
|
--color-blue-a: rgba(100, 181, 246, 0.35);
|
||||||
|
--color-blue-1: rgb(100, 181, 246);
|
||||||
|
--color-blue-2: rgb(66, 165, 245);
|
||||||
|
--color-blue-3: rgb(33, 150, 243);
|
||||||
|
/* danger */
|
||||||
|
--color-red-a: rgba(252, 118, 97, 0.35);
|
||||||
|
--color-red-1: #fc7661;
|
||||||
|
--color-red-2: #ff5f45;
|
||||||
|
--color-red-3: #f33e22;
|
||||||
|
/* warning */
|
||||||
|
--color-orange-a: rgba(254, 174, 117, 0.35);
|
||||||
|
--color-orange-1: #feae75;
|
||||||
|
--color-orange-2: #fd964b;
|
||||||
|
--color-orange-3: #f97316;
|
||||||
|
/* default1 */
|
||||||
|
--color-plain-a: rgba(150, 204, 248, 0.35);
|
||||||
|
--color-plain-1: rgb(242, 245, 252);
|
||||||
|
--color-plain-2: rgb(232, 235, 244);
|
||||||
|
--color-plain-3: rgb(218, 225, 233);
|
||||||
|
/* default2 */
|
||||||
|
--color-grey-a: rgba(206, 214, 224, 0.35);
|
||||||
|
--color-grey-1: rgb(206, 214, 224);
|
||||||
|
--color-grey-2: rgb(164, 176, 190);
|
||||||
|
--color-grey-3: rgb(134, 144, 155);
|
||||||
|
/* inverse */
|
||||||
|
--color-dark-a: rgba(100, 116, 139, 0.35);
|
||||||
|
--color-dark-1: #64748B;
|
||||||
|
--color-dark-2: #475569;
|
||||||
|
--color-dark-3: #2c3441;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
import{html as e,css as t,Component as i}from"wkit";class l extends i{static styles=[t`:host{display:block;width:100%}fieldset{width:100%;height:1px;margin:16px 0;border:0;border-top:1px dashed var(--color-grey-1);user-select:none}fieldset legend{display:inline-flex;align-items:center;padding:0 8px;font-size:12px;text-align:center;color:var(--color-grey-2)}:host([align=left]) fieldset{padding-left:16px}:host([align=left]) fieldset legend{text-align:left}:host([align=right]) fieldset{padding-right:16px}:host([align=right]) fieldset legend{text-align:right}:host(:empty) fieldset legend{padding:0}`];render(){return e`<fieldset>
|
||||||
|
<legend><slot></slot></legend>
|
||||||
|
</fieldset> `}}l.reg("divider");
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,35 @@
|
||||||
|
import{nextTick as r,css as l,html as s,Component as a,classMap as h,outsideClick as c}from"wkit";import"../icon/index.js";const d={duration:100,custom:[{transform:"scaleY(0)",opacity:0},{transform:"scaleY(1)",opacity:1}]};class u extends a{static props={readOnly:!1,autofocus:!1,disabled:!1,clearable:!1,icon:"",placeholder:"",maxlength:{type:Number,default:null},minlength:{type:Number,default:null},value:"str!",lazy:"num!0"};#t=[];#e=-1;#i=!1;#s=0;static styles=[l`:host{position:relative;display:inline-flex;min-width:188px;height:32px;user-select:none;-moz-user-select:none;color:var(--color-dark-1);border-radius:3px;cursor:text;transition:box-shadow .15s linear}.label{flex:1;display:flex;justify-content:center;align-items:center;height:100%;font-size:14px;border:1px solid var(--wc-input-border-color, var(--color-grey-2));border-radius:inherit;background:var(--bg-color, #fff);color:inherit;cursor:inherit}.label input{flex:1;min-width:36px;width:0;height:100%;padding:0 8px;line-height:1;border:0;border-radius:inherit;font:inherit;color:inherit;background:none;outline:none;box-shadow:none;cursor:inherit}.label input::placeholder{color:var(--color-grey-1)}.label .close{--wc-icon-size: 18px;margin:0 8px 0 4px;padding:4px;border-radius:50%;color:var(--color-grey-2);cursor:pointer;transition:background .15s linear}.label .close:hover{background:var(--color-plain-1)}.label .icon{--wc-icon-size: 16px;margin:0 8px 0 4px;color:var(--color-grey-2)}.suggestion{overflow:hidden;position:absolute;z-index:1;left:0;top:calc(100% + 4px);width:100%;padding:4px 0;border-radius:4px;box-shadow:0 2px 5px rgba(0,0,0,.15);transform-origin:top}.suggestion .list{width:100%;background:#fff}.suggestion.hide{display:none}.suggestion li{overflow:hidden;width:100%;height:30px;line-height:30px;padding:0 8px;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.suggestion li:hover,.suggestion li[focus]{background:var(--color-plain-2)}:host([round]){border-radius:26px}:host([round]) .label input{padding:0 10px}:host(:focus-within){box-shadow:0 0 0 2px var(--color-plain-a)}:host([disabled]){pointer-events:none;cursor:not-allowed}:host([disabled]) .label{border-color:var(--color-grey-1);background:var(--color-plain-1);opacity:.6}:host([readonly]){cursor:default}`,l`:host([size=m]){min-width:128px;height:24px;font-size:12px}:host([size=m]) .label{height:24px;font-size:12px}:host([size=m]) .icon{--wc-icon-size: 12px}:host([size=m][circle]){width:24px;height:24px}:host([size=xl]){min-width:224px;height:36px;font-size:14px}:host([size=xl]) .label{height:36px;font-size:14px}:host([size=xl]) .icon{--wc-icon-size: 14px}:host([size=xl][circle]){width:36px;height:36px}:host([size=xxl]){min-width:288px;height:44px;font-size:14px}:host([size=xxl]) .label{height:44px;font-size:14px}:host([size=xxl]) .icon{--wc-icon-size: 14px}:host([size=xxl][circle]){width:44px;height:44px}`];renderClear(){return s`<wc-icon class="close" name="close" @click=${this.clear} />`}render(){let e=h({suggestion:!0,hide:!this.#t.length});return s`
|
||||||
|
<div class="label">
|
||||||
|
<slot name="prepend">
|
||||||
|
<wc-icon class="icon" name=${this.icon}></wc-icon>
|
||||||
|
</slot>
|
||||||
|
<input
|
||||||
|
ref="input"
|
||||||
|
@input=${this.handleInput}
|
||||||
|
@change=${this.handleChange}
|
||||||
|
@keydown=${this.handleKeyDown}
|
||||||
|
@focus=${this.handleFocus}
|
||||||
|
placeholder=${this.placeholder}
|
||||||
|
maxlength=${this.maxlength}
|
||||||
|
minlength=${this.minlength}
|
||||||
|
disabled=${this.disabled}
|
||||||
|
readonly=${this.readOnly}
|
||||||
|
autofocus=${this.autofocus}
|
||||||
|
:value=${this.value}
|
||||||
|
/>
|
||||||
|
${this.clearable&&this.value?this.renderClear():""}
|
||||||
|
<slot name="append"></slot>
|
||||||
|
<div class=${e} ref="suggestion" #animation=${d}>
|
||||||
|
<div ref="scroller" class="scroller">
|
||||||
|
<ul class="list" @click=${this.handleClickItem} ref="list">
|
||||||
|
${this.#t.map((t,i)=>s`<li
|
||||||
|
focus=${this.#e===i?!0:null}
|
||||||
|
index=${i}
|
||||||
|
>
|
||||||
|
${t.value}
|
||||||
|
</li>`)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`}handleInput(e){let{lazy:t}=this;this.value=e.currentTarget.value,!(t&&Date.now()-this.#s<t)&&(this.#s=Date.now(),this.emitFetchSuggest())}handleClickItem(e){let t=e.target.getAttribute("index");this.#e=t,this.emitSelect()}clear(){this.$refs.input.value="",this.value="",this.$emit("change"),this.$emit("input")}handleChange(){this.$emit("change")}handleKeyDown(e){let{lazy:t,minlength:i,value:o}=this;if(e.keyCode===13)return e.preventDefault(),this.#e>-1&&this.#i?this.emitSelect():t&&Date.now()-this.#s<t||(this.#s=Date.now(),i&&o.length<i)?void 0:this.$emit("submit");if(e.keyCode===38||e.keyCode===40){e.preventDefault();let n=e.keyCode===38?-1:1;this.#e+=n,this.#e<0&&(this.#e=0),this.#e>this.#t.length-1&&(this.#e=this.#t.length-1),this.$requestUpdate()}}emitSelect(){let e=this.#t[this.#e];this.value=e.value,this.$refs.suggestion.$animate(!0),this.#i=!1,this.$requestUpdate(),this.$emit("change"),this.$emit("input"),this.$emit("select",{index:this.#e,value:e})}emitFetchSuggest(){this.$emit("fetch-suggest",{value:this.value,send:e=>{this.#t=e.slice(0,10),this.#e=-1,this.$requestUpdate()}})}handleFocus(){this.#i||(this.#i=!0,this.$refs.suggestion.$animate())}mounted(){this.autofocus&&r(e=>this.$refs.input.focus()),c(this,()=>{this.#i=!1,this.$refs.suggestion.$animate(!0)})}}u.reg("input");
|
|
@ -0,0 +1,5 @@
|
||||||
|
import{css as r,html as s,Component as l,bind as i,nextTick as n}from"wkit";class c extends l{static props={type:"primary",to:"",autofocus:!1,disabled:!1,lazy:0};static styles=[r`:host{position:relative;display:inline-flex;border-radius:2px;user-select:none;-moz-user-select:none;font-size:inherit;cursor:pointer;transition:box-shadow .15s linear}:host .link{display:flex;justify-content:center;align-items:center;width:100%;padding:var(--padding, 0 2px);line-height:1;font-size:inherit;font-family:inherit;outline:none;color:inherit;cursor:inherit;text-decoration:none;transition:color .15s linear}:host .link::-moz-focus-inner{border:none}:host::after{position:absolute;bottom:-2px;left:0;width:100%;height:1px;border-bottom:1px dashed rgba(0,0,0,0);content:"";opacity:0;transition:opacity .15s linear}`,r`:host([type=primary]){color:var(--color-teal-2)}:host([type=primary])::after{border-color:var(--color-teal-1)}:host([type=primary]:not([disabled]):hover){color:var(--color-teal-1)}:host([type=primary]:not([disabled]):active){color:var(--color-teal-3)}:host([type=primary]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-teal-a)}:host([type=info]){color:var(--color-blue-2)}:host([type=info])::after{border-color:var(--color-blue-1)}:host([type=info]:not([disabled]):hover){color:var(--color-blue-1)}:host([type=info]:not([disabled]):active){color:var(--color-blue-3)}:host([type=info]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-blue-a)}:host([type=success]){color:var(--color-green-2)}:host([type=success])::after{border-color:var(--color-green-1)}:host([type=success]:not([disabled]):hover){color:var(--color-green-1)}:host([type=success]:not([disabled]):active){color:var(--color-green-3)}:host([type=success]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-green-a)}:host([type=warning]){color:var(--color-orange-2)}:host([type=warning])::after{border-color:var(--color-orange-1)}:host([type=warning]:not([disabled]):hover){color:var(--color-orange-1)}:host([type=warning]:not([disabled]):active){color:var(--color-orange-3)}:host([type=warning]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-orange-a)}:host([type=danger]){color:var(--color-red-2)}:host([type=danger])::after{border-color:var(--color-red-1)}:host([type=danger]:not([disabled]):hover){color:var(--color-red-1)}:host([type=danger]:not([disabled]):active){color:var(--color-red-3)}:host([type=danger]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-red-a)}:host([type=secondary]){color:var(--color-dark-2)}:host([type=secondary])::after{border-color:var(--color-dark-1)}:host([type=secondary]:not([disabled]):hover){color:var(--color-dark-1)}:host([type=secondary]:not([disabled]):active){color:var(--color-dark-3)}:host([type=secondary]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-dark-a)}:host([type=help]){color:var(--color-grey-2)}:host([type=help])::after{border-color:var(--color-grey-1)}:host([type=help]:not([disabled]):hover){color:var(--color-grey-1)}:host([type=help]:not([disabled]):active){color:var(--color-grey-3)}:host([type=help]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-grey-a)}`,r`:host(:not([disabled]):hover)::after,:host([underline])::after{opacity:1}:host([disabled]){cursor:not-allowed;opacity:.6}`];mounted(){this.stamp=0,this.autofocus&&n(o=>this.$refs.a.focus()),this._clickFn=i(this.$refs.a,"click",o=>{let{disabled:a,lazy:e}=this,t=Date.now();if(a){o.preventDefault(),o.stopPropagation();return}if(e>0&&t-this.stamp<e){o.preventDefault(),o.stopPropagation();return}this.stamp=t},!0)}render(){return s`
|
||||||
|
<a tabindex="0" ref="a" class="link" href=${this.to||"javascript:;"}>
|
||||||
|
<slot />
|
||||||
|
</a>
|
||||||
|
`}}c.reg("link");
|
|
@ -0,0 +1,13 @@
|
||||||
|
import{css as e,html as i,Component as s,classMap as a}from"wkit";class n extends s{static props={value:{type:Boolean,default:!1},inactiveText:"",activeText:"",inlineText:!1,disabled:!1,readonly:!1};static styles=[e`:host{display:inline-flex;align-items:center;font-size:14px;cursor:pointer}:host label{display:flex;justify-content:center;align-items:center;min-width:32px;padding:0 8px 0 2px;line-height:1;-moz-user-select:none;user-select:none;white-space:nowrap;cursor:inherit;outline:none;color:var(--color-dark-1)}:host .dot{display:flex;align-items:center;justify-content:space-between;min-width:36px;height:18px;padding:0 4px;margin-right:5px;line-height:14px;border-radius:16px;background:var(--color-plain-3);transition:box-shadow .2s ease,background .2s ease}:host .dot::before{display:block;width:14px;height:14px;border-radius:50%;background:#fff;content:""}:host .dot::after{display:flex;padding:0 2px;font-size:12px;content:attr(st);color:#fff}:host .dot.open{flex-direction:row-reverse;background:var(--color-teal-1)}`,e`:host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-plain-a)}`,e`:host([size=m]){height:24px;font-size:12px}:host([size=m]) .dot{min-width:30px;height:16px;line-height:12px}:host([size=m]) .dot::before{width:12px;height:12px}:host([size=xl]){height:36px;font-size:14px}:host([size=xl]) .dot{min-width:35px;height:18px;line-height:14px}:host([size=xl]) .dot::before{width:14px;height:14px}:host([size=xxl]){height:44px;font-size:14px}:host([size=xxl]) .dot{min-width:35px;height:18px;line-height:14px}:host([size=xxl]) .dot::before{width:14px;height:14px}`,e`:host([type=primary]) .dot.open{background:var(--color-teal-1)}:host([type=primary]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-teal-a)}:host([type=info]) .dot.open{background:var(--color-blue-1)}:host([type=info]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-blue-a)}:host([type=success]) .dot.open{background:var(--color-green-1)}:host([type=success]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-green-a)}:host([type=warning]) .dot.open{background:var(--color-orange-1)}:host([type=warning]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-orange-a)}:host([type=danger]) .dot.open{background:var(--color-red-1)}:host([type=danger]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-red-a)}`,e`:host([readonly]),:host([disabled]){cursor:not-allowed;opacity:.6}:host([readonly]){cursor:default}`];toggleCheck(t){if(this.disabled||this.readOnly)return;t.stopPropagation(),this.value=!this.value;let o={value:this.value};this.$emit("input"),this.$emit("change",o)}handleClick(t){(t.type==="click"||t.keyCode===32)&&(t.preventDefault(),this.toggleCheck(t))}mounted(){}render(){let t=a({dot:!0,open:this.value});return i` <label
|
||||||
|
tabindex=${this.disabled||this.readOnly?"none":0}
|
||||||
|
@click=${this.handleClick}
|
||||||
|
@keydown=${this.handleClick}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class=${t}
|
||||||
|
st=${this.inlineText?this.value?this.activeText:this.inactiveText:""}
|
||||||
|
></span>
|
||||||
|
<slot
|
||||||
|
>${this.inlineText?"":this.value?this.activeText:this.inactiveText}</slot
|
||||||
|
>
|
||||||
|
</label>`}}n.reg("switch");
|
|
@ -0,0 +1,8 @@
|
||||||
|
import{css as s,svg as i,html as o,Component as n}from"wkit";import r from"./svg.js";let e=r;window.EXT_SVG_DICT&&Object.assign(e,EXT_SVG_DICT);class a extends n{static props={name:{type:String,default:null,observer(t){t===""&&(this.name=null)}}};static styles=s`:host{display:inline-flex;width:var(--wc-icon-size, 32px);height:var(--wc-icon-size, 32px)}:host(:not([name])){display:none}.icon{display:block;width:100%;height:100%;color:inherit;fill:currentColor}.icon.loading{animation:load 1.5s linear infinite}.icon circle{stroke:currentColor;animation:circle 1.5s ease-in-out infinite}:host([size=s]){width:20px;height:20px}:host([size=m]){width:24px;height:24px}:host([size=l]){width:32px;height:32px}:host([size=xl]){width:36px;height:36px}:host([size=xxl]){width:44px;height:44px}@keyframes circle{0%{stroke-dasharray:0,3812px;stroke-dashoffset:0}50%{stroke-dasharray:1906px,3812px;stroke-dashoffset:-287px}100%{stroke-dasharray:1906px,3812px;stroke-dashoffset:-2393px}}@keyframes load{to{transform:rotate(360deg)}}`;render(){return o`
|
||||||
|
<svg
|
||||||
|
class="icon ${this.name==="loading"?"loading":""}"
|
||||||
|
viewBox="0 0 1024 1024"
|
||||||
|
>
|
||||||
|
${this.name==="loading"?i`<circle class="circle" cx="512" cy="512" r="384" fill="none" stroke-width="80" />`:i`<path d="${e[this.name]}" />`}
|
||||||
|
</svg>
|
||||||
|
`}}a.reg("icon");
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,30 @@
|
||||||
|
import{css as c,html as n,Component as p}from"wkit";import"../form/button.js";const r={home:a=>n`<wc-button
|
||||||
|
data-act="1"
|
||||||
|
disabled=${a}
|
||||||
|
class="item"
|
||||||
|
icon="dbl-left"
|
||||||
|
></wc-button>`,end:a=>n`<wc-button
|
||||||
|
data-act="end"
|
||||||
|
disabled=${a}
|
||||||
|
class="item"
|
||||||
|
icon="dbl-right"
|
||||||
|
></wc-button>`,prev:a=>n`<wc-button
|
||||||
|
data-act="prev"
|
||||||
|
disabled=${a}
|
||||||
|
class="item"
|
||||||
|
icon="left"
|
||||||
|
></wc-button>`,next:a=>n`<wc-button
|
||||||
|
data-act="next"
|
||||||
|
disabled=${a}
|
||||||
|
class="item"
|
||||||
|
icon="right"
|
||||||
|
></wc-button>`,curr:a=>n`<span class="curr item">${a}</span>`,info:(a,e)=>n`<span class="item">共 ${a}条, ${e}页</span>`,jump(a){return n`<section class="item jump">
|
||||||
|
<span>Go to</span>
|
||||||
|
<input ref="input" @keydown=${this.__gotoPage} maxlength="6" value=${a} />
|
||||||
|
</section>`}};function u(a,e){let i=[],o=0,s=a<3?6-a:2;if(e<2)return i.push({to:a,txt:a}),i;if(a-s>1&&e>5){let t=a-2*s;t=t<1?1:t,i.push({to:t,txt:"..."})}e-a<s&&(o=s-e+a);for(let t=a-s-o;t<a+s+1&&t<=e;t++)t>0&&i.push({to:t,txt:t});if(a+s<e){let t=a+2*s;t=t>e?e:t,i.push({to:t,txt:"..."})}return i}class h extends p{static props={layout:"str!home, prev, pages, next, end",total:{type:Number,default:0,attribute:!1,observer(e){this.totalpage=Math.ceil(e/this.pagesize)}},totalpage:{type:Number,default:1,attribute:!1,observer(e){this.page>e&&(this.page=e)}},page:{type:Number,default:1,attribute:!1,observer(e){e>this.totalpage?this.page=this.totalpage:e<1&&(this.page=1)}},pagesize:{type:Number,default:20,attribute:!1,observer(e){this.total>0&&(this.totalpage=Math.ceil(this.total/e))}}};static styles=[c`:host{display:block;line-height:1;font-size:14px;user-select:none;-moz-user-select:none;color:var(--color-dark-1)}:host .layout{display:flex;justify-content:center;align-items:center;margin:10px auto;--wc-button-icon-size: 10px;--wc-button-border-color: none;--wc-button-background: var(--color-plain-1);--wc-button-color-hover: var(--color-teal-1)}:host .item{min-width:32px;width:auto;margin:0 5px;border-radius:3px}:host .item.curr{display:inline-flex;align-items:center;justify-content:center;height:32px;background:var(--color-teal-1);color:#fff}:host .item.jump{display:flex;align-items:center}:host input{width:48px;height:24px;padding:0 4px;margin-left:4px;border:1px solid var(--color-grey-2);border-radius:3px;text-align:center;outline:none;transition:box-shadow .15s linear}:host input:focus{box-shadow:0 0 0 2px var(--color-plain-a)}`,c``];#t(e){let i=e.target;if(i.tagName==="WC-BUTTON"){let{page:o,totalpage:s}=this,t=i.dataset.act;if(i.disabled)return;switch(t){case"prev":t=o-1;break;case"next":console.log(t,o),t=o+1;break;case"end":t=s;break}if(+t===o)return;this.page=t,this.$refs.input&&(this.$refs.input.value=t),this.$emit("page-change",{data:t})}}__gotoPage(e){if(e.keyCode===13){let i=+e.target.value;i===i&&(this.page=i,this.$emit("page-change",{data:i})),e.target.value=this.page}}render(){let e=this.layout.split(",").map(t=>t.trim()),{page:i,total:o,totalpage:s}=this;return n`
|
||||||
|
<div class="layout" @click=${this.#t}>
|
||||||
|
${e.map(t=>{switch(t){case"pages":return u(i,s).map(l=>i===l.to?r.curr(i):n`<wc-button class="item" data-act="${l.to}"
|
||||||
|
>${l.txt}</wc-button
|
||||||
|
>`);case"home":return r.home(i===1);case"prev":return r.prev(i===1);case"next":return r.next(i>=s);case"end":return r.end(i>=s);case"curr":return r.curr(i);case"info":return r.info(o,s);case"jump":return r.jump.call(this,i);default:return""}})}
|
||||||
|
</div>
|
||||||
|
`}}h.reg("pager");
|
|
@ -0,0 +1,13 @@
|
||||||
|
import{css as p,html as $,bind as a,unbind as x,Component as _}from"wkit";class z extends _{static props={axis:"xy",delay:1e3,distance:1};static styles=[p`:host{position:relative;display:block}:host .container{overflow:hidden;position:relative;width:100%;height:100%;max-height:inherit}:host .wrapper{overflow:auto;scrollbar-width:none;width:100%;height:100%;max-height:inherit;scrollbar-width:0}:host .wrapper::-webkit-scrollbar{display:none}:host .content{min-width:100%;width:fit-content;height:fit-content}`,p`.is-horizontal,.is-vertical{visibility:hidden;position:absolute;display:flex;justify-content:flex-end;opacity:0;user-select:none;transition:opacity .3s linear,visibility .3s linear}.is-horizontal .thumb,.is-vertical .thumb{display:block;border-radius:5px;background:rgba(44,47,53,.25);cursor:default;transition:width .1s linear,height .1s linear}.is-horizontal .thumb:hover,.is-vertical .thumb:hover{background:rgba(44,47,53,.5)}.is-horizontal{flex-direction:column;left:0;bottom:0;width:100%;height:10px}.is-horizontal .thumb{width:0;height:6px}.is-horizontal .thumb:hover{height:10px}.is-vertical{top:0;right:0;width:10px;height:100%}.is-vertical .thumb{width:6px;height:0}.is-vertical .thumb:hover{width:10px}`,p`:host(:hover) .is-horizontal,:host(:hover) .is-vertical{visibility:visible;opacity:1}:host([axis=x]) .wrapper{overflow-y:hidden}:host([axis=x]) .is-vertical{display:none}:host([axis=y]) .wrapper{overflow-x:hidden}:host([axis=y]) .is-horizontal{display:none}:host([disabled]) .wrapper{overflow:hidden}:host([disabled]) .is-vertical,:host([disabled]) .is-horizontal{display:none}`];stamp=0;cache={xBar:0,yBar:0,thumbX:0,thumbY:0};get scrollTop(){return this.$refs.box?.scrollTop||0}set scrollTop(t){t=+t,t===t&&(this.$refs.box.scrollTop=t)}get scrollLeft(){return this.$refs.box?.scrollLeft||0}set scrollLeft(t){t=+t,t===t&&(this.$refs.box.scrollLeft=t)}get scrollHeight(){return this.$refs.box?.scrollHeight}get scrollWidth(){return this.$refs.box?.scrollWidth}__init__(t){let e=this.offsetWidth,r=this.offsetHeight,s=this.scrollWidth,l=this.scrollHeight,h=50,i=50;h=r*(r/l)>>0,i=e*(e/s)>>0,h<50&&(h=50),i<50&&(i=50),i>=e&&(i=0),h>=r&&(h=0),this.cache.yBar=h,this.cache.xBar=i,i>0?(this.$refs.x.parentNode.style.display="flex",this.$refs.x.style.width=i+"px"):this.$refs.x.parentNode.style.display="none",h>0?(this.$refs.y.parentNode.style.display="flex",this.$refs.y.style.height=h+"px"):this.$refs.y.parentNode.style.display="none"}_fetchScrollX(t){let{xBar:e}=this.cache,{scrollWidth:r,offsetWidth:s}=this;return t<0?t=0:t>s-e&&(t=s-e),this.scrollLeft=(r-s)*(t/(s-e)),this.$refs.x.style.transform=`translateX(${t}px)`,t}_fetchScrollY(t){let{yBar:e}=this.cache,{scrollHeight:r,offsetHeight:s}=this;return t<0?t=0:t>s-e&&(t=s-e),this.scrollTop=(r-s)*(t/(s-e)),this.$refs.y.style.transform=`translateY(${t}px)`,t}_fireReachEnd(t="reach-bottom"){let e=this.delay,{scrollHeight:r,offsetHeight:s}=this,l=this.scrollTop,h=Date.now();if(h-this.stamp>e){if(t==="reach-bottom"){if(s+l<r)return}else if(l>0)return;this.stamp=h,this.$emit(t)}}mounted(){let t,e,r,s,l=i=>{let{thumbY:c,thumbX:n}=this.cache;t!==void 0&&(r=this._fetchScrollX(n+i.pageX-t)),e!==void 0&&(s=this._fetchScrollY(c+i.pageY-e))},h=i=>{Math.abs(i.pageY-e)>this.distance&&this._fireReachEnd(i.pageY>e?"reach-bottom":"reach-top"),t=void 0,e=void 0,this.cache.thumbX=r||0,this.cache.thumbY=s||0,delete this._active,x(document,"mousemove",l),x(document,"mouseup",h)};a(this.$refs.box,"scroll",i=>{if(i.stopPropagation(),this._active)return;let{xBar:c,yBar:n,thumbX:m,thumbY:f}=this.cache,{axis:d,scrollHeight:y,scrollWidth:g,offsetHeight:u,offsetWidth:b,scrollTop:v,scrollLeft:w}=this;if(!(c===0&&n===0)){if((d==="y"||d==="xy")&&n){let o=~~(v/(y-u)*(u-n));o!==f&&(this.cache.thumbY=o,this.$refs.y.style.transform=`translateY(${o}px)`,Math.abs(o-f)>this.distance&&this._fireReachEnd(o>f?"reach-bottom":"reach-top"))}if((d==="x"||d==="xy")&&c){let o=~~(w/(g-b)*(b-c));o!==m&&(this.cache.thumbX=o,this.$refs.x.style.transform=`translateX(${o}px)`)}this.$emit("scroll")}}),a(this.$refs.y,"mousedown",i=>{e=i.pageY,this._active=!0,a(document,"mousemove",l),a(document,"mouseup",h)}),a(this.$refs.x,"mousedown",i=>{t=i.pageX,this._active=!0,a(document,"mousemove",l),a(document,"mouseup",h)}),this.__observer=new ResizeObserver(this.__init__.bind(this)),this.__observer.observe(this.$refs.cont)}unmounted(){this.__observer?.disconnect()}render(){return $`
|
||||||
|
<div class="container">
|
||||||
|
<div class="wrapper" ref="box">
|
||||||
|
<div class="content" ref="cont"><slot></slot></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="is-horizontal">
|
||||||
|
<span ref="x" class="thumb"></span>
|
||||||
|
</div>
|
||||||
|
<div class="is-vertical">
|
||||||
|
<span ref="y" class="thumb"></span>
|
||||||
|
</div>
|
||||||
|
`}}z.reg("scroll");
|
|
@ -0,0 +1 @@
|
||||||
|
import{css as p,html as a,Component as n}from"wkit";class t extends n{static styles=p`:host{display:block}.container{display:flex;flex-wrap:wrap;align-items:center;width:100%;padding:6px 0;gap:12px}:host([vertical]) .container{flex-direction:column}:host([justify]) .container{justify-content:space-between}:host([gap=s]) .container{padding:2px 0;gap:4px}:host([gap=m]) .container{padding:4px 0;gap:8px}:host([gap=l]) .container{padding:6px 0;gap:12px}:host([gap=xl]) .container{padding:8px 0;gap:16px}:host([gap=xxl]) .container{padding:10px 0;gap:20px}:host([gap=xxxl]) .container{padding:12px 0;gap:24px}`;render(){return a`<div class="container"><slot /></div>`}}t.reg("space");
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { createRouter, createWebHistory } from 'wkitd'
|
||||||
|
|
||||||
|
import './views/home.js'
|
||||||
|
import './views/request.js'
|
||||||
|
import './views/login.js'
|
||||||
|
import './views/about.js'
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(),
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'wc-home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/about',
|
||||||
|
name: 'wc-about'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/request',
|
||||||
|
name: 'wc-request'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
name: 'wc-login'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
export default router
|
|
@ -1,6 +1,6 @@
|
||||||
import { reactive } from 'vue'
|
import { createStore } from 'wkitd'
|
||||||
|
|
||||||
const store = reactive({
|
export default createStore({
|
||||||
user: {},
|
user: {},
|
||||||
stats: {
|
stats: {
|
||||||
0: '❌已删除',
|
0: '❌已删除',
|
||||||
|
@ -10,7 +10,3 @@ const store = reactive({
|
||||||
},
|
},
|
||||||
result: null // 搜索结果
|
result: null // 搜索结果
|
||||||
})
|
})
|
||||||
|
|
||||||
export default function (app) {
|
|
||||||
app.config.globalProperties.$store = store
|
|
||||||
}
|
|
|
@ -0,0 +1,390 @@
|
||||||
|
import { html, css, Component } from 'wkit'
|
||||||
|
|
||||||
|
class Request extends Component {
|
||||||
|
static styles = [
|
||||||
|
css`
|
||||||
|
.packages {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 16px;
|
||||||
|
|
||||||
|
.toolbar,
|
||||||
|
.list {
|
||||||
|
width: 1024px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 16px 0;
|
||||||
|
|
||||||
|
wc-input {
|
||||||
|
width: 480px;
|
||||||
|
}
|
||||||
|
wc-link {
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pager {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-form {
|
||||||
|
width: 640px;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 48px;
|
||||||
|
padding: 0 16px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: var(--color-grey-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 16px 16px 32px;
|
||||||
|
|
||||||
|
.field {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 12px;
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
margin-top: 16px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
wc-input,
|
||||||
|
.value {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
]
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<main class="packages">
|
||||||
|
<div class="toolbar">
|
||||||
|
<wc-input
|
||||||
|
v-model="filter"
|
||||||
|
placeholder="请输入开源库的名字"
|
||||||
|
@submit="search"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<wc-switch v-model="onlyShowWaited" @change="search"
|
||||||
|
>只显示待审核</wc-switch
|
||||||
|
>
|
||||||
|
<wc-link type="info" @click="openDialog">
|
||||||
|
没找到你想的库?点击申请收录
|
||||||
|
</wc-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<wc-table class="list" :thead="thead">
|
||||||
|
<wc-tr v-for="it of list" :key="it.id">
|
||||||
|
<wc-td align="center">
|
||||||
|
<router-link :to="'/?name=' + it.id">{{ it.id }}</router-link>
|
||||||
|
</wc-td>
|
||||||
|
<wc-td align="center">{{ it.author }}</wc-td>
|
||||||
|
<wc-td align="center">{{ it.latest || '-' }}</wc-td>
|
||||||
|
<wc-td align="center">{{ it.latest ? it.sync_date : '-' }}</wc-td>
|
||||||
|
<wc-td align="center">{{ $store.stats[it.stat] }}</wc-td>
|
||||||
|
<wc-td>{{ it.remark || '-' }}</wc-td>
|
||||||
|
<wc-td align="center">
|
||||||
|
<wc-link
|
||||||
|
v-if="it.stat === 2"
|
||||||
|
:disabled="loading"
|
||||||
|
@click="handlePackgae('sync', it.id)"
|
||||||
|
type="info"
|
||||||
|
>更新</wc-link
|
||||||
|
>
|
||||||
|
<wc-link
|
||||||
|
v-if="$store.user.admin && it.stat !== 2"
|
||||||
|
@click="handlePackgae('accept', it.id)"
|
||||||
|
type="info"
|
||||||
|
>通过</wc-link
|
||||||
|
>
|
||||||
|
<wc-link
|
||||||
|
v-if="$store.user.admin && it.stat !== 0"
|
||||||
|
@click="handlePackgae('reject', it.id)"
|
||||||
|
type="warning"
|
||||||
|
>拒绝</wc-link
|
||||||
|
>
|
||||||
|
<wc-link
|
||||||
|
v-if="$store.user.admin && it.stat !== 0"
|
||||||
|
@click="handlePackgae('delete', it.id)"
|
||||||
|
type="danger"
|
||||||
|
>删除</wc-link
|
||||||
|
>
|
||||||
|
</wc-td>
|
||||||
|
</wc-tr>
|
||||||
|
</wc-table>
|
||||||
|
|
||||||
|
<wc-pager
|
||||||
|
class="pager"
|
||||||
|
layout="prev,pages,next,info"
|
||||||
|
red
|
||||||
|
@page-changed="pageChanged"
|
||||||
|
:total="total"
|
||||||
|
:page="page"
|
||||||
|
/>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<wc-layer ref="form" mask mask-close>
|
||||||
|
<div class="request-form">
|
||||||
|
<header class="title">申请收录开源库</header>
|
||||||
|
<content class="content">
|
||||||
|
<section class="field">
|
||||||
|
<span class="label">开源库名称:</span>
|
||||||
|
<wc-input v-model="lib.name" @input="autoUpdateInfo" />
|
||||||
|
</section>
|
||||||
|
<section class="field">
|
||||||
|
<span class="label">作者:</span>
|
||||||
|
<span class="value">{{ lib.author }}</span>
|
||||||
|
</section>
|
||||||
|
<section class="field">
|
||||||
|
<span class="label">简介:</span>
|
||||||
|
<span class="value">{{ lib.description }}</span>
|
||||||
|
</section>
|
||||||
|
<section class="field">
|
||||||
|
<span class="label">最新版本:</span>
|
||||||
|
<span class="value">{{ lib.latest }}</span>
|
||||||
|
</section>
|
||||||
|
<section class="field center">
|
||||||
|
<wc-button
|
||||||
|
type="danger"
|
||||||
|
:disabled="disabled"
|
||||||
|
:loading="loading"
|
||||||
|
@click="submit"
|
||||||
|
>提交申请</wc-button
|
||||||
|
>
|
||||||
|
</section>
|
||||||
|
</content>
|
||||||
|
</div>
|
||||||
|
</wc-layer>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Request.reg('request')
|
||||||
|
|
||||||
|
import '//jscdn.ink/@bytedo/wcui/1.0.12/table/index.js'
|
||||||
|
import fetch from '/lib/fetch.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
content: '这是关于我们页面',
|
||||||
|
list: [],
|
||||||
|
thead: JSON.stringify([
|
||||||
|
'开源库',
|
||||||
|
'作者',
|
||||||
|
'最后同步版本',
|
||||||
|
'最后同步日期',
|
||||||
|
'收录状态',
|
||||||
|
'备注',
|
||||||
|
'操作'
|
||||||
|
]),
|
||||||
|
page: 1,
|
||||||
|
total: 0,
|
||||||
|
filter: '',
|
||||||
|
onlyShowWaited: false,
|
||||||
|
loading: false,
|
||||||
|
disabled: true,
|
||||||
|
lib: {
|
||||||
|
name: '',
|
||||||
|
author: '-',
|
||||||
|
description: '-',
|
||||||
|
latest: '-'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.searchShow = false
|
||||||
|
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchList() {
|
||||||
|
fetch('/package/list').then(r => {
|
||||||
|
this.$list = r.data.map(
|
||||||
|
it => ((it.sync_date = new Date(it.sync_date).format('Y/m/d')), it)
|
||||||
|
)
|
||||||
|
this.fetchPage()
|
||||||
|
this.total = this.$list.length
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchPage() {
|
||||||
|
let start = (this.page - 1) * 20
|
||||||
|
let end = start + 20
|
||||||
|
this.list = this.$list
|
||||||
|
.filter(it => (this.onlyShowWaited ? it.stat === 1 : true))
|
||||||
|
.slice(start, end)
|
||||||
|
},
|
||||||
|
|
||||||
|
pageChanged(ev) {
|
||||||
|
this.page = ev.data
|
||||||
|
console.log('<><><>', this.page)
|
||||||
|
this.fetchPage()
|
||||||
|
},
|
||||||
|
|
||||||
|
search() {
|
||||||
|
let filter = this.filter.trim()
|
||||||
|
let onlyShowWaited = this.onlyShowWaited
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
this.list = this.$list.filter(
|
||||||
|
it =>
|
||||||
|
it.id.indexOf(filter) > -1 &&
|
||||||
|
(onlyShowWaited ? it.stat === 1 : true)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this.list = this.$list.filter(it =>
|
||||||
|
onlyShowWaited ? it.stat === 1 : true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
this.total = this.list.length
|
||||||
|
},
|
||||||
|
|
||||||
|
openDialog() {
|
||||||
|
if (this.$store.user.id) {
|
||||||
|
this.$refs.form.show()
|
||||||
|
} else {
|
||||||
|
layer.confirm('你还没有登录, 请先登录之后, 再申请').then(_ => {
|
||||||
|
localStorage.setItem('login_callback_path', this.$route.path)
|
||||||
|
this.$router.push('/login')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
resetForm(force) {
|
||||||
|
force && (this.lib.name = '')
|
||||||
|
this.lib.author = '-'
|
||||||
|
this.lib.description = '-'
|
||||||
|
this.lib.latest = '-'
|
||||||
|
this.disabled = true
|
||||||
|
},
|
||||||
|
|
||||||
|
autoUpdateInfo() {
|
||||||
|
let name = this.lib.name.trim()
|
||||||
|
clearTimeout(this.$timer)
|
||||||
|
if (name) {
|
||||||
|
if (name.startsWith('@') && name.indexOf('/') === -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$timer = setTimeout(_ => {
|
||||||
|
this.getPackageInfo(name)
|
||||||
|
}, 800)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getPackageInfo(name) {
|
||||||
|
return fetch('https://registry.npmmirror.com/' + name)
|
||||||
|
.then(r => {
|
||||||
|
let author = r.author
|
||||||
|
? r.author.name
|
||||||
|
: r.maintainers
|
||||||
|
? r.maintainers[0].name
|
||||||
|
: 'unknow'
|
||||||
|
|
||||||
|
this.lib.author = author
|
||||||
|
this.lib.description = r.description || r.homepage
|
||||||
|
this.lib.latest = r['dist-tags'].latest
|
||||||
|
|
||||||
|
this.disabled = false
|
||||||
|
return {
|
||||||
|
author,
|
||||||
|
description: this.lib.description,
|
||||||
|
latest: r['dist-tags'].latest
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(_ => {
|
||||||
|
this.resetForm()
|
||||||
|
layer.toast(
|
||||||
|
`开源库【${name}】在npm上找不到, 请确认名称是否正确`,
|
||||||
|
'error'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadPackge(body) {
|
||||||
|
fetch('/package/upload', { method: 'post', body })
|
||||||
|
.then(r => {
|
||||||
|
layer.toast('提交成功,等待审核', 'success')
|
||||||
|
this.resetForm(true)
|
||||||
|
this.fetchList()
|
||||||
|
this.$refs.form.close()
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
layer.toast(e.msg, 'error')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
let name = this.lib.name.trim()
|
||||||
|
if (name) {
|
||||||
|
if (name.startsWith('@') && name.indexOf('/') === -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.loading = true
|
||||||
|
this.getPackageInfo(name)
|
||||||
|
.then(({ author, description, latest }) => {
|
||||||
|
//
|
||||||
|
this.uploadPackge({ name, author, description, latest })
|
||||||
|
})
|
||||||
|
|
||||||
|
.finally(_ => (this.loading = false))
|
||||||
|
} else {
|
||||||
|
layer.toast(`请填写正确的名称`, 'warning')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handlePackgae(act, id) {
|
||||||
|
if (act !== 'sync' && !this.$store.user.admin) {
|
||||||
|
return layer.alert('别闹, 老实等管理员通过~~')
|
||||||
|
}
|
||||||
|
let req
|
||||||
|
if (act === 'reject' || act === 'delete') {
|
||||||
|
req = layer.prompt('请输入理由').then(remark => {
|
||||||
|
return fetch(`/package/${act}/${encodeURIComponent(id)}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
body: { remark }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else if (act === 'accept') {
|
||||||
|
req = layer.prompt('请输入文件目录', 'dist').then(dist => {
|
||||||
|
return fetch(`/package/${act}/${encodeURIComponent(id)}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
body: { dist }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
req = fetch(`/package/${act}/${encodeURIComponent(id)}`, {
|
||||||
|
method: 'PUT'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.loading = true
|
||||||
|
req
|
||||||
|
.then(r => {
|
||||||
|
layer.toast('操作成功', 'success')
|
||||||
|
this.fetchList()
|
||||||
|
})
|
||||||
|
.catch(r => {
|
||||||
|
r && layer.toast(r.msg, 'error')
|
||||||
|
})
|
||||||
|
.finally(_ => (this.loading = false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,37 +0,0 @@
|
||||||
import { resolve } from 'path'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
devServer: {
|
|
||||||
port: 8080,
|
|
||||||
domain: '',
|
|
||||||
https: false,
|
|
||||||
ssl: {
|
|
||||||
key: '',
|
|
||||||
cert: ''
|
|
||||||
// ca: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
pages: {
|
|
||||||
// 如果多页应用, 则这里写传入多个值即可(注意不是数组格式)
|
|
||||||
// 这里的key值, 将是最终的页面的名称
|
|
||||||
index: {
|
|
||||||
// 这里的resolve可将相对路径转为绝对路径
|
|
||||||
// 如果传入的路径已经是绝对路径的, 可不需要resolve
|
|
||||||
entry: resolve('./src/main.js'),
|
|
||||||
title: '免费、快速、开放的 CDN 服务'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 以下cdn地址, 可自行修改为适合的
|
|
||||||
// 有用到其他的库, 可以手动添加,
|
|
||||||
// 也可以在页面中直接引入完整的路径, 而不必须在这里声明
|
|
||||||
imports: {
|
|
||||||
'es.shim': '//jscdn.ink/es.shim/2.1.0/index.js',
|
|
||||||
vue: '//jscdn.ink/vue/latest/vue.esm-browser.prod.js',
|
|
||||||
'vue-router': '//jscdn.ink/@bytedo/vue-router/4.1.6/vue-router.js',
|
|
||||||
// 这个库被vue-router依赖, 可以注释掉vue-router代码中的 @vue/devtools-api 的引入
|
|
||||||
// 以达到减少不必须的体积的效果
|
|
||||||
fetch: '//jscdn.ink/@bytedo/fetch/latest/next.js',
|
|
||||||
'@bd/core': '//jscdn.ink/wkit/latest/index.js',
|
|
||||||
wkit: '//jscdn.ink/wkit/latest/index.js'
|
|
||||||
}
|
|
||||||
}
|
|
18
index.html
18
index.html
|
@ -1,18 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
|
||||||
<title>{{title}}</title>
|
|
||||||
<meta name="keywords" content="{{keywords}}">
|
|
||||||
<meta name="description" content="{{description}}">
|
|
||||||
<link rel="stylesheet" href="//jscdn.ink/@bd/ui/latest/css/reset-basic.css">
|
|
||||||
<script async src="//jscdn.ink/es-module-shims/1.6.3/es-module-shims.wasm.js"></script>
|
|
||||||
<script type="importmap">{{importmap}}</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="app"></div>
|
|
||||||
<script src="main.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,11 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "jscdn.ink",
|
"name": "jscdn.ink",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {},
|
||||||
"start": "fite dev",
|
"devDependencies": {}
|
||||||
"build": "fite build"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"fite": "^1.1.6"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
70
src/app.vue
70
src/app.vue
|
@ -1,70 +0,0 @@
|
||||||
<template>
|
|
||||||
<Header :searchInput="$store.searchInput" />
|
|
||||||
<div class="main-body"><router-view /></div>
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from './components/header.vue'
|
|
||||||
import Footer from './components/footer.vue'
|
|
||||||
|
|
||||||
import fetch from '@/lib/fetch.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { Header, Footer },
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
var user = localStorage.getItem('user')
|
|
||||||
var checked = sessionStorage.getItem('session_checked')
|
|
||||||
|
|
||||||
if (user) {
|
|
||||||
if (checked) {
|
|
||||||
return (this.$store.user = JSON.parse(user))
|
|
||||||
}
|
|
||||||
fetch('/login/check')
|
|
||||||
.then(r => {
|
|
||||||
localStorage.setItem('token', r.data.token)
|
|
||||||
sessionStorage.setItem('session_checked', 1)
|
|
||||||
this.$store.user = JSON.parse(user)
|
|
||||||
})
|
|
||||||
.catch(r => {
|
|
||||||
localStorage.removeItem('token')
|
|
||||||
localStorage.removeItem('user')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
background: var(--color-plain-3);
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: var(--color-dark-a);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: var(--color-dark-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
line-height: 1.5;
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--color-dark-1);
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.app {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-body {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,29 +0,0 @@
|
||||||
<template>
|
|
||||||
<footer class="copyright">
|
|
||||||
<span>©Copyright 2022 jscdn.ink Power by</span>
|
|
||||||
<a class="link" target="_blank" href="//github.com/bytedo/vue-live">vue-live</a>
|
|
||||||
</footer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.copyright {
|
|
||||||
flex-shrink: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 128px;
|
|
||||||
background: var(--color-plain-1);
|
|
||||||
color: var(--color-grey-2);
|
|
||||||
|
|
||||||
.link {
|
|
||||||
margin-left: 6px;
|
|
||||||
color: var(--color-blue-1);
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,177 +0,0 @@
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
class="common-header noselect"
|
|
||||||
:class="{ 'search-show': $store.searchShow }"
|
|
||||||
>
|
|
||||||
<header class="navibar">
|
|
||||||
<div class="wrapper">
|
|
||||||
<a class="logo"><img src="/assets/logo.svg" /></a>
|
|
||||||
|
|
||||||
<nav class="navi">
|
|
||||||
<router-link to="/">首 页</router-link>
|
|
||||||
<router-link to="/request">收 录</router-link>
|
|
||||||
<router-link to="/about">关 于</router-link>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<cite class="banner">
|
|
||||||
<p>
|
|
||||||
我们的目标是提供这样一个仓库,让它尽可能全面收录优秀的支持ESM访问的开源库,并免费为之提供
|
|
||||||
CDN加速服务,使之有更好的访问速度和稳定的环境。
|
|
||||||
</p>
|
|
||||||
<p>同时我们也提供自主提交开源库的收录(前提是在npm上发布的)</p>
|
|
||||||
</cite>
|
|
||||||
|
|
||||||
<wc-input
|
|
||||||
class="search"
|
|
||||||
no-border
|
|
||||||
placeholder="请输入开源库的名字~~"
|
|
||||||
clearable
|
|
||||||
v-model="input"
|
|
||||||
@submit="search"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import fetch from '@/lib/fetch'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return { input: '' }
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
'$store.searchInput'(v) {
|
|
||||||
this.input = v
|
|
||||||
this.search()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
search() {
|
|
||||||
let id = this.input.trim()
|
|
||||||
if (id) {
|
|
||||||
fetch('/package/search/' + encodeURIComponent(id)).then(r => {
|
|
||||||
let dict = { versions: [], id }
|
|
||||||
let last = null
|
|
||||||
for (let it of r.data) {
|
|
||||||
let tmp = it.split('/')
|
|
||||||
let v = tmp.shift()
|
|
||||||
let n = tmp.join('/')
|
|
||||||
if (last === v) {
|
|
||||||
dict[last].push(n)
|
|
||||||
} else {
|
|
||||||
last = v
|
|
||||||
dict.versions.push(last)
|
|
||||||
dict[last] = [n]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.$store.result = dict
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.$store.result = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.common-header {
|
|
||||||
flex-shrink: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 240px;
|
|
||||||
background: var(--color-red-1);
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
display: flex;
|
|
||||||
width: 1024px;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navibar {
|
|
||||||
height: 36px;
|
|
||||||
margin-top: 24px;
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 26px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.navi {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 16px;
|
|
||||||
|
|
||||||
a {
|
|
||||||
margin: 0 16px;
|
|
||||||
padding: 3px 6px;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: background 0.2s ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.router-link-active {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner {
|
|
||||||
width: 640px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search {
|
|
||||||
display: none;
|
|
||||||
width: 520px;
|
|
||||||
color: #fff;
|
|
||||||
--bg-color: rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.search-show {
|
|
||||||
height: 320px;
|
|
||||||
.search {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 48px;
|
|
||||||
font-size: 16px;
|
|
||||||
background: rgba(0, 0, 0, 0.1);
|
|
||||||
content: '免费、快速、开放的 CDN 服务';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 1024px) {
|
|
||||||
.common-header {
|
|
||||||
.navibar {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0 32px;
|
|
||||||
}
|
|
||||||
.wrapper {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
21
src/main.js
21
src/main.js
|
@ -1,21 +0,0 @@
|
||||||
import { createApp } from 'vue'
|
|
||||||
|
|
||||||
import 'es.shim'
|
|
||||||
import '//jscdn.ink/@bd/ui/latest/form/input.js'
|
|
||||||
import '//jscdn.ink/@bd/ui/latest/form/button.js'
|
|
||||||
import '//jscdn.ink/@bd/ui/latest/form/checkbox.js'
|
|
||||||
import '//jscdn.ink/@bd/ui/latest/form/switch.js'
|
|
||||||
import '//jscdn.ink/@bd/ui/latest/form/link.js'
|
|
||||||
import '//jscdn.ink/@bd/ui/latest/layer/index.js'
|
|
||||||
// import 'http://127.0.0.1:8090/dist/layer/index.js'
|
|
||||||
import '//jscdn.ink/@bd/ui/latest/pager/index.js'
|
|
||||||
import '//jscdn.ink/@bytedo/wcui/1.0.12/form/dropdown.js'
|
|
||||||
|
|
||||||
import App from './app.vue'
|
|
||||||
|
|
||||||
import router from './router'
|
|
||||||
import store from './store'
|
|
||||||
|
|
||||||
const app = createApp(App)
|
|
||||||
|
|
||||||
app.use(router).use(store).mount('.app')
|
|
|
@ -1,30 +0,0 @@
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
|
||||||
import Home from './views/home.vue'
|
|
||||||
|
|
||||||
const router = createRouter({
|
|
||||||
history: createWebHistory(),
|
|
||||||
routes: [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
name: 'home',
|
|
||||||
component: Home
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/about',
|
|
||||||
name: 'about',
|
|
||||||
component: () => import('./views/about.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/request',
|
|
||||||
name: 'request',
|
|
||||||
component: () => import('./views/request.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/login',
|
|
||||||
name: 'login',
|
|
||||||
component: () => import('./views/login.vue')
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
export default router
|
|
Loading…
Reference in New Issue