From 48536d29e8f56fc580db5545a84f8a8a02a5311c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E5=A4=A9?= Date: Fri, 5 Feb 2021 16:38:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0UI=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/lib/code/colorful.js | 1 + src/lib/code/index.js | 6 +- src/lib/css/reset-basic.css | 108 +++--- src/lib/form/button.js | 487 +------------------------- src/lib/form/cascader.js | 13 + src/lib/form/checkbox-item.js | 312 +---------------- src/lib/form/checkbox.js | 143 +------- src/lib/form/index.js | 1 + src/lib/form/input.js | 620 +--------------------------------- src/lib/form/link.js | 13 + src/lib/form/number.js | 414 +---------------------- src/lib/form/progress.js | 164 +-------- src/lib/form/radio-item.js | 309 +---------------- src/lib/form/radio.js | 131 +------ src/lib/form/select.js | 560 +----------------------------- src/lib/form/star.js | 302 +---------------- src/lib/form/switch.js | 242 +------------ src/lib/form/textarea.js | 13 + src/lib/icon/index.js | 6 +- src/lib/layer/index.js | 6 +- src/lib/scroll/index.js | 6 +- 22 files changed, 189 insertions(+), 3670 deletions(-) create mode 100644 src/lib/code/colorful.js create mode 100644 src/lib/form/cascader.js create mode 100644 src/lib/form/index.js create mode 100644 src/lib/form/link.js create mode 100644 src/lib/form/textarea.js diff --git a/package.json b/package.json index b190519..12bb8b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "org.bytedo.epub", - "version": "1.2.0", + "version": "1.2.1", "description": "E-pub Reader", "main": "src/main.js", "scripts": { diff --git a/src/lib/code/colorful.js b/src/lib/code/colorful.js new file mode 100644 index 0000000..4cfa028 --- /dev/null +++ b/src/lib/code/colorful.js @@ -0,0 +1 @@ +const DOCTYPE_EXP=/<\!DOCTYPE html>/,TAG_START_EXP=/<([\w\-]+)([\w\W]*?)>/g,TAG_END_EXP=/<\/([\w\-]+)>/g,TAG_ATTR_EXP=/[@a-zA-Z\-.]+=(["'])[^"]+\1|[@a-zA-Z\-.]+=[a-zA-Z0-9]+|[@a-zA-Z\-.]+/g,TAG_CM_EXP=//g;export function colorHtml(t){return(t=t.replace(DOCTYPE_EXP,"[tag]<!DOCTYPE [attr]html[/attr]>[/tag]").replace(TAG_START_EXP,(t,a,r)=>(r&&(r=r.replace(TAG_ATTR_EXP,(function(t){if(~t.indexOf("=")){return`[attr]${(t=t.split("=")).shift()}[/attr]=[str]${t.join("=")}[/str]`}return`[attr]${t}[/attr]`}))),`[tag]<${a+r}>[/tag]`)).replace(TAG_END_EXP,(t,a)=>`[tag]</${a}>[/tag]`).replace(TAG_CM_EXP,'<!--$1-->')).replace(/\[(\/?)tag\]/g,(t,a)=>a?"":'').replace(/\[(\/?)attr\]/g,(t,a)=>a?"":'').replace(/\[(\/?)str\]/g,(t,a)=>a?"":'')}export function colorCss(t){return t=t.replace(/:(hover|after|active|last\-child|first\-child)/g,':$1').replace(/([\.#])([\w\-]+)/g,'$1$2').replace(/([a-zA-Z\-]+):\s?([^;\n]+);?/g,'$1: $2;').replace(/([,\{\}])/g,'$1').replace(/&/g,'&')} \ No newline at end of file diff --git a/src/lib/code/index.js b/src/lib/code/index.js index 3cec96c..2294db5 100644 --- a/src/lib/code/index.js +++ b/src/lib/code/index.js @@ -1,12 +1,12 @@ /** * * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-23 15:31:02 - * @version v1.0.0 + * @date 2021-02-05 16:32:07 + * @version v1.0.3 * */ -import"../scroll/index.js";import"../layer/index.js";import $ from"../utils.js";export default class Code extends HTMLElement{static get observedAttributes(){return["dark","lang"]}props={dark:"",lang:""};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
';var e=this.root.children[1],o=e.children[0];this.__CODE__=e.children[1],this.__LANG__=o.children[1],this.__RUN__=o.children[2].firstElementChild,this.__CP__=o.children[2].lastElementChild}get value(){return this.props.content}set value(e){this.props.content=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),e=(e=e.replace(//g,">").split("\n")).map(e=>`

${e}

`).join(""),this.__CODE__.innerHTML=e}connectedCallback(){var e=this.innerHTML||this.textContent;this.value=e.replace(/^[\r\n]|\s{2,}$/g,""),this.textContent="",this._cpFN=$.bind(this.__CP__,"click",e=>{try{navigator.clipboard.writeText(this.value),layer.toast("复制到粘贴板成功","success")}catch(e){layer.toast("复制到粘贴板失败","error")}}),this._runFN=$.bind(this.__RUN__,"click",e=>{this.dispatchEvent(new CustomEvent("run",{detail:this.value}))})}unmounted(){$.unbind(this.__CP__,"click",this._cpFN),$.unbind(this.__RUN__,"click",this._runFN)}attributeChangedCallback(e,o,r){if(null!==r&&o!==r)switch(e){case"lang":this.props.lang=r.toLowerCase(),this.__LANG__.textContent=this.props.lang;break;case"value":this.value=r,this.removeAttribute("value")}}} +import"../scroll/index.js";import"../layer/index.js";import $ from"../utils.js";import{colorHtml,colorCss}from"./colorful.js";export default class Code extends HTMLElement{static get observedAttributes(){return["dark","lang"]}props={dark:"",lang:""};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
';var o=this.root.children[1],e=o.children[0];this.__CODE__=o.children[1],this.__LANG__=e.children[1],this.__RUN__=e.children[2].firstElementChild,this.__CP__=e.children[2].lastElementChild}get value(){return this.props.content}set value(o){switch(o=o.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),this.props.content=o,this.props.lang){case"html":o=colorHtml(o);break;case"css":case"scss":case"less":o=colorCss(o);break;default:o=o.replace(//g,">")}o=o.split("\n").map(o=>`${o}`).join(""),this.__CODE__.innerHTML=o}connectedCallback(){var o=this.innerHTML||this.textContent;(o=o.trim().replace(/^[\r\n]|\s{2,}$/g,"")).startsWith("")&&o.endsWith("")&&(o=o.slice(5,-6).trim()),this.value=o,this.textContent="",this._cpFN=$.bind(this.__CP__,"click",o=>{try{navigator.clipboard.writeText(this.value),layer.toast("复制到粘贴板成功","success")}catch(o){layer.toast("复制到粘贴板失败","error")}}),this._runFN=$.bind(this.__RUN__,"click",o=>{this.dispatchEvent(new CustomEvent("run",{detail:this.value}))})}unmounted(){$.unbind(this.__CP__,"click",this._cpFN),$.unbind(this.__RUN__,"click",this._runFN)}attributeChangedCallback(o,e,r){if(e!==r)switch(o){case"lang":this.props.lang=r.toLowerCase(),this.__LANG__.textContent=this.props.lang;break;case"value":this.value=r,this.removeAttribute("value")}}} if(!customElements.get('wc-code')){ customElements.define('wc-code', Code) diff --git a/src/lib/css/reset-basic.css b/src/lib/css/reset-basic.css index 651aa7f..2f7883b 100644 --- a/src/lib/css/reset-basic.css +++ b/src/lib/css/reset-basic.css @@ -4,14 +4,9 @@ * @authors yutent (yutent.io@gmail.com) * @date 2014-10-10 00:45:09 * - * doui的CSS规范 + * CSS规范 * * 不能出现大写,以连字符风格命名 - * 表示状态的应该用do-st-*命名 - * 表示功能的应该用do-fn-*命名 - * 表示页面模块的应该用do-mod-modname 命名 - * 表示UI组件的应该用do-uiname命名, 它的子元素应该全部包在 .do-uiname这个根类下 - * 如 .do-layer .body { ... } * * 样式规则的出现顺序 * 1 display float position overflow z-index 表示定位/布局的属性 @@ -22,57 +17,66 @@ * */ - -* {margin: 0;padding: 0;vertical-align: baseline;box-sizing:border-box;} -::before,::after {box-sizing:border-box;} +* {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;} +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;} +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;} -[anot],[\:repeat],[\:if] {visibility:hidden;} +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;} +[anot],[\:repeat],[\:if] {visibility: hidden;} .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 } -.osx-thin {-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;} +.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 { - --color-teal-1: #4db6ac; - --color-teal-2: #26a69a; - --color-teal-3: #009688; - --color-green-1: #81c784; - --color-green-2: #66bb6a; - --color-green-3: #4caf50; - --color-purple-1: #9575cd; - --color-purple-2: #9575cd; - --color-purple-3: #673ab7; - --color-blue-1: #64b5f6; - --color-blue-2: #42a5f5; - --color-blue-3: #2196f3; - --color-red-1: #ff5061; - --color-red-2: #eb3b48; - --color-red-3: #ce3742; - --color-orange-1: #ffb618; - --color-orange-2: #f39c12; - --color-orange-3: #e67e22; - --color-plain-1: #f2f5fc; - --color-plain-2: #e8ebf4; - --color-plain-3: #dae1e9; - --color-grey-1: #bdbdbd; - --color-grey-2: #9e9e9e; - --color-grey-3: #757575; - --color-dark-1: #62778d; - --color-dark-2: #526273; - --color-dark-3: #425064; -} \ No newline at end of file + /* primary */ + --color-teal-a: rgba(72, 201, 176, 0.5); + --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(88, 214, 141, 0.5); + --color-green-1: rgb(88, 214, 141); + --color-green-2: rgb(46, 204, 113); + --color-green-3: rgb(39, 173, 96); + /* info */ + --color-blue-a: rgba(100, 181, 246, 0.5); + --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(255, 107, 129, 0.5); + --color-red-1: rgb(255, 107, 129); + --color-red-2: rgb(255, 71, 87); + --color-red-3: rgb(230, 52, 67); + /* warning */ + --color-orange-a: rgba(244, 211, 19, 0.5); + --color-orange-1: rgb(244, 211, 19); + --color-orange-2: rgb(241, 196, 15); + --color-orange-3: rgb(205, 167, 13); + /* default1 */ + --color-plain-a: rgba(150, 204, 248, 0.5); + --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.5); + --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(87, 96, 111, 0.5); + --color-dark-1: rgb(87, 96, 111); + --color-dark-2: rgb(52, 73, 94); + --color-dark-3: rgb(44, 62, 80); +} diff --git a/src/lib/form/button.js b/src/lib/form/button.js index 98aabd2..39bae39 100644 --- a/src/lib/form/button.js +++ b/src/lib/form/button.js @@ -1,483 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import "../icon/index.js" -import $ from "../utils.js" - -const IS_FIREFOX = !!window.sidebar - -export default class Button extends HTMLElement { - - - static get observedAttributes() { - return ["icon","autofocus","loading","disabled","lazy"] - } - - props = { - icon: '', - autofocus: '', - loading: false, - disabled: false, - lazy: 0 // 并发拦截时间, 单位毫秒 - } - - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` - -` - - - // 圆形按钮不允许文字 - if (this.hasAttribute('circle')) { - this.textContent = '' - } - - this.__BTN__ = this.root.children[1] - this.__ICO__ = this.__BTN__.children[0] - } - - get loading() { - return this.props.loading - } - - set loading(val) { - var type = typeof val - - if (val === this.props.loading) { - return - } - - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.loading = true - this.__ICO__.setAttribute('is', 'loading') - this.setAttribute('loading', '') - } else { - this.props.loading = false - this.__ICO__.setAttribute('is', this.props.icon) - this.removeAttribute('loading') - } - } - - get disabled() { - return this.props.disabled - } - - set disabled(val) { - var type = typeof val - - if (val === this.props.disabled) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.disabled = true - this.setAttribute('disabled', '') - } else { - this.props.disabled = false - this.removeAttribute('disabled') - } - } - - connectedCallback() { - this.stamp = 0 - - // 阻止事件冒泡, 避免用户自己绑定click事件不受这2个值的限制 - this._handleClick = $.bind(this.__BTN__, 'click', ev => { - var { loading, disabled, lazy } = this.props - var now = Date.now() - - if (loading || disabled) { - return ev.stopPropagation() - } - // 并发拦截 - if (lazy && now - this.stamp < lazy) { - return ev.stopPropagation() - } - this.stamp = now - }) - } - - disconnectedCallback() { - $.unbind(this.__BTN__, 'click', this._handleClick) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'icon': - this.props.icon = val - if (val) { - if (!this.props.loading) { - this.__ICO__.setAttribute('is', val) - } - } else { - this.removeAttribute('icon') - this.__ICO__.removeAttribute('is') - } - break - - case 'autofocus': - this.__BTN__.setAttribute('autofocus', '') - // 辣鸡火狐, 要触发一下focus, 才能聚焦 - if (IS_FIREFOX) { - setTimeout(_ => { - this.__BTN__.focus() - }, 10) - } - break - case 'lazy': - this.props.lazy = val >> 0 - break - - case 'loading': - case 'disabled': - this[name] = true - break - } - } -} - + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ + +import"../icon/index.js";import $ from"../utils.js";const IS_FIREFOX=!!window.sidebar;export default class Button extends HTMLElement{static get observedAttributes(){return["icon","autofocus","loading","disabled","lazy"]}props={icon:"",autofocus:"",loading:!1,disabled:!1,lazy:0};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=' ',this.hasAttribute("circle")&&(this.textContent=""),this.__BTN__=this.root.children[1],this.__ICO__=this.__BTN__.children[0]}get loading(){return this.props.loading}set loading(o){var t=typeof o;o!==this.props.loading&&("boolean"===t&&o||"boolean"!==t?(this.props.loading=!0,this.__BTN__.disabled=!0,this.__ICO__.setAttribute("is","loading"),this.setAttribute("loading","")):(this.props.loading=!1,this.__BTN__.disabled=!1,this.__ICO__.setAttribute("is",this.props.icon),this.removeAttribute("loading")))}get disabled(){return this.props.disabled}set disabled(o){var t=typeof o;o!==this.props.disabled&&("boolean"===t&&o||"boolean"!==t?(this.props.disabled=!0,this.__BTN__.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.__BTN__.disabled=!1,this.removeAttribute("disabled")))}connectedCallback(){this.stamp=0,this._handleClick=$.bind(this.__BTN__,"click",o=>{var{loading:t,disabled:i,lazy:e}=this.props,r=Date.now();return t||i||e&&r-this.stamp{this.__BTN__.focus()},10);break;case"lazy":this.props.lazy=i>>0;break;case"loading":case"disabled":this[o]=null!==i}}} if(!customElements.get('wc-button')){ customElements.define('wc-button', Button) diff --git a/src/lib/form/cascader.js b/src/lib/form/cascader.js new file mode 100644 index 0000000..3726015 --- /dev/null +++ b/src/lib/form/cascader.js @@ -0,0 +1,13 @@ +/** + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ + + + +if(!customElements.get('wc-')){ + customElements.define('wc-', ) +} diff --git a/src/lib/form/checkbox-item.js b/src/lib/form/checkbox-item.js index 2154488..7dddd84 100644 --- a/src/lib/form/checkbox-item.js +++ b/src/lib/form/checkbox-item.js @@ -1,310 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import "../icon/index.js" -import $ from "../utils.js" - -export default class CheckboxItem extends HTMLElement { - - - static get observedAttributes() { - return ["color","value","checked","readonly","disabled"] - } - - props = { - color: '', - value: '', - checked: false, - readonly: false, - disabled: false - } - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` - -` - - - this.__SWITCH__ = this.root.lastElementChild - this.__ICO__ = this.__SWITCH__.children[0] - - this._isInGroup = false - } - - _checkGroup() { - this._isInGroup = this.parentNode.tagName === 'WC-CHECKBOX' - if (this._isInGroup && this.parentNode.root) { - if (this.parentNode.value.includes(this.value)) { - this.checked = true - } - } - } - - get value() { - return this.props.value - } - - set value(val) { - this.props.value = val - } - - get checked() { - return this.props.checked - } - - set checked(val) { - this.props.checked = !!val - var { checked, color } = this.props - this.__SWITCH__.classList.toggle('checked', checked) - this.__ICO__.setAttribute('is', 'checkbox-' + (checked ? 'on' : 'off')) - - if (checked) { - this.__ICO__.setAttribute('color', color) - } else { - this.__ICO__.removeAttribute('color') - } - } - - get readOnly() { - return this.props.readonly - } - - set readOnly(val) { - var type = typeof val - - if (val === this.props.readonly) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.readonly = true - this.setAttribute('readonly', '') - } else { - this.props.readonly = false - this.removeAttribute('readonly') - } - } - - get disabled() { - return this.props.disabled - } - - set disabled(val) { - var type = typeof val - - if (val === this.props.disabled) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.disabled = true - this.setAttribute('disabled', '') - } else { - this.props.disabled = false - this.removeAttribute('disabled') - } - } - - connectedCallback() { - this._checkGroup() - - this._handlClick = $.bind(this, 'click', ev => { - ev.preventDefault() - - if (this.disabled || this.readOnly) { - return - } - - this.checked = !this.checked - - if (this._isInGroup) { - this.parentNode.dispatchEvent( - new CustomEvent('child-picked', { - detail: { value: this.value, checked: this.checked } - }) - ) - } else { - this.dispatchEvent(new CustomEvent('input')) - } - }) - } - - disconnectedCallback() { - $.unbind(this, 'click', this._handlClick) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'value': - case 'color': - this.props[name] = val - break - - case 'checked': - case 'readonly': - case 'disabled': - var k = name - if (k === 'readonly') { - k = 'readOnly' - } - this[k] = true - break - } - } -} + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ +import"../icon/index.js";import $ from"../utils.js";export default class CheckboxItem extends HTMLElement{static get observedAttributes(){return["color","value","checked","readonly","disabled"]}props={color:"",value:"",checked:!1,readonly:!1,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=' ',this.__SWITCH__=this.root.lastElementChild,this.__ICO__=this.__SWITCH__.children[0],this._isInGroup=!1}_checkGroup(){this._isInGroup="WC-CHECKBOX"===this.parentNode.tagName,this._isInGroup&&this.parentNode.root&&this.parentNode.value.includes(this.value)&&(this.checked=!0)}get value(){return this.props.value}set value(e){this.props.value=e}get checked(){return this.props.checked}set checked(e){this.props.checked=!!e;var{checked:o,color:t}=this.props;this.__SWITCH__.classList.toggle("checked",o),this.__ICO__.setAttribute("is","checkbox-"+(o?"on":"off")),o?this.__ICO__.setAttribute("color",t):this.__ICO__.removeAttribute("color")}get readOnly(){return this.props.readonly}set readOnly(e){var o=typeof e;e!==this.props.readonly&&("boolean"===o&&e||"boolean"!==o?(this.props.readonly=!0,this.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(e){var o=typeof e;e!==this.props.disabled&&("boolean"===o&&e||"boolean"!==o?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}connectedCallback(){this._checkGroup(),this._handlClick=$.bind(this,"click",e=>{e.preventDefault(),this.disabled||this.readOnly||(this.checked=!this.checked,this._isInGroup?this.parentNode.dispatchEvent(new CustomEvent("child-picked",{detail:{value:this.value,checked:this.checked}})):this.dispatchEvent(new CustomEvent("input")))})}disconnectedCallback(){$.unbind(this,"click",this._handlClick)}attributeChangedCallback(e,o,t){if(o!==t)switch(e){case"value":case"color":this.props[e]=t;break;case"checked":case"readonly":case"disabled":var r=e;"readonly"===r&&(r="readOnly"),this[r]=!0}}} if(!customElements.get('wc-checkbox-item')){ customElements.define('wc-checkbox-item', CheckboxItem) diff --git a/src/lib/form/checkbox.js b/src/lib/form/checkbox.js index 7e199e7..b24386d 100644 --- a/src/lib/form/checkbox.js +++ b/src/lib/form/checkbox.js @@ -1,141 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import $ from "../utils.js" -import "./checkbox-item.js" - -export default class Checkbox extends HTMLElement { - - - static get observedAttributes() { - return ["value"] - } - - props = { - value: [] - } - - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` - -` - - } - - _updateChildrenStat() { - Array.from(this.children).forEach(it => { - if (it.tagName === 'WC-CHECKBOX-ITEM' && it.root) { - if (this.value.includes(it.value)) { - it.checked = true - } else { - it.checked = false - } - } - }) - } - - get value() { - return this.props.value - } - - set value(val) { - if (val === this.props.value) { - return - } - this.props.value = val - this._updateChildrenStat() - } - - connectedCallback() { - this._pickedFn = $.bind(this, 'child-picked', ev => { - var tmp = [...this.props.value] - var idx = tmp.indexOf(ev.detail.value) - if (ev.detail.checked) { - if (idx < 0) { - tmp.push(ev.detail.value) - } - } else { - if (~idx) { - tmp.splice(idx, 1) - } - } - this.props.value = tmp - this.dispatchEvent(new CustomEvent('input')) - }) - } - - disconnectedCallback() { - $.unbind(this, 'child-picked', this._pickedFn) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'value': - if (val) { - this.value = val.split(/,\s*?/) - } - break - } - } -} + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ +import $ from"../utils.js";import"./checkbox-item.js";export default class Checkbox extends HTMLElement{static get observedAttributes(){return["value"]}props={value:[]};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=" "}_updateChildrenStat(){Array.from(this.children).forEach(e=>{"WC-CHECKBOX-ITEM"===e.tagName&&e.root&&(this.value.includes(e.value)?e.checked=!0:e.checked=!1)})}get value(){return this.props.value}set value(e){e!==this.props.value&&(this.props.value=e,this._updateChildrenStat())}connectedCallback(){this._pickedFn=$.bind(this,"child-picked",e=>{var t=[...this.props.value],i=t.indexOf(e.detail.value);e.detail.checked?i<0&&t.push(e.detail.value):~i&&t.splice(i,1),this.props.value=t,this.dispatchEvent(new CustomEvent("input"))})}disconnectedCallback(){$.unbind(this,"child-picked",this._pickedFn)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"value":i&&(this.value=i.split(/,\s*?/))}}} if(!customElements.get('wc-checkbox')){ customElements.define('wc-checkbox', Checkbox) diff --git a/src/lib/form/index.js b/src/lib/form/index.js new file mode 100644 index 0000000..c3a342b --- /dev/null +++ b/src/lib/form/index.js @@ -0,0 +1 @@ +import"./button.js";import"./link.js";import"./input.js";import"./textarea.js";import"./number.js";import"./radio.js";import"./checkbox.js";import"./switch.js";import"./select.js";import"./star.js"; \ No newline at end of file diff --git a/src/lib/form/input.js b/src/lib/form/input.js index 1d232c3..a1a8848 100644 --- a/src/lib/form/input.js +++ b/src/lib/form/input.js @@ -1,616 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import "../scroll/index.js" -import "../icon/index.js" -import $ from "../utils.js" - -const TYPES = ['text', 'textarea', 'password'] -const INPUTS = { - text: '', - textarea: '' -} - -export default class Input extends HTMLElement { - - - static get observedAttributes() { - return ["value","icon","type","placeholder","maxlength","minlength","autofocus","readonly","disabled"] - } - - props = { - value: '', - icon: '', - type: 'text', - placeholder: '', - maxlength: null, - minlength: null, - autofocus: false, - readonly: false, - disabled: false - } - - - state = { - mvidx: null //下拉列表光标的索引ID - } - - constructor() { - super(); - var type = this.getAttribute('type') - var input = '' - - if (type !== 'textarea') { - type = 'text' - } - - input = INPUTS[type] - - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` -
- - ${input} - - - -
- -
    -
    -
    -
    -` - - - this.props.type = type - - this.__OUTER__ = this.root.children[1] - this.__PREPEND__ = this.__OUTER__.children[0] - this.__INPUT__ = this.__OUTER__.children[1] - this.__ICO__ = this.__OUTER__.children[2] - this.__APPEND__ = this.__OUTER__.children[3] - this.__LIST__ = this.__OUTER__.children[4] - } - - get readOnly() { - return this.props.readonly - } - - set readOnly(val) { - var type = typeof val - - if (val === this.props.readonly) { - return - } - - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.readonly = true - this.setAttribute('readonly', '') - this.__INPUT__.setAttribute('readonly', '') - } else { - this.props.readonly = false - this.removeAttribute('readonly') - this.__INPUT__.removeAttribute('readonly') - } - } - - get disabled() { - return this.props.disabled - } - - set disabled(val) { - var type = typeof val - - if (val === this.props.disabled) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.disabled = true - this.setAttribute('disabled', '') - this.__INPUT__.setAttribute('disabled', '') - } else { - this.props.disabled = false - this.removeAttribute('disabled') - this.__INPUT__.removeAttribute('disabled') - } - } - - get value() { - return this.__INPUT__.value - } - - set value(val) { - this.__INPUT__.value = val - } - - get type() { - return this.__INPUT__.type - } - - set type(val) { - if (val !== 'textarea') { - this.__INPUT__.type = val - } - } - - // 移动光标选择下拉选项 - _moveSelect(ev) { - var { list } = this.props - if (list && list.length) { - ev.preventDefault() - var step = ev.keyCode === 38 ? -1 : 1 - var items = Array.from( - this.__LIST__.firstElementChild.firstElementChild.children - ) - if (this.state.mvidx === null) { - this.state.mvidx = 0 - } else { - this.state.mvidx += step - } - if (this.state.mvidx < 0) { - this.state.mvidx = 0 - } else if (this.state.mvidx > items.length - 1) { - this.state.mvidx = items.length - 1 - } - items.forEach((it, i) => { - if (i === this.state.mvidx) { - this.__LIST__.firstElementChild.scrollTop = it.offsetTop - 150 - it.setAttribute('focus', '') - } else { - it.removeAttribute('focus') - } - }) - } - } - - // 触发列表选择 - _fetchSelect(idx, ev) { - var item = this.props.list[idx] - this.value = item.value - this.dispatchEvent( - new CustomEvent('select', { - detail: item - }) - ) - this._handleChange(ev) - this.__LIST__.classList.remove('show') - this.state.mvidx = null - } - - _updateAttr() { - var { maxlength, minlength } = this.props - - if (maxlength && maxlength > 0) { - this.__INPUT__.setAttribute('maxlength', maxlength) - } else { - this.__INPUT__.removeAttribute('maxlength') - } - if (minlength && minlength > 0) { - this.__INPUT__.setAttribute('minlength', minlength) - } else { - this.__INPUT__.removeAttribute('minlength') - } - } - - connectedCallback() { - var prepend = this.__PREPEND__.assignedNodes() - var append = this.__APPEND__.assignedNodes() - var { type } = this.props - - // 相同插槽, 只允许1个 - while (prepend.length > 1) { - this.removeChild(prepend.pop()) - } - while (append.length > 1) { - this.removeChild(append.pop()) - } - - if (prepend.length && type !== 'textarea') { - this.__OUTER__.setAttribute('prepend', '') - } - if (append.length && type !== 'textarea') { - this.__OUTER__.setAttribute('append', '') - } - - this._updateAttr() - - // 键盘事件 - this._handleSubmit = $.catch(this.__INPUT__, 'keydown', ev => { - if (this.disabled || this.readOnly) { - return - } - // up: 38, down: 40 - if (ev.keyCode === 38 || ev.keyCode === 40) { - // 仅普通文本表单, 密码和多行文本框不做响应 - if (type === 'text') { - return this._moveSelect(ev) - } - } - // 回车触发submit事件 - // textarea 要按Ctrl Or Cmd键, 才会触发 - if (ev.keyCode === 13) { - // 如果是输入建议存在,则第1次回车的时候, 不触发提交 - if (type === 'text' && this.state.mvidx !== null) { - return this._fetchSelect(this.state.mvidx, ev) - } - - if ( - type === 'text' || - (type === 'textarea' && (ev.ctrlKey || ev.metaKey)) - ) { - this.dispatchEvent( - new CustomEvent('submit', { - detail: this.value - }) - ) - } - } - }) - - // 非textarea, 可做输入建议功能 - if (type === 'text') { - // 输入状态事件 - this._handleChange = $.bind(this.__INPUT__, 'input', ev => { - ev.preventDefault() - this.dispatchEvent( - new CustomEvent('fetch-suggest', { - detail: { - value: this.value, - send: list => { - this.props.list = list - this._parseSuggestion() - } - } - }) - ) - }) - - // 渲染建议列表 - this._parseSuggestion = $.bind(this.__INPUT__, 'click', ev => { - var { list } = this.props - let { x, y, width } = this.getBoundingClientRect() - if (list && list.length) { - var html = list - .map((it, i) => `
  • ${it.value}
  • `) - .join('') - this.__LIST__.firstElementChild.firstElementChild.innerHTML = html - this.__LIST__.classList.toggle('show', true) - this.__LIST__.style.cssText = `left:${x}px;top:${y + - 50}px;width:${width}px;` - } else { - this.__LIST__.classList.toggle('show', false) - } - }) - - this._inactiveFn = $.outside(this, ev => { - this.__LIST__.classList.remove('show') - }) - - // 选择建议 - this._handleSelect = $.bind(this.__LIST__, 'click', ev => { - if (ev.target.tagName === 'LI') { - this._fetchSelect(ev.target.dataset.idx, ev) - this.dispatchEvent(new CustomEvent('input')) - } - }) - } else { - this._handleWheel = $.catch(this.__INPUT__, 'wheel') - } - } - - disconnectedCallback() { - $.unbind(this.__INPUT__, 'wheel', this._handleWheel) - $.unbind(this.__INPUT__, 'keydown', this._handleSubmit) - $.unbind(this.__INPUT__, 'input', this._handleChange) - $.unbind(this.__LIST__, 'click', this._handleSelect) - $.clearOutside(this._inactiveFn) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'icon': - this.props.icon = val - if (val) { - this.__ICO__.setAttribute('is', val) - } else { - this.removeAttribute('icon') - this.__ICO__.removeAttribute('is') - } - break - - case 'autofocus': - this.__INPUT__.setAttribute('autofocus', '') - // 辣鸡火狐, 要触发一下focus, 才能聚焦 - setTimeout(_ => { - this.__INPUT__.focus() - }, 10) - - break - - case 'placeholder': - this.__INPUT__.setAttribute('placeholder', val) - break - - case 'type': - if (~TYPES.indexOf(val)) { - this.type = val - } else { - this.type = 'text' - } - break - - case 'value': - this.value = val - break - - case 'maxlength': - case 'minlength': - this.props[name] = val - this._updateAttr() - break - - case 'readonly': - case 'disabled': - var k = name - if (k === 'readonly') { - k = 'readOnly' - } - this[k] = true - break - } - } -} - + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ + +import"../scroll/index.js";import"../icon/index.js";import $ from"../utils.js";export default class Input extends HTMLElement{static get observedAttributes(){return["value","icon","placeholder","maxlength","minlength","autofocus","readonly","disabled","passwd","lazy"]}props={value:"",icon:"",placeholder:"",maxlength:null,minlength:null,autofocus:!1,readonly:!1,disabled:!1,passwd:!1,lazy:0};state={mvidx:null};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
      ',this.__OUTER__=this.root.children[1],this.__PREPEND__=this.__OUTER__.children[0],this.__INPUT__=this.__OUTER__.children[1],this.__ICO__=this.__OUTER__.children[2],this.__APPEND__=this.__OUTER__.children[3],this.__LIST__=this.__OUTER__.children[4]}get readOnly(){return this.props.readonly}set readOnly(e){var t=typeof e;e!==this.props.readonly&&("boolean"===t&&e||"boolean"!==t?(this.props.readonly=!0,this.setAttribute("readonly",""),this.__INPUT__.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly"),this.__INPUT__.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&("boolean"===t&&e||"boolean"!==t?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__INPUT__.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled"),this.__INPUT__.removeAttribute("disabled")))}get value(){return this.__INPUT__.value}set value(e){this.__INPUT__.value=e}_moveSelect(e){var{list:t}=this.props;if(t&&t.length){e.preventDefault();var s=38===e.keyCode?-1:1,i=Array.from(this.__LIST__.firstElementChild.firstElementChild.children);null===this.state.mvidx?this.state.mvidx=0:this.state.mvidx+=s,this.state.mvidx<0?this.state.mvidx=0:this.state.mvidx>i.length-1&&(this.state.mvidx=i.length-1),i.forEach((e,t)=>{t===this.state.mvidx?(this.__LIST__.firstElementChild.scrollTop=e.offsetTop-150,e.setAttribute("focus","")):e.removeAttribute("focus")})}}_fetchSelect(e,t){var s=this.props.list[e];this.value=s.value,this.dispatchEvent(new CustomEvent("select",{detail:s})),this._handleChange(t),this.__LIST__.classList.remove("show"),this.state.mvidx=null}connectedCallback(){var e=this.__PREPEND__.assignedNodes(),t=this.__APPEND__.assignedNodes();for(this.stamp=0;e.length>1;)this.removeChild(e.pop());for(;t.length>1;)this.removeChild(t.pop());e.length&&this.__OUTER__.setAttribute("prepend",""),t.length&&this.__OUTER__.setAttribute("append",""),this._handleSubmit=$.catch(this.__INPUT__,"keydown",e=>{let{passwd:t}=this.props;if(!this.disabled&&!this.readOnly){if((38===e.keyCode||40===e.keyCode)&&!t)return this._moveSelect(e);if(13===e.keyCode){if(null!==this.state.mvidx)return this._fetchSelect(this.state.mvidx,e);this.dispatchEvent(new CustomEvent("submit",{detail:this.value}))}}}),this._handleChange=$.bind(this.__INPUT__,"input",e=>{let t=Date.now(),{lazy:s}=this.props;s&&t-this.stamp{this.props.list=e,this._parseSuggestion()}}})))}),this._parseSuggestion=$.bind(this.__INPUT__,"click",e=>{var{list:t}=this.props;let{x:s,y:i,width:o}=this.getBoundingClientRect();if(t&&t.length){var r=t.map((e,t)=>`
    • ${e.value}
    • `).join("");this.__LIST__.firstElementChild.firstElementChild.innerHTML=r,this.__LIST__.classList.toggle("show",!0),this.__LIST__.style.cssText=`left:${s}px;top:${i+50}px;width:${o}px;`}else this.__LIST__.classList.toggle("show",!1)}),this._inactiveFn=$.outside(this,e=>{this.__LIST__.classList.remove("show")}),this._handleSelect=$.bind(this.__LIST__,"click",e=>{"LI"===e.target.tagName&&(this._fetchSelect(e.target.dataset.idx,e),this.dispatchEvent(new CustomEvent("input")))})}disconnectedCallback(){$.unbind(this.__INPUT__,"keydown",this._handleSubmit),$.unbind(this.__INPUT__,"input",this._handleChange),$.unbind(this.__LIST__,"click",this._handleSelect),$.clearOutside(this._inactiveFn)}attributeChangedCallback(e,t,s){if(t!==s)switch(e){case"icon":this.props.icon=s,s?this.__ICO__.setAttribute("is",s):(this.removeAttribute("icon"),this.__ICO__.removeAttribute("is"));break;case"autofocus":this.__INPUT__.setAttribute("autofocus",""),setTimeout(e=>{this.__INPUT__.focus()},10);break;case"placeholder":this.__INPUT__.setAttribute("placeholder",s);break;case"value":this.value=s;break;case"maxlength":case"minlength":if(null===s)this.__INPUT__.removeAttribute(e);else{+s>0&&this.__INPUT__.setAttribute(e,+s)}break;case"lazy":this.props.lazy=s>>0;break;case"readonly":case"disabled":var i=e;"readonly"===i&&(i="readOnly"),this[i]=null!==s;break;case"passwd":null===s?(this.props.passwd=!1,this.__INPUT__.type="text"):(this.props.passwd=!0,this.__INPUT__.type="password")}}} if(!customElements.get('wc-input')){ customElements.define('wc-input', Input) diff --git a/src/lib/form/link.js b/src/lib/form/link.js new file mode 100644 index 0000000..3231e7f --- /dev/null +++ b/src/lib/form/link.js @@ -0,0 +1,13 @@ +/** + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ + +import"../icon/index.js";import $ from"../utils.js";const IS_FIREFOX=!!window.sidebar;export default class Link extends HTMLElement{static get observedAttributes(){return["to","autofocus","disabled","lazy"]}props={to:null,autofocus:"",disabled:!1,lazy:0};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=' ',this.__LINK__=this.root.children[1]}get disabled(){return this.props.disabled}set disabled(o){var e=typeof o;o!==this.props.disabled&&("boolean"===e&&o||"boolean"!==e?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__LINK__.removeAttribute("tabindex")):(this.props.disabled=!1,this.removeAttribute("disabled"),this.__LINK__.setAttribute("tabindex",0)))}connectedCallback(){this.stamp=0,this._handleClick=$.bind(this.__LINK__,"click",o=>{var{disabled:e,lazy:t}=this.props,r=Date.now();return e?(o.stopPropagation(),void o.preventDefault()):t&&r-this.stamp{this.__LINK__.focus()},10);break;case"to":null===t?this.__LINK__.removeAttribute("href"):this.__LINK__.setAttribute("href",t);break;case"lazy":this.props.lazy=t>>0;break;case"disabled":this[o]=null!==t}}} + +if(!customElements.get('wc-link')){ + customElements.define('wc-link', Link) +} diff --git a/src/lib/form/number.js b/src/lib/form/number.js index e6cc97a..06e8cc5 100644 --- a/src/lib/form/number.js +++ b/src/lib/form/number.js @@ -1,412 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import "../scroll/index.js" -import "../icon/index.js" -import $ from "../utils.js" - -export default class Number extends HTMLElement { - - - static get observedAttributes() { - return ["value","max","min","step","autofocus","readonly","disabled"] - } - - props = { - value: 0, - max: null, - min: null, - step: 1, - autofocus: false, - readonly: false, - disabled: false - } - - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` -
      - - - - - + - -
      -` - - - this.__OUTER__ = this.root.children[1] - this.__INPUT__ = this.__OUTER__.children[1] - } - - get readOnly() { - return this.props.readonly - } - - set readOnly(val) { - var type = typeof val - - if (val === this.props.readonly) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.readonly = true - this.setAttribute('readonly', '') - this.__INPUT__.setAttribute('readonly', '') - } else { - this.props.readonly = false - this.removeAttribute('readonly') - this.__INPUT__.removeAttribute('readonly') - } - } - - get disabled() { - return this.props.disabled - } - - set disabled(val) { - var type = typeof val - - if (val === this.props.disabled) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.disabled = true - this.setAttribute('disabled', '') - this.__INPUT__.setAttribute('disabled', '') - } else { - this.props.disabled = false - this.removeAttribute('disabled') - this.__INPUT__.removeAttribute('disabled') - } - } - - get value() { - return this.props.value - } - - set value(val) { - var n = +val - if (n === n) { - val = n - } else { - val = 0 - } - this.props.value = val - this.__INPUT__.value = val - - this._checkActionEnable() - } - - _checkActionEnable() { - var { max, min, value } = this.props - var n = value - - if (min !== null) { - if (min > n) { - n = min - } - this.__OUTER__.children[0].classList.toggle('disabled', value <= min) - } - if (max !== null) { - if (max < n) { - n = max - } - this.__OUTER__.children[2].classList.toggle('disabled', value >= max) - } - if (n !== value) { - this.props.value = n - this.__INPUT__.value = n - this.dispatchEvent(new CustomEvent('input')) - } - } - - _updateValue(act) { - var { max, min, value, step } = this.props - if (act === '+') { - if (max !== null && max < value + step) { - return - } - value += step - } else { - if (min !== null && min > value - step) { - return - } - value -= step - } - this.props.value = +value.toFixed(2) - this.__INPUT__.value = this.props.value - this._checkActionEnable() - this.dispatchEvent(new CustomEvent('input')) - } - - connectedCallback() { - // 键盘事件 - this._handleSubmit = $.catch(this.__INPUT__, 'keydown', ev => { - if (this.disabled || this.readOnly) { - return - } - - // up: 38, down: 40 - if (ev.keyCode === 38 || ev.keyCode === 40) { - ev.preventDefault() - return this._updateValue(ev.keyCode === 38 ? '+' : '-') - } - // 回车触发submit事件 - if (ev.keyCode === 13) { - ev.preventDefault() - this.dispatchEvent( - new CustomEvent('submit', { - detail: this.value - }) - ) - } - }) - - this._handleChange = $.catch(this.__INPUT__, 'change', ev => { - if (isFinite(this.__INPUT__.value)) { - this.props.value = +this.__INPUT__.value - if (!this.__INPUT__.value.endsWith('.')) { - this.__INPUT__.value = this.props.value - } - } else { - this.__INPUT__.value = this.props.value = 0 - } - this.dispatchEvent(new CustomEvent('input')) - }) - - this._handleAction = $.bind(this.__OUTER__, 'click', ev => { - if (this.disabled || this.readOnly) { - return - } - var target = ev.target - - if (target.tagName === 'SPAN' || target.parentNode === 'SPAN') { - var act = target.dataset.act || target.parentNode.dataset.act - - this._updateValue(act) - } - }) - } - - disconnectedCallback() { - $.unbind(this.__INPUT__, 'keydown', this._handleSubmit) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'autofocus': - this.__INPUT__.setAttribute('autofocus', '') - // 辣鸡火狐, 要触发一下focus, 才能聚焦 - setTimeout(_ => { - this.__INPUT__.focus() - }, 10) - break - - case 'value': - this.value = val >> 0 - break - - case 'step': - case 'max': - case 'min': - var n = +val - if (n === n) { - this.props[name] = n - } - this._checkActionEnable() - break - - case 'readonly': - case 'disabled': - var k = name - if (k === 'readonly') { - k = 'readOnly' - } - this[k] = true - break - } - } -} + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ +import"../scroll/index.js";import"../icon/index.js";import $ from"../utils.js";export default class Number extends HTMLElement{static get observedAttributes(){return["value","max","min","step","autofocus","readonly","disabled"]}props={value:0,max:null,min:null,step:1,autofocus:!1,readonly:!1,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
      - \x3c!-- --\x3e + \x3c!-- --\x3e
      ',this.__OUTER__=this.root.children[1],this.__INPUT__=this.__OUTER__.children[1]}get readOnly(){return this.props.readonly}set readOnly(e){var t=typeof e;e!==this.props.readonly&&("boolean"===t&&e||"boolean"!==t?(this.props.readonly=!0,this.setAttribute("readonly",""),this.__INPUT__.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly"),this.__INPUT__.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&("boolean"===t&&e||"boolean"!==t?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__INPUT__.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled"),this.__INPUT__.removeAttribute("disabled")))}get value(){return this.props.value}set value(e){var t=+e;e=t==t?t:0,this.props.value=e,this.__INPUT__.value=e,this._checkActionEnable()}_checkActionEnable(){var{max:e,min:t,value:s}=this.props,i=s;null!==t&&(t>i&&(i=t),this.__OUTER__.children[0].classList.toggle("disabled",s<=t)),null!==e&&(e=e)),i!==s&&(this.props.value=i,this.__INPUT__.value=i,this.dispatchEvent(new CustomEvent("input")))}_updateValue(e){var{max:t,min:s,value:i,step:a}=this.props;if("+"===e){if(null!==t&&ti-a)return;i-=a}this.props.value=+i.toFixed(2),this.__INPUT__.value=this.props.value,this._checkActionEnable(),this.dispatchEvent(new CustomEvent("input"))}connectedCallback(){this._handleSubmit=$.catch(this.__INPUT__,"keydown",e=>{if(!this.disabled&&!this.readOnly)return 38===e.keyCode||40===e.keyCode?(e.preventDefault(),this._updateValue(38===e.keyCode?"+":"-")):void(13===e.keyCode&&(e.preventDefault(),this.dispatchEvent(new CustomEvent("submit",{detail:this.value}))))}),this._handleChange=$.catch(this.__INPUT__,"change",e=>{isFinite(this.__INPUT__.value)?(this.props.value=+this.__INPUT__.value,this.__INPUT__.value.endsWith(".")||(this.__INPUT__.value=this.props.value)):this.__INPUT__.value=this.props.value=0,this.dispatchEvent(new CustomEvent("input"))}),this._handleAction=$.bind(this.__OUTER__,"click",e=>{if(!this.disabled&&!this.readOnly){var t=e.target;if("SPAN"===t.tagName||"SPAN"===t.parentNode){var s=t.dataset.act||t.parentNode.dataset.act;this._updateValue(s)}}})}disconnectedCallback(){$.unbind(this.__INPUT__,"keydown",this._handleSubmit)}attributeChangedCallback(e,t,s){if(t!==s)switch(e){case"autofocus":this.__INPUT__.setAttribute("autofocus",""),setTimeout(e=>{this.__INPUT__.focus()},10);break;case"value":this.value=s>>0;break;case"step":case"max":case"min":var i=+s;i==i&&(this.props[e]=i),this._checkActionEnable();break;case"readonly":case"disabled":var a=e;"readonly"===a&&(a="readOnly"),this[a]=!0}}} if(!customElements.get('wc-number')){ customElements.define('wc-number', Number) diff --git a/src/lib/form/progress.js b/src/lib/form/progress.js index 7e8128a..7b5a9cc 100644 --- a/src/lib/form/progress.js +++ b/src/lib/form/progress.js @@ -1,162 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -export default class Progress extends HTMLElement { - - - static get observedAttributes() { - return ["value","max"] - } - - props = { - value: 0, - max: 1 - } - - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` - -` - - this.__THUMB__ = this.root.children[1].lastElementChild - } - - get value() { - return this.props.value - } - - set value(val) { - this.props.value = +val - this.calculate() - } - - calculate() { - var { max, value } = this.props - this.__THUMB__.style.width = `${(100 * value) / max}%` - } - - connectedCallback() { - this.calculate() - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'max': - var max = +val - if (max !== max || max < 1) { - max = 1 - } - this.props.max = max - this.calculate() - break - - case 'value': - var v = +val - if (v === v) { - this.props.value = v - this.calculate() - } - break - } - } -} + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ +export default class Progress extends HTMLElement{static get observedAttributes(){return["value","max"]}props={value:0,max:1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=" ",this.__THUMB__=this.root.children[1].lastElementChild}get value(){return this.props.value}set value(e){this.props.value=+e,this.calculate()}calculate(){var{max:e,value:a}=this.props;this.__THUMB__.style.width=100*a/e+"%"}connectedCallback(){this.calculate()}attributeChangedCallback(e,a,l){if(a!==l)switch(e){case"max":var r=+l;(r!=r||r<1)&&(r=1),this.props.max=r,this.calculate();break;case"value":var t=+l;t==t&&(this.props.value=t,this.calculate())}}} if(!customElements.get('wc-progress')){ customElements.define('wc-progress', Progress) diff --git a/src/lib/form/radio-item.js b/src/lib/form/radio-item.js index af33309..5672316 100644 --- a/src/lib/form/radio-item.js +++ b/src/lib/form/radio-item.js @@ -1,307 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import $ from "../utils.js" - -export default class RadioItem extends HTMLElement { - - - static get observedAttributes() { - return ["value","checked","readonly","disabled"] - } - - props = { - value: '', - checked: false, - readonly: false, - disabled: false - } - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` - -` - - - this.__SWITCH__ = this.root.lastElementChild - } - - get value() { - return this.props.value - } - - set value(val) { - this.props.value = val - } - - get checked() { - return this.props.checked - } - - set checked(val) { - this.props.checked = !!val - this.__SWITCH__.classList.toggle('checked', this.props.checked) - } - - get readOnly() { - return this.props.readonly - } - - set readOnly(val) { - var type = typeof val - - if (val === this.props.readonly) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.readonly = true - this.setAttribute('readonly', '') - } else { - this.props.readonly = false - this.removeAttribute('readonly') - } - } - - get disabled() { - return this.props.disabled - } - - set disabled(val) { - var type = typeof val - - if (val === this.props.disabled) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.disabled = true - this.setAttribute('disabled', '') - } else { - this.props.disabled = false - this.removeAttribute('disabled') - } - } - - connectedCallback() { - if (this.value === this.parentNode.value) { - this.checked = true - } - - this._handleClick = $.catch(this, 'click', ev => { - if (this.disabled || this.readOnly || this.checked) { - return - } - - this.parentNode.dispatchEvent( - new CustomEvent('child-picked', { detail: this.value }) - ) - }) - } - - disconnectedCallback() { - $.unbind(this, 'click', this._handleClick) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'value': - this.value = val - break - - case 'checked': - case 'readonly': - case 'disabled': - var k = name - if (k === 'readonly') { - k = 'readOnly' - } - this[k] = true - break - } - } -} + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ +import $ from"../utils.js";export default class RadioItem extends HTMLElement{static get observedAttributes(){return["value","checked","readonly","disabled"]}props={value:"",checked:!1,readonly:!1,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=' ',this.__SWITCH__=this.root.lastElementChild}get value(){return this.props.value}set value(e){this.props.value=e}get checked(){return this.props.checked}set checked(e){this.props.checked=!!e,this.__SWITCH__.classList.toggle("checked",this.props.checked)}get readOnly(){return this.props.readonly}set readOnly(e){var o=typeof e;e!==this.props.readonly&&("boolean"===o&&e||"boolean"!==o?(this.props.readonly=!0,this.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(e){var o=typeof e;e!==this.props.disabled&&("boolean"===o&&e||"boolean"!==o?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}connectedCallback(){this.value===this.parentNode.value&&(this.checked=!0),this._handleClick=$.catch(this,"click",e=>{this.disabled||this.readOnly||this.checked||this.parentNode.dispatchEvent(new CustomEvent("child-picked",{detail:this.value}))})}disconnectedCallback(){$.unbind(this,"click",this._handleClick)}attributeChangedCallback(e,o,t){if(o!==t)switch(e){case"value":this.value=t;break;case"checked":case"readonly":case"disabled":var r=e;"readonly"===r&&(r="readOnly"),this[r]=!0}}} if(!customElements.get('wc-radio-item')){ customElements.define('wc-radio-item', RadioItem) diff --git a/src/lib/form/radio.js b/src/lib/form/radio.js index b541f48..61fd927 100644 --- a/src/lib/form/radio.js +++ b/src/lib/form/radio.js @@ -1,129 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import $ from "../utils.js" -import "./radio-item.js" - -export default class Radio extends HTMLElement { - - - static get observedAttributes() { - return ["value"] - } - - props = { - value: null - } - - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` - -` - - } - - _updateChildrenStat() { - Array.from(this.children).forEach(it => { - if (it.tagName === 'WC-RADIO-ITEM' && it.root) { - if (it.value === this.props.value) { - it.checked = true - } else { - it.checked = false - } - } - }) - } - - get value() { - return this.props.value - } - - set value(val) { - if (val === this.props.value) { - return - } - this.props.value = val - this._updateChildrenStat() - } - - connectedCallback() { - this._pickedFn = $.bind(this, 'child-picked', ev => { - log('radio picked: ', ev.detail) - this.value = ev.detail - this.dispatchEvent(new CustomEvent('input')) - }) - } - - disconnectedCallback() { - $.unbind(this, 'child-picked', this._pickedFn) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'value': - this.value = val - break - } - } -} + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ +import $ from"../utils.js";import"./radio-item.js";export default class Radio extends HTMLElement{static get observedAttributes(){return["value"]}props={value:null};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=" "}_updateChildrenStat(){Array.from(this.children).forEach(e=>{"WC-RADIO-ITEM"===e.tagName&&e.root&&(e.value===this.props.value?e.checked=!0:e.checked=!1)})}get value(){return this.props.value}set value(e){e!==this.props.value&&(this.props.value=e,this._updateChildrenStat())}connectedCallback(){this._pickedFn=$.bind(this,"child-picked",e=>{log("radio picked: ",e.detail),this.value=e.detail,this.dispatchEvent(new CustomEvent("input"))})}disconnectedCallback(){$.unbind(this,"child-picked",this._pickedFn)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"value":this.value=i}}} if(!customElements.get('wc-radio')){ customElements.define('wc-radio', Radio) diff --git a/src/lib/form/select.js b/src/lib/form/select.js index c411c33..0255365 100644 --- a/src/lib/form/select.js +++ b/src/lib/form/select.js @@ -1,558 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import "../scroll/index.js" -import "../icon/index.js" -import $ from "../utils.js" - -function parseOptions(arr, props) { - let html = '' - for (let it of arr) { - if (it.list) { - html += `
      ${it.name}
      ` - for (let _ of it.list) { - props.DICT[_.value] = _ - if (!_.disabled) { - props.LIST.push(_) - } - html += `
      ${_.label}
      ` - } - } else { - if (!it.disabled) { - props.LIST.push(it) - } - props.DICT[it.value] = it - html += `
      ${it.label}
      ` - } - } - return html -} - -export default class Select extends HTMLElement { - - - static get observedAttributes() { - return ["label","placeholder","multi","value","options","mvidx","readonly","disabled"] - } - - props = { - label: '', - placeholder: '', - multi: '', - value: '', - options: '', - mvidx: null, //下拉列表光标的索引ID - readonly: false, - disabled: false - } - - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` -
      - - - - -
      - -
      -
      -
      -
      -` - - - this.__OUTER__ = this.root.children[1] - this.__PREPEND__ = this.__OUTER__.children[0] - this.__INPUT__ = this.__OUTER__.children[1] - this.__APPEND__ = this.__OUTER__.children[3] - this.__OPTG__ = this.__OUTER__.children[4] - } - - get readOnly() { - return this.props.readonly - } - - set readOnly(val) { - var type = typeof val - - if (val === this.props.readonly) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.readonly = true - this.setAttribute('readonly', '') - } else { - this.props.readonly = false - this.removeAttribute('readonly') - } - } - - get disabled() { - return this.props.disabled - } - - set disabled(val) { - var type = typeof val - - if (val === this.props.disabled) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.disabled = true - this.setAttribute('disabled', '') - this.__INPUT__.setAttribute('disabled', '') - } else { - this.props.disabled = false - this.removeAttribute('disabled') - this.__INPUT__.removeAttribute('disabled') - } - } - - get value() { - return this.props.value - } - - set value(val) { - var { DICT, active } = this.props - this.props.value = val - this.__INPUT__.value = (DICT && DICT[val] && DICT[val].label) || val - if (!active) { - this._updateStyle() - } - } - - _renderOptions(options) { - this.props.DICT = {} - this.props.LIST = [] - var elem = this.__OPTG__.firstElementChild.firstElementChild - - elem.innerHTML = parseOptions(options, this.props) - this.props.ITEMS = Array.from(elem.children).filter(it => { - return it.tagName === 'DD' && !it.hasAttribute('disabled') - }) - this.value = this.props.value - } - - // 移动光标选择下拉选项 - _moveSelect(ev) { - var { LIST, DICT, ITEMS } = this.props - if (LIST && LIST.length) { - ev.preventDefault() - var step = ev.keyCode === 38 ? -1 : 1 - - if (this.props.mvidx === null) { - this.props.mvidx = 0 - } else { - this.props.mvidx += step - } - if (this.props.mvidx < 0) { - this.props.mvidx = 0 - } else if (this.props.mvidx > ITEMS.length - 1) { - this.props.mvidx = ITEMS.length - 1 - } - - ITEMS.forEach((it, i) => { - if (i === this.props.mvidx) { - this.__OPTG__.firstElementChild.scrollTop = it.offsetTop - 150 - it.setAttribute('focus', '') - } else { - it.removeAttribute('focus') - } - }) - } - } - - _updateStyle(idx) { - var { LIST, ITEMS, value } = this.props - if (LIST && LIST.length) { - if (idx === undefined) { - for (let i = -1, it; (it = LIST[++i]); ) { - if (value === it.value) { - idx = i - break - } - } - } - this.props.mvidx = idx - ITEMS.forEach((it, i) => { - if (i === idx) { - it.setAttribute('focus', '') - } else { - it.removeAttribute('focus') - } - }) - } - } - - // 触发列表选择 - _fetchSelect(idx, needUpdateStyle) { - var item = this.props.LIST[idx] - this.value = item.value - this.dispatchEvent( - new CustomEvent('select', { - detail: item - }) - ) - if (needUpdateStyle) { - this._updateStyle(idx) - } - this.props.active = false - this.__OPTG__.classList.remove('show') - } - - connectedCallback() { - var prepend = this.__PREPEND__.assignedNodes() - var append = this.__APPEND__.assignedNodes() - - // 相同插槽, 只允许1个 - while (prepend.length > 1) { - this.removeChild(prepend.pop()) - } - while (append.length > 1) { - this.removeChild(append.pop()) - } - - if (prepend.length && this.props.type !== 'textarea') { - this.__OUTER__.setAttribute('prepend', '') - } - if (append.length && this.props.type !== 'textarea') { - this.__OUTER__.setAttribute('append', '') - } - - function initPos() { - var { x, y, width } = this.getBoundingClientRect() - var size = this.getAttribute('size') - this.props.active = true - if (size && size === 'mini') { - y += 32 - } else { - y += 50 - } - this.__OPTG__.style.cssText = `left:${x}px;top:${y}px;width:${width}px;` - } - - /* ---------------------------------------------------- */ - /* ----------------- 各种事件 ------------------ */ - /* ---------------------------------------------------- */ - - // 键盘事件 - this._handleKeydown = $.catch(this.__INPUT__, 'keydown', ev => { - if (this.disabled || this.readOnly) { - return - } - // up: 38, down: 40 - if (ev.keyCode === 38 || ev.keyCode === 40) { - if (!this.props.active) { - initPos.call(this) - this.__OPTG__.classList.toggle('show', true) - return - } - return this._moveSelect(ev) - } - // 回车触发select事件 - if (ev.keyCode === 13) { - if (this.props.mvidx !== null && this.props.active) { - return this._fetchSelect(this.props.mvidx) - } - } - }) - - // 渲染列表 - this._activeFn = $.bind(this.__INPUT__, 'click', ev => { - var { options } = this.props - - if (this.disabled || this.readOnly) { - return - } - - initPos.call(this) - this.__OPTG__.classList.toggle('show') - }) - - // 选择选项 - this._handleSelect = $.bind(this.__OPTG__, 'click', ev => { - if (ev.target.tagName === 'DD' && !ev.target.hasAttribute('disabled')) { - this._fetchSelect(+ev.target.dataset.idx, true) - this.dispatchEvent(new CustomEvent('input')) - } - }) - - this._inactiveFn = $.outside(this, ev => { - this.__OPTG__.classList.toggle('show', false) - this.props.active = false - }) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - // label和placeholder 功能相同 - case 'label': - case 'placeholder': - this.__INPUT__.setAttribute('placeholder', val) - break - - case 'options': - if (val) { - try { - this._renderOptions(JSON.parse(val)) - } catch (err) {} - this.removeAttribute('options') - } - break - - case 'value': - this.value = val - break - - case 'readonly': - case 'disabled': - var k = name - if (k === 'readonly') { - k = 'readOnly' - } - this[k] = true - break - } - } - - disconnectedCallback() { - $.unbind(this.__INPUT__, 'keydown', this._handleKeydown) - $.unbind(this.__INPUT__, 'click', this._activeFn) - $.unbind(this.__OPTG__, 'click', this._handleSelect) - $.clearOutside(this._inactiveFn) - } -} + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ +import"../scroll/index.js";import"../icon/index.js";import $ from"../utils.js";function parseOptions(t,e){let s="";for(let i of t)if(i.list){s+=`
      ${i.name}
      `;for(let t of i.list)e.DICT[t.value]=t,t.disabled||e.LIST.push(t),s+=`
      ${t.label}
      `}else i.disabled||e.LIST.push(i),e.DICT[i.value]=i,s+=`
      ${i.label}
      `;return s}export default class Select extends HTMLElement{static get observedAttributes(){return["label","placeholder","multi","value","options","mvidx","readonly","disabled"]}props={label:"",placeholder:"",multi:"",value:"",options:"",mvidx:null,readonly:!1,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
      ',this.__OUTER__=this.root.children[1],this.__PREPEND__=this.__OUTER__.children[0],this.__INPUT__=this.__OUTER__.children[1],this.__APPEND__=this.__OUTER__.children[3],this.__OPTG__=this.__OUTER__.children[4]}get readOnly(){return this.props.readonly}set readOnly(t){var e=typeof t;t!==this.props.readonly&&("boolean"===e&&t||"boolean"!==e?(this.props.readonly=!0,this.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(t){var e=typeof t;t!==this.props.disabled&&("boolean"===e&&t||"boolean"!==e?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__INPUT__.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled"),this.__INPUT__.removeAttribute("disabled")))}get value(){return this.props.value}set value(t){var{DICT:e,active:s}=this.props;this.props.value=t,this.__INPUT__.value=e&&e[t]&&e[t].label||t,s||this._updateStyle()}_renderOptions(t){this.props.DICT={},this.props.LIST=[];var e=this.__OPTG__.firstElementChild.firstElementChild;e.innerHTML=parseOptions(t,this.props),this.props.ITEMS=Array.from(e.children).filter(t=>"DD"===t.tagName&&!t.hasAttribute("disabled")),this.value=this.props.value}_moveSelect(t){var{LIST:e,DICT:s,ITEMS:i}=this.props;if(e&&e.length){t.preventDefault();var l=38===t.keyCode?-1:1;null===this.props.mvidx?this.props.mvidx=0:this.props.mvidx+=l,this.props.mvidx<0?this.props.mvidx=0:this.props.mvidx>i.length-1&&(this.props.mvidx=i.length-1),i.forEach((t,e)=>{e===this.props.mvidx?(this.__OPTG__.firstElementChild.scrollTop=t.offsetTop-150,t.setAttribute("focus","")):t.removeAttribute("focus")})}}_updateStyle(t){var{LIST:e,ITEMS:s,value:i}=this.props;if(e&&e.length){if(void 0===t)for(let s,l=-1;s=e[++l];)if(i===s.value){t=l;break}this.props.mvidx=t,s.forEach((e,s)=>{s===t?e.setAttribute("focus",""):e.removeAttribute("focus")})}}_fetchSelect(t,e){var s=this.props.LIST[t];this.value=s.value,this.dispatchEvent(new CustomEvent("select",{detail:s})),e&&this._updateStyle(t),this.props.active=!1,this.__OPTG__.classList.remove("show")}connectedCallback(){for(var t=this.__PREPEND__.assignedNodes(),e=this.__APPEND__.assignedNodes();t.length>1;)this.removeChild(t.pop());for(;e.length>1;)this.removeChild(e.pop());function s(){var{x:t,y:e,width:s}=this.getBoundingClientRect(),i=this.getAttribute("size");this.props.active=!0,e+=i&&"mini"===i?32:50,this.__OPTG__.style.cssText=`left:${t}px;top:${e}px;width:${s}px;`}t.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("prepend",""),e.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("append",""),this._handleKeydown=$.catch(this.__INPUT__,"keydown",t=>{if(!this.disabled&&!this.readOnly)return 38===t.keyCode||40===t.keyCode?this.props.active?this._moveSelect(t):(s.call(this),void this.__OPTG__.classList.toggle("show",!0)):13===t.keyCode&&null!==this.props.mvidx&&this.props.active?this._fetchSelect(this.props.mvidx):void 0}),this._activeFn=$.bind(this.__INPUT__,"click",t=>{var{options:e}=this.props;this.disabled||this.readOnly||(s.call(this),this.__OPTG__.classList.toggle("show"))}),this._handleSelect=$.bind(this.__OPTG__,"click",t=>{"DD"!==t.target.tagName||t.target.hasAttribute("disabled")||(this._fetchSelect(+t.target.dataset.idx,!0),this.dispatchEvent(new CustomEvent("input")))}),this._inactiveFn=$.outside(this,t=>{this.__OPTG__.classList.toggle("show",!1),this.props.active=!1})}attributeChangedCallback(t,e,s){if(e!==s)switch(t){case"label":case"placeholder":this.__INPUT__.setAttribute("placeholder",s);break;case"options":if(s){try{this._renderOptions(JSON.parse(s))}catch(t){}this.removeAttribute("options")}break;case"value":this.value=s;break;case"readonly":case"disabled":var i=t;"readonly"===i&&(i="readOnly"),this[i]=!0}}disconnectedCallback(){$.unbind(this.__INPUT__,"keydown",this._handleKeydown),$.unbind(this.__INPUT__,"click",this._activeFn),$.unbind(this.__OPTG__,"click",this._handleSelect),$.clearOutside(this._inactiveFn)}} if(!customElements.get('wc-select')){ customElements.define('wc-select', Select) diff --git a/src/lib/form/star.js b/src/lib/form/star.js index c9a93ac..e7c9848 100644 --- a/src/lib/form/star.js +++ b/src/lib/form/star.js @@ -1,300 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import $ from "../utils.js" - -export default class Star extends HTMLElement { - - - static get observedAttributes() { - return ["value","text","size","color","'allow-half'","'show-value'","starSize","disabled"] - } - - props = { - value: 0, - text: [], - size: '', - color: '', - 'allow-half': false, - 'show-value': false, - starSize: 32, // 星星的宽度, 用于实现半星 - disabled: false - } - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` - -` - - - this.__BOX__ = this.root.children[1] - this.__STARS__ = Array.from(this.__BOX__.children) - this.__TEXT__ = this.__STARS__.pop() - } - - get value() { - return this.props.value - } - - set value(val) { - var v = +val - var tmp = val >> 0 - if (v === v && v > 0) { - val = v - } else { - val = 0 - } - - if (val > 5) { - val = 5 - } - - this.props.value = val - this._updateDraw(-1) - } - - /** - * 更新图标渲染 - * i: int - * f: float - */ - _updateDraw(i, f = 0) { - var _last = 'star-half' - var { value, tmp = { i: 0, f: 0 } } = this.props - - if (i === -1) { - i = Math.floor(value) - f = +(value % 1).toFixed(1) - if (i > 0 && i === value) { - i-- - f = 1 - } - } - - if (!this.props['allow-half']) { - f = f > 0 ? 1 : 0 - } - // 减少DOM操作 - if (i === tmp.i && f === tmp.f) { - return - } - - if (f > 0.5) { - _last = 'star-full' - } - - this.__STARS__.forEach((it, k) => { - it.setAttribute('is', k < i ? 'star-full' : 'star') - it.setAttribute('color', k < i ? this.props.color : 'grey') - }) - - if (f > 0) { - this.__STARS__[i].setAttribute('is', _last) - this.__STARS__[i].setAttribute('color', this.props.color) - } - - // 缓存结果 - this.props.tmp = { i, f } - - if (i === 0 && f === 0) { - this.__TEXT__.textContent = '' - } else { - if (this.props.text.length === 5) { - this.__TEXT__.textContent = this.props.text[i] - } else { - if (this.props['show-value']) { - this.__TEXT__.textContent = i + f - } - } - } - } - - connectedCallback() { - $.catch(this.__BOX__, 'mousemove', ev => { - if (this.props.disabled) { - return - } - if (ev.target.tagName === 'WC-ICON') { - let idx = +ev.target.dataset.idx - this._updateDraw(idx, +(ev.offsetX / this.props.starSize).toFixed(1)) - } - }) - - $.catch(this.__BOX__, 'click', ev => { - var { tmp, disabled } = this.props - if (disabled) { - return - } - if (ev.target.tagName === 'WC-ICON') { - this.props.value = tmp.i + tmp.f - this.dispatchEvent(new CustomEvent('input')) - } - }) - - $.catch(this.__BOX__, 'mouseleave', ev => { - if (this.props.disabled) { - return - } - this._updateDraw(-1) - }) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'size': - this.props.starSize = this.__STARS__[0].clientWidth - break - - case 'allow-half': - case 'show-value': - case 'disabled': - this.props[name] = true - break - - case 'color': - if (val) { - this.props.color = val - } - break - - case 'text': - if (val) { - val = val.split('|') - if (val.length === 5) { - this.props.text = val.map(it => it.trim()) - } - } - break - - case 'value': - this.value = val - break - } - } -} + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ +import $ from"../utils.js";export default class Star extends HTMLElement{static get observedAttributes(){return["value","text","size","color","'allow-half'","'show-value'","starSize","disabled"]}props={value:0,text:[],size:"",color:"","allow-half":!1,"show-value":!1,starSize:32,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=' ',this.__BOX__=this.root.children[1],this.__STARS__=Array.from(this.__BOX__.children),this.__TEXT__=this.__STARS__.pop()}get value(){return this.props.value}set value(t){var e=+t;(t=e==e&&e>0?e:0)>5&&(t=5),this.props.value=t,this._updateDraw(-1)}_updateDraw(t,e=0){var s="star-half",{value:o,tmp:a={i:0,f:0}}=this.props;-1===t&&(t=Math.floor(o),e=+(o%1).toFixed(1),t>0&&t===o&&(t--,e=1)),this.props["allow-half"]||(e=e>0?1:0),t===a.i&&e===a.f||(e>.5&&(s="star-full"),this.__STARS__.forEach((e,s)=>{e.setAttribute("is",s0&&(this.__STARS__[t].setAttribute("is",s),this.__STARS__[t].setAttribute("color",this.props.color)),this.props.tmp={i:t,f:e},0===t&&0===e?this.__TEXT__.textContent="":5===this.props.text.length?this.__TEXT__.textContent=this.props.text[t]:this.props["show-value"]&&(this.__TEXT__.textContent=t+e))}connectedCallback(){$.catch(this.__BOX__,"mousemove",t=>{if(!this.props.disabled&&"WC-ICON"===t.target.tagName){let e=+t.target.dataset.idx;this._updateDraw(e,+(t.offsetX/this.props.starSize).toFixed(1))}}),$.catch(this.__BOX__,"click",t=>{var{tmp:e,disabled:s}=this.props;s||"WC-ICON"===t.target.tagName&&(this.props.value=e.i+e.f,this.dispatchEvent(new CustomEvent("input")))}),$.catch(this.__BOX__,"mouseleave",t=>{this.props.disabled||this._updateDraw(-1)})}attributeChangedCallback(t,e,s){if(e!==s)switch(t){case"size":this.props.starSize=this.__STARS__[0].clientWidth;break;case"allow-half":case"show-value":case"disabled":this.props[t]=!0;break;case"color":s&&(this.props.color=s);break;case"text":s&&5===(s=s.split("|")).length&&(this.props.text=s.map(t=>t.trim()));break;case"value":this.value=s}}} if(!customElements.get('wc-star')){ customElements.define('wc-star', Star) diff --git a/src/lib/form/switch.js b/src/lib/form/switch.js index 9288822..c3065c3 100644 --- a/src/lib/form/switch.js +++ b/src/lib/form/switch.js @@ -1,240 +1,12 @@ /** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - - -import $ from "../utils.js" -export default class Switch extends HTMLElement { - - - static get observedAttributes() { - return ["'active-text'","'inactive-text'","checked","disabled"] - } - - props = { - 'active-text': null, - 'inactive-text': null, - checked: false, - disabled: false - } - - constructor() { - super(); - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` -
      - - -
      -` - - - this.__SWITCH__ = this.root.lastElementChild.firstElementChild - } - - get value() { - return this.props.checked - } - - set value(val) { - this.checked = val - } - - get checked() { - return this.props.checked - } - - set checked(val) { - this.props.checked = !!val - this.__SWITCH__.classList.toggle('checked', this.props.checked) - } - - get disabled() { - return this.props.disabled - } - - set disabled(val) { - var type = typeof val - - if (val === this.props.disabled) { - return - } - if ((type === 'boolean' && val) || type !== 'boolean') { - this.props.disabled = true - this.setAttribute('disabled', '') - } else { - this.props.disabled = false - this.removeAttribute('disabled') - } - } - - connectedCallback() { - this._handleClick = $.bind(this, 'click', ev => { - if (this.disabled) { - return - } - this.checked = !this.checked - if (this.checked) { - if (this.props['active-text'] !== null) { - this.textContent = this.props['active-text'] - } - } else { - if (this.props['inactive-text'] !== null) { - this.textContent = this.props['inactive-text'] - } - } - this.dispatchEvent(new CustomEvent('input')) - }) - } - - disconnectedCallback() { - $.unbind(this, 'click', this._handleClick) - } - - attributeChangedCallback(name, old, val) { -if (val === null || old === val) {return} - switch (name) { - case 'checked': - case 'disabled': - this[name] = true - break - case 'active-text': - case 'inactive-text': - this.props[name] = val + '' - break - } - } -} + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ +import $ from"../utils.js";export default class Switch extends HTMLElement{static get observedAttributes(){return["'active-text'","'inactive-text'","checked","disabled"]}props={"active-text":null,"inactive-text":null,checked:!1,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
      ',this.__SWITCH__=this.root.lastElementChild.firstElementChild}get value(){return this.props.checked}set value(e){this.checked=e}get checked(){return this.props.checked}set checked(e){this.props.checked=!!e,this.__SWITCH__.classList.toggle("checked",this.props.checked)}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&("boolean"===t&&e||"boolean"!==t?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}connectedCallback(){this._handleClick=$.bind(this,"click",e=>{this.disabled||(this.checked=!this.checked,this.checked?null!==this.props["active-text"]&&(this.textContent=this.props["active-text"]):null!==this.props["inactive-text"]&&(this.textContent=this.props["inactive-text"]),this.dispatchEvent(new CustomEvent("input")))})}disconnectedCallback(){$.unbind(this,"click",this._handleClick)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"checked":case"disabled":this[e]=!0;break;case"active-text":case"inactive-text":this.props[e]=i+""}}} if(!customElements.get('wc-switch')){ customElements.define('wc-switch', Switch) diff --git a/src/lib/form/textarea.js b/src/lib/form/textarea.js new file mode 100644 index 0000000..fab82c9 --- /dev/null +++ b/src/lib/form/textarea.js @@ -0,0 +1,13 @@ +/** + * + * @authors yutent (yutent.io@gmail.com) + * @date 2021-02-05 16:32:07 + * @version v1.0.3 + * + */ + +import"../scroll/index.js";import"../icon/index.js";import $ from"../utils.js";const TYPES=["text","textarea","password"],INPUTS={text:'',textarea:''};export default class Input extends HTMLElement{static get observedAttributes(){return["value","icon","type","placeholder","maxlength","minlength","autofocus","readonly","disabled"]}props={value:"",icon:"",type:"text",placeholder:"",maxlength:null,minlength:null,autofocus:!1,readonly:!1,disabled:!1};state={mvidx:null};constructor(){super();var e,t=this.getAttribute("type");"textarea"!==t&&(t="text"),e=INPUTS[t],Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=`
      ${e}
        `,this.props.type=t,this.__OUTER__=this.root.children[1],this.__PREPEND__=this.__OUTER__.children[0],this.__INPUT__=this.__OUTER__.children[1],this.__ICO__=this.__OUTER__.children[2],this.__APPEND__=this.__OUTER__.children[3],this.__LIST__=this.__OUTER__.children[4]}get readOnly(){return this.props.readonly}set readOnly(e){var t=typeof e;e!==this.props.readonly&&("boolean"===t&&e||"boolean"!==t?(this.props.readonly=!0,this.setAttribute("readonly",""),this.__INPUT__.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly"),this.__INPUT__.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&("boolean"===t&&e||"boolean"!==t?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__INPUT__.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled"),this.__INPUT__.removeAttribute("disabled")))}get value(){return this.__INPUT__.value}set value(e){this.__INPUT__.value=e}get type(){return this.__INPUT__.type}set type(e){"textarea"!==e&&(this.__INPUT__.type=e)}_moveSelect(e){var{list:t}=this.props;if(t&&t.length){e.preventDefault();var i=38===e.keyCode?-1:1,s=Array.from(this.__LIST__.firstElementChild.firstElementChild.children);null===this.state.mvidx?this.state.mvidx=0:this.state.mvidx+=i,this.state.mvidx<0?this.state.mvidx=0:this.state.mvidx>s.length-1&&(this.state.mvidx=s.length-1),s.forEach((e,t)=>{t===this.state.mvidx?(this.__LIST__.firstElementChild.scrollTop=e.offsetTop-150,e.setAttribute("focus","")):e.removeAttribute("focus")})}}_fetchSelect(e,t){var i=this.props.list[e];this.value=i.value,this.dispatchEvent(new CustomEvent("select",{detail:i})),this._handleChange(t),this.__LIST__.classList.remove("show"),this.state.mvidx=null}_updateAttr(){var{maxlength:e,minlength:t}=this.props;e&&e>0?this.__INPUT__.setAttribute("maxlength",e):this.__INPUT__.removeAttribute("maxlength"),t&&t>0?this.__INPUT__.setAttribute("minlength",t):this.__INPUT__.removeAttribute("minlength")}connectedCallback(){for(var e=this.__PREPEND__.assignedNodes(),t=this.__APPEND__.assignedNodes(),{type:i}=this.props;e.length>1;)this.removeChild(e.pop());for(;t.length>1;)this.removeChild(t.pop());e.length&&"textarea"!==i&&this.__OUTER__.setAttribute("prepend",""),t.length&&"textarea"!==i&&this.__OUTER__.setAttribute("append",""),this._updateAttr(),this._handleSubmit=$.catch(this.__INPUT__,"keydown",e=>{if(!this.disabled&&!this.readOnly){if((38===e.keyCode||40===e.keyCode)&&"text"===i)return this._moveSelect(e);if(13===e.keyCode){if("text"===i&&null!==this.state.mvidx)return this._fetchSelect(this.state.mvidx,e);("text"===i||"textarea"===i&&(e.ctrlKey||e.metaKey))&&this.dispatchEvent(new CustomEvent("submit",{detail:this.value}))}}}),"text"===i?(this._handleChange=$.bind(this.__INPUT__,"input",e=>{e.preventDefault(),this.dispatchEvent(new CustomEvent("fetch-suggest",{detail:{value:this.value,send:e=>{this.props.list=e,this._parseSuggestion()}}}))}),this._parseSuggestion=$.bind(this.__INPUT__,"click",e=>{var{list:t}=this.props;let{x:i,y:s,width:r}=this.getBoundingClientRect();if(t&&t.length){var a=t.map((e,t)=>`
      • ${e.value}
      • `).join("");this.__LIST__.firstElementChild.firstElementChild.innerHTML=a,this.__LIST__.classList.toggle("show",!0),this.__LIST__.style.cssText=`left:${i}px;top:${s+50}px;width:${r}px;`}else this.__LIST__.classList.toggle("show",!1)}),this._inactiveFn=$.outside(this,e=>{this.__LIST__.classList.remove("show")}),this._handleSelect=$.bind(this.__LIST__,"click",e=>{"LI"===e.target.tagName&&(this._fetchSelect(e.target.dataset.idx,e),this.dispatchEvent(new CustomEvent("input")))})):this._handleWheel=$.catch(this.__INPUT__,"wheel")}disconnectedCallback(){$.unbind(this.__INPUT__,"wheel",this._handleWheel),$.unbind(this.__INPUT__,"keydown",this._handleSubmit),$.unbind(this.__INPUT__,"input",this._handleChange),$.unbind(this.__LIST__,"click",this._handleSelect),$.clearOutside(this._inactiveFn)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"icon":this.props.icon=i,i?this.__ICO__.setAttribute("is",i):(this.removeAttribute("icon"),this.__ICO__.removeAttribute("is"));break;case"autofocus":this.__INPUT__.setAttribute("autofocus",""),setTimeout(e=>{this.__INPUT__.focus()},10);break;case"placeholder":this.__INPUT__.setAttribute("placeholder",i);break;case"type":~TYPES.indexOf(i)?this.type=i:this.type="text";break;case"value":this.value=i;break;case"maxlength":case"minlength":this.props[e]=i,this._updateAttr();break;case"readonly":case"disabled":var s=e;"readonly"===s&&(s="readOnly"),this[s]=!0}}} + +if(!customElements.get('wc-input')){ + customElements.define('wc-input', Input) +} diff --git a/src/lib/icon/index.js b/src/lib/icon/index.js index bc7c49f..743ddec 100644 --- a/src/lib/icon/index.js +++ b/src/lib/icon/index.js @@ -1,12 +1,12 @@ /** * * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-23 15:31:02 - * @version v1.0.0 + * @date 2021-02-05 16:32:07 + * @version v1.0.3 * */ -import SVG_DICT from"./svg.js";let dict=SVG_DICT;window.EXT_SVG_DICT&&Object.assign(dict,EXT_SVG_DICT);export default class Icon extends HTMLElement{static get observedAttributes(){return["is"]}props={is:""};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=" ",this.__ICO__=this.root.lastElementChild,this.drawPath()}get is(){return this.props.is}set is(o){o&&this.setAttribute("is",o)}drawPath(){var{is:o}=this.props,r=dict[o];this.__ICO__&&o&&r&&(this.__ICO__.innerHTML="loading"===o?r:``,this.__ICO__.classList.toggle("load","loading"===o))}attributeChangedCallback(o,r,e){if(null!==e&&r!==e)switch(o){case"is":this.props.is=e,e?this.drawPath():this.removeAttribute("is")}}} +import SVG_DICT from"./svg.js";let dict=SVG_DICT;window.EXT_SVG_DICT&&Object.assign(dict,EXT_SVG_DICT);export default class Icon extends HTMLElement{static get observedAttributes(){return["is"]}props={is:""};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=' ',this.__ICO__=this.root.lastElementChild,this.drawPath()}get is(){return this.props.is}set is(t){t&&this.setAttribute("is",t)}drawPath(){var{is:t}=this.props,o=dict[t];this.__ICO__&&t&&o&&(this.__ICO__.innerHTML="loading"===t?o:``,this.__ICO__.classList.toggle("load","loading"===t))}attributeChangedCallback(t,o,e){if(o!==e)switch(t){case"is":this.props.is=e,e?this.drawPath():this.removeAttribute("is")}}} if(!customElements.get('wc-icon')){ customElements.define('wc-icon', Icon) diff --git a/src/lib/layer/index.js b/src/lib/layer/index.js index c720c9a..c100593 100644 --- a/src/lib/layer/index.js +++ b/src/lib/layer/index.js @@ -1,12 +1,12 @@ /** * * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-23 15:31:02 - * @version v1.0.0 + * @date 2021-02-05 16:32:07 + * @version v1.0.3 * */ -import"../form/input.js";import Drag from"../drag/core.js";import $ from"../utils.js";const LANGUAGES={en:{TITLE:"Dialog",BTNS:["Cancel","OK"]},zh:{TITLE:"提示",BTNS:["取消","确定"]}};LANGUAGES["zh-CN"]=LANGUAGES.zh;const lang=LANGUAGES[window.__ENV_LANG__||navigator.language]||LANGUAGES.en;let uniqueInstance=null,toastInstance=null;const UNIQUE_TYPES=["alert","confirm","prompt"];function renderBtns(t){var e="";return t.forEach((t,o)=>{e+=``}),e}export default class Layer extends HTMLElement{static get observedAttributes(){return["left","right","top","bottom","from","to","btns","type","title","blur","background","mask","radius","'mask-close'","'mask-color'","fixed"]}props={left:"auto",right:"auto",top:"auto",bottom:"auto",from:Object.create(null),to:Object.create(null),btns:[],type:"",title:"",blur:!1,background:null,mask:!1,radius:null,"mask-close":!1,"mask-color":null,fixed:!0};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
        ',this.__TITLE__=this.root.children[1].firstElementChild,this.__BODY__=this.root.children[1].children[1],this.__CTRL__=this.root.children[1].lastElementChild,this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}set title(t){this.props.title=t,t?(this.__TITLE__.firstElementChild?this.__TITLE__.insertBefore(document.createTextNode(t),this.__TITLE__.firstElementChild):this.__TITLE__.textContent=t,this.__TITLE__.style.display="flex"):this.__TITLE__.style.display=""}set type(t){var{btns:e}=this.props;if(t&&!this._handleBtnClick){switch(t){case"alert":for(;e.length>1;)e.splice(0,1);break;case"confirm":case"prompt":for(;e.length>2;)e.splice(0,1);break;case"toast":case"notify":case"frame":if("notify"===t){var o=document.createElement("wc-icon");o.setAttribute("is","close"),this.__TITLE__.appendChild(o)}e=[];break;default:t="common"}this.props.type=t,e.length?(this.__CTRL__.innerHTML=renderBtns(e),this.__CTRL__.style.display="flex"):this.__CTRL__.style.display="",this.setAttribute(t,"")}}set fixed(t){this.props.fixed=!!t,this._updateFixedStat()}_updateFixedStat(){UNIQUE_TYPES.includes(this.props.type)||(this.props.fixed?this._dragIns&&(this._dragIns.destroy(),this._dragIns=null):(this._dragIns=new Drag(this.root.children[1]).by(this.__TITLE__,{overflow:!!this.props.hasOwnProperty("overflow")&&this.props.overflow}),this.removeAttribute("fixed")))}_intercept(t){this.props.intercept?this.props.intercept(t,e=>{delete this.props.intercept,this.resolve(t),this.close()}):(this.resolve(t),this.close())}close(t){if(!1===this.wrapped)if(this._dragIns&&this._dragIns.destroy(),UNIQUE_TYPES.includes(this.props.type)&&(uniqueInstance=null),delete this.promise,$.unbind(this.__CTRL__,"click",this._handleBtnClick),this.props.from&&!t){let t="opacity:0;";for(let e in this.props.from)t+=`${e}:${this.props.from[e]};`;this.root.children[1].style.cssText+=t,this.timer=setTimeout(()=>{this.parentNode.removeChild(this),this.dispatchEvent(new CustomEvent("close"))},200)}else clearTimeout(this.timer),this.parentNode.removeChild(this),this.dispatchEvent(new CustomEvent("close"));else this.removeAttribute("common"),this.dispatchEvent(new CustomEvent("close"))}show(){!1!==this.wrapped&&this.setAttribute("common","")}moveTo(t={}){var e="";for(var o in t)e+=`${o}:${t[o]};`;this.root.children[1].style.cssText+=e}connectedCallback(){this.type=this.props.type,this.title=this.props.title,this._handleBtnClick=$.bind(this.__CTRL__,"click",t=>{if("BUTTON"===t.target.tagName){var e=+t.target.dataset.idx,{type:o}=this.props;switch(o){case"alert":this.resolve(),this.close();break;case"confirm":case"prompt":if(0===e)this.reject(),this.close();else{let t="prompt"===o?this.__INPUT__.value:null;this._intercept(t)}break;default:this._intercept(e)}}}),"prompt"===this.props.type&&(this.__INPUT__=this.__BODY__.firstElementChild.assignedNodes().pop(),this._handleSubmit=$.bind(this.__INPUT__,"submit",t=>{this._intercept(t.detail)})),this.props.mask&&this.setAttribute("mask",""),this._updateFixedStat(),this.props.mask&&(this._handlMask=$.outside(this.root.children[1],t=>{t.target===this&&(this.props["mask-close"]?(!1===this.wrapped&&this.reject(null),this.close()):UNIQUE_TYPES.includes(this.props.type)&&(this.root.children[1].classList.toggle("scale",!0),setTimeout(t=>{this.root.children[1].classList.remove("scale")},100)))}),this.props["mask-color"]&&(this.style.backgroundColor=this.props["mask-color"])),this.props.blur&&this.root.children[1].classList.toggle("blur",!0);let t=this.props.from?"":"opacity:1;";if(this.props.background&&(t+=`background: ${this.props.background};`),(this.props.radius||0===this.props.radius)&&(t+=`border-radius: ${this.props.radius};`),this.props.size)for(let e in this.props.size)t+=`${e}:${this.props.size[e]};`;if(this.props.from){for(let e in this.props.from)t+=`${e}:${this.props.from[e]};`;setTimeout(t=>{let e="opacity:1;";for(let t in this.props.to)e+=`${t}:${this.props.to[t]};`;this.root.children[1].style.cssText+=e},50)}t&&(this.root.children[1].style.cssText+=t),"toast"===this.props.type&&(this.timer=setTimeout(()=>{toastInstance=null,this.close()},3e3)),"notify"===this.props.type&&(this._handleClose=$.bind(this.__TITLE__,"click",t=>{"WC-ICON"===t.target.tagName&&this.close()}))}disconnectedCallback(){$.clearOutside(this._handlMask),$.unbind(this.__TITLE__,"click",this._handleClose)}attributeChangedCallback(t,e,o){if(null!==o&&e!==o)switch(t){case"title":case"type":this[t]=o,this.removeAttribute(t);break;case"mask-color":case"background":this.props[t]=o;break;case"mask":case"mask-close":case"blur":this.props[t]=!0;break;case"radius":this.props.radius=o;break;case"left":case"right":case"top":case"bottom":this.props.from[t]=o,this.props.to=this.props.from,this.removeAttribute(t);break;case"fixed":this.fixed=!0}}}function _layer(t){var e=document.createElement("wc-layer");if(t.type||(t.type="common"),"toast"===t.type){var{type:o,content:r}=t;t={type:o,content:r,from:{top:0},to:{top:"30px"}},toastInstance&&toastInstance.close(!0),toastInstance=e}else e.props.mask=t.mask,!1===t.btns?e.props.btns=[]:t.btns&&t.btns.length?e.props.btns=t.btns:e.props.btns=lang.BTNS.concat(),t.intercept&&"function"==typeof t.intercept&&(e.props.intercept=t.intercept),e.props.mask=t.mask,e.props["mask-close"]=t["mask-close"],t.hasOwnProperty("overflow")&&(e.props.overflow=t.overflow),e.props["mask-color"]=t["mask-color"],e.props.blur=t.blur,e.props.radius=t.radius,e.props.background=t.background,t.size&&"object"==typeof t.size&&(e.props.size=t.size),UNIQUE_TYPES.includes(t.type)&&(uniqueInstance&&uniqueInstance.close(!0),uniqueInstance=e);return t.to&&"object"==typeof t.to&&(e.props.to=t.to,t.from&&"object"==typeof t.from?e.props.from=t.from:e.props.from=t.to),e.props.type=t.type,e.props.title=t.title,t.hasOwnProperty("fixed")&&(e.props.fixed=t.fixed),e.innerHTML=t.content,e.wrapped=!1,document.body.appendChild(e),e.promise}Object.assign(_layer,{alert(t,e=lang.TITLE){return this({type:"alert",title:e,content:t,mask:!0})},confirm(t,e=lang.TITLE,o){return"function"==typeof e&&(o=e,e=lang.TITLE),this({type:"confirm",title:e,content:t,mask:!0,intercept:o})},prompt(t=lang.TITLE,e){return this({type:"prompt",title:t,content:'',mask:!0,intercept:e})},frame(t,e={}){return this({...e,type:"frame",content:``,mask:!0,"mask-close":!0})},notify(t){return this({type:"notify",title:"通知",content:t,blur:!0,from:{right:"-300px",top:0},to:{right:0}})},toast(t,e="info"){var o=e;switch(e){case"info":case"warn":break;case"error":o="deny";break;case"success":o="get";break;default:o="info"}return this({content:`\n
        \n \n ${t}\n
        `,type:"toast"})}}),window.layer=_layer; +import"../form/input.js";import Drag from"../drag/core.js";import $ from"../utils.js";const LANGUAGES={en:{TITLE:"Dialog",BTNS:["Cancel","OK"]},zh:{TITLE:"提示",BTNS:["取消","确定"]}};LANGUAGES["zh-CN"]=LANGUAGES.zh;const lang=LANGUAGES[window.__ENV_LANG__||navigator.language]||LANGUAGES.en;let uniqueInstance=null,toastInstance=null;const UNIQUE_TYPES=["alert","confirm","prompt"];function renderBtns(t){var e="";return t.forEach((t,s)=>{e+=``}),e}export default class Layer extends HTMLElement{static get observedAttributes(){return["left","right","top","bottom","from","to","btns","type","title","blur","background","mask","radius","'mask-close'","'mask-color'","fixed"]}props={left:"auto",right:"auto",top:"auto",bottom:"auto",from:Object.create(null),to:Object.create(null),btns:[],type:"",title:"",blur:!1,background:null,mask:!1,radius:null,"mask-close":!1,"mask-color":null,fixed:!0};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
        ',this.__TITLE__=this.root.children[1].firstElementChild,this.__BODY__=this.root.children[1].children[1],this.__CTRL__=this.root.children[1].lastElementChild,this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}set title(t){this.props.title=t,t?(this.__TITLE__.firstElementChild?this.__TITLE__.insertBefore(document.createTextNode(t),this.__TITLE__.firstElementChild):this.__TITLE__.textContent=t,this.__TITLE__.style.display="flex"):this.__TITLE__.style.display=""}set type(t){var{btns:e}=this.props;if(t&&!this._handleBtnClick){switch(t){case"alert":for(;e.length>1;)e.splice(0,1);break;case"confirm":case"prompt":for(;e.length>2;)e.splice(0,1);break;case"toast":case"notify":case"frame":if("notify"===t){var s=document.createElement("wc-icon");s.setAttribute("is","close"),this.__TITLE__.appendChild(s)}e=[];break;default:t="common"}this.props.type=t,e.length?(this.__CTRL__.innerHTML=renderBtns(e),this.__CTRL__.style.display="flex"):this.__CTRL__.style.display="",this.setAttribute(t,"")}}set fixed(t){this.props.fixed=!!t,this._updateFixedStat()}_updateFixedStat(){UNIQUE_TYPES.includes(this.props.type)||(this.props.fixed?this._dragIns&&(this._dragIns.destroy(),this._dragIns=null):(this._dragIns=new Drag(this.root.children[1]).by(this.__TITLE__,{overflow:!!this.props.hasOwnProperty("overflow")&&this.props.overflow}),this.removeAttribute("fixed")))}_intercept(t){this.props.intercept?this.props.intercept(t,e=>{delete this.props.intercept,this.resolve(t),this.close()}):(this.resolve(t),this.close())}close(t){if(!1===this.wrapped)if(this._dragIns&&this._dragIns.destroy(),UNIQUE_TYPES.includes(this.props.type)&&(uniqueInstance=null),delete this.promise,$.unbind(this.__CTRL__,"click",this._handleBtnClick),this.props.from&&!t){let t="opacity:0;";for(let e in this.props.from)t+=`${e}:${this.props.from[e]};`;this.root.children[1].style.cssText+=t,this.timer=setTimeout(()=>{this.parentNode.removeChild(this),this.dispatchEvent(new CustomEvent("close"))},200)}else clearTimeout(this.timer),this.parentNode.removeChild(this),this.dispatchEvent(new CustomEvent("close"));else this.removeAttribute("common"),this.dispatchEvent(new CustomEvent("close"))}show(){!1!==this.wrapped&&this.setAttribute("common","")}moveTo(t={}){var e="";for(var s in t)e+=`${s}:${t[s]};`;this.root.children[1].style.cssText+=e}connectedCallback(){this.type=this.props.type,this.title=this.props.title,this._handleBtnClick=$.bind(this.__CTRL__,"click",t=>{if("BUTTON"===t.target.tagName){var e=+t.target.dataset.idx,{type:s}=this.props;switch(s){case"alert":this.resolve(),this.close();break;case"confirm":case"prompt":if(0===e)this.reject(),this.close();else{let t="prompt"===s?this.__INPUT__.value:null;this._intercept(t)}break;default:this._intercept(e)}}}),"prompt"===this.props.type&&(this.__INPUT__=this.__BODY__.firstElementChild.assignedNodes().pop(),this._handleSubmit=$.bind(this.__INPUT__,"submit",t=>{this._intercept(t.detail)})),this.props.mask&&this.setAttribute("mask",""),this._updateFixedStat(),this.props.mask&&(this._handlMask=$.outside(this.root.children[1],t=>{t.target===this&&(this.props["mask-close"]?(!1===this.wrapped&&this.reject(null),this.close()):UNIQUE_TYPES.includes(this.props.type)&&(this.root.children[1].classList.toggle("scale",!0),setTimeout(t=>{this.root.children[1].classList.remove("scale")},100)))}),this.props["mask-color"]&&(this.style.backgroundColor=this.props["mask-color"])),this.props.blur&&this.root.children[1].classList.toggle("blur",!0);let t=this.props.from?"":"opacity:1;";if(this.props.background&&(t+=`background: ${this.props.background};`),(this.props.radius||0===this.props.radius)&&(t+=`border-radius: ${this.props.radius};`),this.props.size)for(let e in this.props.size)t+=`${e}:${this.props.size[e]};`;if(this.props.from){for(let e in this.props.from)t+=`${e}:${this.props.from[e]};`;setTimeout(t=>{let e="opacity:1;";for(let t in this.props.to)e+=`${t}:${this.props.to[t]};`;this.root.children[1].style.cssText+=e},50)}t&&(this.root.children[1].style.cssText+=t),"toast"===this.props.type&&(this.timer=setTimeout(()=>{toastInstance=null,this.close()},3e3)),"notify"===this.props.type&&(this._handleClose=$.bind(this.__TITLE__,"click",t=>{"WC-ICON"===t.target.tagName&&this.close()}))}disconnectedCallback(){$.clearOutside(this._handlMask),$.unbind(this.__TITLE__,"click",this._handleClose)}attributeChangedCallback(t,e,s){if(e!==s)switch(t){case"title":case"type":this[t]=s,this.removeAttribute(t);break;case"mask-color":case"background":this.props[t]=s;break;case"mask":case"mask-close":case"blur":this.props[t]=!0;break;case"radius":this.props.radius=s;break;case"left":case"right":case"top":case"bottom":this.props.from[t]=s,this.props.to=this.props.from,this.removeAttribute(t);break;case"fixed":this.fixed=!0}}}function _layer(t){var e=document.createElement("wc-layer");if(t.type||(t.type="common"),"toast"===t.type){var{type:s,content:o}=t;t={type:s,content:o,from:{top:0},to:{top:"30px"}},toastInstance&&toastInstance.close(!0),toastInstance=e}else e.props.mask=t.mask,!1===t.btns?e.props.btns=[]:t.btns&&t.btns.length?e.props.btns=t.btns:e.props.btns=lang.BTNS.concat(),t.intercept&&"function"==typeof t.intercept&&(e.props.intercept=t.intercept),e.props.mask=t.mask,e.props["mask-close"]=t["mask-close"],t.hasOwnProperty("overflow")&&(e.props.overflow=t.overflow),e.props["mask-color"]=t["mask-color"],e.props.blur=t.blur,e.props.radius=t.radius,e.props.background=t.background,t.size&&"object"==typeof t.size&&(e.props.size=t.size),UNIQUE_TYPES.includes(t.type)&&(uniqueInstance&&uniqueInstance.close(!0),uniqueInstance=e);return t.to&&"object"==typeof t.to&&(e.props.to=t.to,t.from&&"object"==typeof t.from?e.props.from=t.from:e.props.from=t.to),e.props.type=t.type,e.props.title=t.title,t.hasOwnProperty("fixed")&&(e.props.fixed=t.fixed),e.innerHTML=t.content,e.wrapped=!1,document.body.appendChild(e),e.promise}Object.assign(_layer,{alert(t,e=lang.TITLE){return this({type:"alert",title:e,content:t,mask:!0})},confirm(t,e=lang.TITLE,s){return"function"==typeof e&&(s=e,e=lang.TITLE),this({type:"confirm",title:e,content:t,mask:!0,intercept:s})},prompt(t=lang.TITLE,e){return this({type:"prompt",title:t,content:'',mask:!0,intercept:e})},frame(t,e={}){return this({...e,type:"frame",content:``,mask:!0,"mask-close":!0})},notify(t){return this({type:"notify",title:"通知",content:t,blur:!0,from:{right:"-300px",top:0},to:{right:0}})},toast(t,e="info"){var s=e;switch(e){case"info":case"warn":break;case"error":s="deny";break;case"success":s="get";break;default:s="info"}return this({content:`\n
        \n \n ${t}\n
        `,type:"toast"})}}),window.layer=_layer; if(!customElements.get('wc-layer')){ customElements.define('wc-layer', Layer) diff --git a/src/lib/scroll/index.js b/src/lib/scroll/index.js index cc153f0..bb8e951 100644 --- a/src/lib/scroll/index.js +++ b/src/lib/scroll/index.js @@ -1,12 +1,12 @@ /** * * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-23 15:31:02 - * @version v1.0.0 + * @date 2021-02-05 16:32:07 + * @version v1.0.3 * */ -import $ from"../utils.js";const IS_FF=!!window.sidebar;export default class Scroll extends HTMLElement{static get observedAttributes(){return["thumbX","thumbY","disabled","axis","delay","distance"]}props={thumbX:0,thumbY:0,disabled:!1,axis:"xy",delay:1e3,distance:1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
        ',this.__BOX__=this.root.children[1],this.__X__=this.root.children[2].children[0],this.__Y__=this.root.children[3].children[0],this.__last__=0}get scrollTop(){return this.__BOX__.scrollTop}set scrollTop(t){if((t=+t)==t){var{sh:s,oh:i,yh:e}=this.props;this.__BOX__.scrollTop=t;var o=this.__BOX__.scrollTop/(s-i)*(i-e);this.props.thumbY=o,this.__Y__.style.transform=`translateY(${o}px)`}}get scrollLeft(){return this.__BOX__.scrollLeft}set scrollLeft(t){if((t=+t)==t){var{sw:s,ow:i,xw:e}=this.props;this.__BOX__.scrollLeft=t;var o=this.__BOX__.scrollLeft/(s-i)*(i-e);this.props.thumbX=o,this.__X__.style.transform=`translateX(${o}px)`}}get scrollHeight(){return this.__BOX__.scrollHeight}get scrollWidth(){return this.__BOX__.scrollWidth}get disabled(){return this.props.disabled}set disabled(t){var s=typeof t;t!==this.props.disabled&&("boolean"===s&&t||"boolean"!==s?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}_fetchScrollX(t){var{sw:s,ow:i,xw:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollLeft=t/(i-e)*(s-i),this.__X__.style.transform=`translateX(${t}px)`,t}_fetchScrollY(t){var{sh:s,oh:i,yh:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollTop=t/(i-e)*(s-i),this.__Y__.style.transform=`translateY(${t}px)`,t}_fireReachEnd(t="reach-bottom"){var{sh:s,oh:i,delay:e,disabled:o}=this.props,r=this.__BOX__.scrollTop,h=Date.now();if(!o&&h-this.__last__>e){if("reach-bottom"===t){if(i+r0)return;this.__last__=h,this.dispatchEvent(new CustomEvent(t))}}connectedCallback(){this._initFn=$.bind(this.__BOX__,"mouseenter",t=>{if(!this.disabled){var s=this.__BOX__.offsetWidth,i=this.__BOX__.scrollWidth,e=this.__BOX__.offsetHeight,o=this.__BOX__.scrollHeight,r=e*e/o>>0,h=s*s/i>>0;r<50&&(r=50),h<50&&(h=50),h===s&&(h=0),r===e&&(r=0),this.props.oh=e,this.props.sh=o,this.props.ow=s,this.props.sw=i,this.props.yh=r,this.props.xw=h,this.__X__.style.width=h+"px",this.__Y__.style.height=r+"px"}}),this._inactiveFn=$.bind(this.__BOX__,"mouseleave",t=>{delete this._active}),this._wheelFn=$.bind(this.__BOX__,"wheel",t=>{if(!this.disabled){var{sh:s,oh:i,yh:e,sw:o,ow:r,xw:h}=this.props;if(h||e){var l,a,_=Date.now();if((!this.stamp||_-this.stamp>800)&&(this.stamp=_,this.times=1),IS_FF)l=t.deltaMode?10*t.deltaX:t.deltaX,a=t.deltaMode?10*t.deltaY:t.deltaY;else{var n=Math.abs(t.wheelDelta);n<120?(l=t.deltaX,a=t.deltaY):(l=t.deltaX/(n/120),a=t.deltaY/(n/120))}if(_-this.stamp<20&&(this.times+=.05,this.times>3&&(this.times=3)),l*=this.times,a*=this.times,"x"!==this.props.axis&&(this.__BOX__.scrollTop+=a,e)){var c=this.__BOX__.scrollTop/(s-i)*(i-e);if((0===(c>>=0)||i-e===c)&&c===this.props.thumbY)return;t.preventDefault(),t.stopPropagation(),this.props.thumbY=c,this.__Y__.style.transform=`translateY(${c}px)`,Math.abs(a)>this.props.distance&&this._fireReachEnd(a>0?"reach-bottom":"reach-top")}if("y"!==this.props.axis&&(this.__BOX__.scrollLeft+=l,h)){var p=this.__BOX__.scrollLeft/(o-r)*(r-h);if((0===(p>>=0)||r-h===p)&&p===this.props.thumbX)return;t.preventDefault(),t.stopPropagation(),this.props.thumbX=p,this.__X__.style.transform=`translateX(${p}px)`}this._active=!0,this.stamp=_,this.dispatchEvent(new CustomEvent("scroll",{detail:{x:this.props.thumbX,y:this.props.thumbY}}))}}});var t,s,i,e,o=o=>{var{thumbY:r,thumbX:h}=this.props;null!==t&&(i=this._fetchScrollX(h+o.pageX-t)),null!==s&&(this._active=!0,e=this._fetchScrollY(r+o.pageY-s))},r=h=>{Math.abs(h.pageY-s)>this.props.distance&&this._fireReachEnd(h.pageY>s?"reach-bottom":"reach-top"),t=null,s=null,this.props.thumbX=i,this.props.thumbY=e,$.unbind(document,"mousemove",o),$.unbind(document,"mouseup",r)};$.bind(this.__Y__,"mousedown",t=>{s=t.pageY,this.props.thumbY||(this.props.thumbY=0),this.disabled||($.bind(document,"mousemove",o),$.bind(document,"mouseup",r))}),$.bind(this.__X__,"mousedown",s=>{t=s.pageX,this.props.thumbX||(this.props.thumbX=0),this.disabled||($.bind(document,"mousemove",o),$.bind(document,"mouseup",r))}),$.catch(document,"keydown",t=>{if(this._active){var{oh:s,sh:i}=this.props,e=!1;switch(t.keyCode){case 33:e=!0,this.scrollTop-=s;break;case 34:e=!0,this.scrollTop+=s;break;case 35:e=!0,this.scrollTop=i;break;case 36:e=!0,this.scrollTop=0}e&&t.preventDefault()}}),this.__observer=new MutationObserver(this._initFn),this.__observer.observe(this,{childList:!0,subtree:!0,characterData:!0})}disconnectedCallback(){this.__observer.disconnect(),$.unbind(this.__BOX__,"mouseenter",this._initFn),$.unbind(this.__BOX__,"mouseleave",this._inactiveFn),$.unbind(this.__BOX__,"wheel",this._wheelFn)}attributeChangedCallback(t,s,i){if(null!==i&&s!==i)switch(t){case"axis":this.props.axis=i;break;case"disabled":this[t]=!0;break;case"delay":this.props.delay=+i||1e3;break;case"distance":this.props.distance=+i||1}}} +import $ from"../utils.js";const IS_FF=!!window.sidebar;export default class Scroll extends HTMLElement{static get observedAttributes(){return["thumbX","thumbY","disabled","axis","delay","distance"]}props={thumbX:0,thumbY:0,disabled:!1,axis:"xy",delay:1e3,distance:1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
        ',this.__BOX__=this.root.children[1],this.__X__=this.root.children[2].children[0],this.__Y__=this.root.children[3].children[0],this.__last__=0}get scrollTop(){return this.__BOX__.scrollTop}set scrollTop(t){if((t=+t)==t){var{sh:s,oh:i,yh:e}=this.props;this.__BOX__.scrollTop=t;var h=this.__BOX__.scrollTop/(s-i)*(i-e);this.props.thumbY=h,this.__Y__.style.transform=`translateY(${h}px)`}}get scrollLeft(){return this.__BOX__.scrollLeft}set scrollLeft(t){if((t=+t)==t){var{sw:s,ow:i,xw:e}=this.props;this.__BOX__.scrollLeft=t;var h=this.__BOX__.scrollLeft/(s-i)*(i-e);this.props.thumbX=h,this.__X__.style.transform=`translateX(${h}px)`}}get scrollHeight(){return this.__BOX__.scrollHeight}get scrollWidth(){return this.__BOX__.scrollWidth}get disabled(){return this.props.disabled}set disabled(t){var s=typeof t;t!==this.props.disabled&&("boolean"===s&&t||"boolean"!==s?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}_fetchScrollX(t){var{sw:s,ow:i,xw:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollLeft=t/(i-e)*(s-i),this.__X__.style.transform=`translateX(${t}px)`,t}_fetchScrollY(t){var{sh:s,oh:i,yh:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollTop=t/(i-e)*(s-i),this.__Y__.style.transform=`translateY(${t}px)`,t}_fireReachEnd(t="reach-bottom"){var{sh:s,oh:i,delay:e,disabled:h}=this.props,o=this.__BOX__.scrollTop,r=Date.now();if(!h&&r-this.__last__>e){if("reach-bottom"===t){if(i+o0)return;this.__last__=r,this.dispatchEvent(new CustomEvent(t))}}connectedCallback(){this._initFn=$.bind(this.__BOX__,"mouseenter",t=>{if(!this.disabled){var s=this.__BOX__.offsetWidth,i=this.__BOX__.scrollWidth,e=this.__BOX__.offsetHeight,h=this.__BOX__.scrollHeight,o=e*e/h>>0,r=s*s/i>>0;o<50&&(o=50),r<50&&(r=50),r>=s&&(r=0),o>=e&&(o=0),this.props.oh=e,this.props.sh=h,this.props.ow=s,this.props.sw=i,this.props.yh=o,this.props.xw=r,this.__X__.style.width=r+"px",this.__Y__.style.height=o+"px"}}),this._inactiveFn=$.bind(this.__BOX__,"mouseleave",t=>{delete this._active}),this._wheelFn=$.bind(this.__BOX__,"wheel",t=>{if(!this.disabled){var{sh:s,oh:i,yh:e,sw:h,ow:o,xw:r}=this.props;if(r||e){var a,l,_=Date.now();if((!this.stamp||_-this.stamp>800)&&(this.stamp=_,this.times=1),IS_FF)a=t.deltaMode?10*t.deltaX:t.deltaX,l=t.deltaMode?10*t.deltaY:t.deltaY;else{var n=Math.abs(t.wheelDelta);n<120?(a=t.deltaX,l=t.deltaY):(a=t.deltaX/(n/120),l=t.deltaY/(n/120))}if(_-this.stamp<20&&(this.times+=.05,this.times>3&&(this.times=3)),a*=this.times,l*=this.times,"x"!==this.props.axis&&(this.__BOX__.scrollTop+=l,e)){var p=this.__BOX__.scrollTop/(s-i)*(i-e);if((0===(p>>=0)||i-e===p)&&p===this.props.thumbY)return;t.preventDefault(),t.stopPropagation(),this.props.thumbY=p,this.__Y__.style.transform=`translateY(${p}px)`,Math.abs(l)>this.props.distance&&this._fireReachEnd(l>0?"reach-bottom":"reach-top")}if("y"!==this.props.axis&&(this.__BOX__.scrollLeft+=a,r)){var d=this.__BOX__.scrollLeft/(h-o)*(o-r);if((0===(d>>=0)||o-r===d)&&d===this.props.thumbX)return;t.preventDefault(),t.stopPropagation(),this.props.thumbX=d,this.__X__.style.transform=`translateX(${d}px)`}this._active=!0,this.stamp=_,this.dispatchEvent(new CustomEvent("scroll",{detail:{x:this.props.thumbX,y:this.props.thumbY}}))}}});var t,s,i,e,h=h=>{var{thumbY:o,thumbX:r}=this.props;null!==t&&(i=this._fetchScrollX(r+h.pageX-t)),null!==s&&(this._active=!0,e=this._fetchScrollY(o+h.pageY-s))},o=r=>{Math.abs(r.pageY-s)>this.props.distance&&this._fireReachEnd(r.pageY>s?"reach-bottom":"reach-top"),t=null,s=null,this.props.thumbX=i,this.props.thumbY=e,$.unbind(document,"mousemove",h),$.unbind(document,"mouseup",o)};$.bind(this.__Y__,"mousedown",t=>{s=t.pageY,this.props.thumbY||(this.props.thumbY=0),this.disabled||($.bind(document,"mousemove",h),$.bind(document,"mouseup",o))}),$.bind(this.__X__,"mousedown",s=>{t=s.pageX,this.props.thumbX||(this.props.thumbX=0),this.disabled||($.bind(document,"mousemove",h),$.bind(document,"mouseup",o))}),$.catch(document,"keydown",t=>{if(this._active){var{oh:s,sh:i}=this.props,e=!1;switch(t.keyCode){case 33:e=!0,this.scrollTop-=s;break;case 34:e=!0,this.scrollTop+=s;break;case 35:e=!0,this.scrollTop=i;break;case 36:e=!0,this.scrollTop=0}e&&t.preventDefault()}}),this.__observer=new MutationObserver(this._initFn),this.__observer.observe(this,{childList:!0,subtree:!0,characterData:!0})}disconnectedCallback(){this.__observer.disconnect(),$.unbind(this.__BOX__,"mouseenter",this._initFn),$.unbind(this.__BOX__,"mouseleave",this._inactiveFn),$.unbind(this.__BOX__,"wheel",this._wheelFn)}attributeChangedCallback(t,s,i){if(s!==i)switch(t){case"axis":this.props.axis=i;break;case"disabled":this[t]=!0;break;case"delay":this.props.delay=+i||1e3;break;case"distance":this.props.distance=+i||1}}} if(!customElements.get('wc-scroll')){ customElements.define('wc-scroll', Scroll)