From 12d7ae7c349260eadc8d21500c093037a2a563bb Mon Sep 17 00:00:00 2001 From: chenjiajian <770230504@qq.com> Date: Fri, 5 May 2023 15:15:04 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BC=98=E5=8C=96input&popconfirm=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/form/input.js | 89 +++++++++++++++-------------------------- src/popconfirm/index.js | 14 +------ 2 files changed, 34 insertions(+), 69 deletions(-) diff --git a/src/form/input.js b/src/form/input.js index 623ec2d..cb9265d 100644 --- a/src/form/input.js +++ b/src/form/input.js @@ -16,7 +16,10 @@ import '../icon/index.js' const ANIMATION = { duration: 100, - custom: [{ transform: 'scaleY(0)' }, { transform: 'scaleY(1)' }] + custom: [ + { transform: 'scaleY(0)', opacity: 0 }, + { transform: 'scaleY(1)', opacity: 1 } + ] } class Input extends Component { @@ -38,8 +41,6 @@ class Input extends Component { lazy: 0 // 并发拦截时间, 单位毫秒 } #list = [] - #originList = [] - #isComposing = false #selectIndex = -1 #listShowing = false #stamp = 0 @@ -132,16 +133,11 @@ class Input extends Component { left: 0; top: calc(100% + 4px); width: 100%; - height: auto; - max-height: 200px; padding: 4px 0; border-radius: 4px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15); transform-origin: top; - .scroller { - max-height: 200px; - } .list { width: 100%; } @@ -375,8 +371,6 @@ class Input extends Component { ref="input" @input=${this.handleInput} @change=${this.handleChange} - @compositionstart=${this.handleCompositionstart} - @compositionend=${this.handleCompositionend} @keydown=${this.handleKeyDown} @focus=${this.handleFocus} placeholder=${this.placeholder} @@ -409,73 +403,39 @@ class Input extends Component { ` } - handleCompositionstart() { - this.#isComposing = true - } - handleCompositionend() { - this.#isComposing = false - this.filterSuggestList() - } - filterSuggestList() { - if (!this.#originList.length) { - return - } - if (!this.value.trim()) { - this.#list = [] - } else { - this.#list = this.#originList.filter(li => - li.value.startsWith(this.value) - ) - } - if (!this.#listShowing) { - this.#listShowing = true - this.$refs.suggestion.$animate() - } - this.$requestUpdate() - } + handleInput(e) { let { lazy } = this this.value = e.currentTarget.value + if (lazy && Date.now() - this.#stamp < lazy) { return } this.#stamp = Date.now() - if (!this.#isComposing) { - this.filterSuggestList() - } this.emitFetchSuggest() } handleClickItem(e) { let index = e.target.getAttribute('index') - this.value = this.#list[index].value - this.#list = [this.#list[index]] - this.$refs.suggestion.$animate(true) - this.#listShowing = false - this.$emit('select') + this.#selectIndex = index + this.emitSelect() } clear() { this.$refs.input.value = '' this.value = '' - if (this.#originList.length) { - this.filterSuggestList() - } + this.$emit('change') + this.$emit('input') } handleChange() { this.$emit('change') } handleKeyDown(e) { let { lazy, minlength, value } = this + if (e.keyCode === 13) { e.preventDefault() if (this.#selectIndex > -1 && this.#listShowing) { - this.value = this.#list[this.#selectIndex].value - this.#list = [this.#list[this.#selectIndex]] - this.#selectIndex = 0 - this.$requestUpdate() - this.$refs.suggestion.$animate(true) - this.#listShowing = false - return this.$emit('select') //输入建议存在,则第1次回车的时候, 不触发提交 + return this.emitSelect() } if (lazy && Date.now() - this.#stamp < lazy) { return @@ -486,6 +446,7 @@ class Input extends Component { } return this.$emit('submit') } + if (e.keyCode === 38 || e.keyCode === 40) { e.preventDefault() let step = e.keyCode === 38 ? -1 : 1 @@ -497,17 +458,33 @@ class Input extends Component { if (this.#selectIndex > this.#list.length - 1) { this.#selectIndex = this.#list.length - 1 } - let target = this.$refs.list.children[this.#selectIndex] - this.$refs.scroller.scrollTop = target.offsetTop - 150 + this.$requestUpdate() } } + // 触发列表选择 + emitSelect() { + let item = this.#list[this.#selectIndex] + this.value = item.value + + this.$refs.suggestion.$animate(true) + this.#listShowing = false + this.$requestUpdate() + + this.$emit('change') + this.$emit('input') + this.$emit('select', { + index: this.#selectIndex, + value: item + }) + } emitFetchSuggest() { this.$emit('fetch-suggest', { value: this.value, send: list => { - this.#originList = this.#list = list.slice(0, 5) - this.filterSuggestList() + this.#list = list.slice(0, 10) + this.#selectIndex = -1 + this.$requestUpdate() } }) } diff --git a/src/popconfirm/index.js b/src/popconfirm/index.js index f240b07..c458008 100644 --- a/src/popconfirm/index.js +++ b/src/popconfirm/index.js @@ -4,9 +4,8 @@ * @date 2023/04/28 16:14:10 */ -import { css, html, Component, nextTick, styleMap } from '@bd/core' +import { css, html, Component, styleMap } from '@bd/core' import '../form/button.js' -import '../icon/index.js' class Popconfirm extends Component { static props = { @@ -51,17 +50,6 @@ class Popconfirm extends Component { attribute: false }, - //组件状态 - left: { - type: Number, - default: 0, - attribute: false - }, - top: { - type: Number, - default: 0, - attribute: false - }, show: { type: Boolean, default: false, From c2678e744ce1a61952c2e4b508aa345806bf5857 Mon Sep 17 00:00:00 2001 From: chenjiajian <770230504@qq.com> Date: Fri, 5 May 2023 18:23:37 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=88=86=E7=A6=BBimagePreview=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/image-preview/index.js | 283 +++++++++++++++++++++++++++++++++++++ src/image/index.js | 20 +-- src/index.js | 2 +- 3 files changed, 289 insertions(+), 16 deletions(-) create mode 100644 src/image-preview/index.js diff --git a/src/image-preview/index.js b/src/image-preview/index.js new file mode 100644 index 0000000..88b866e --- /dev/null +++ b/src/image-preview/index.js @@ -0,0 +1,283 @@ +/** + * {图片预览组件} + * @author chensbox + * @date 2023/03/06 15:17:25 + */ + +import { css, html, Component, styleMap, bind, unbind } from '@bd/core' +import '../icon/index.js' + +class ImagePreview extends Component { + static props = { + list: { + type: Array, + default: [], + attribute: false + }, + visible: false, + 'max-zoom': 3, + 'min-zoom': 1 / 3 + } + + static styles = css` + :host { + z-index: 1; + position: fixed; + display: none; + width: 100%; + height: 100%; + top: 0; + left: 0; + background: rgba(0, 0, 0, 0.5); + } + :host([visible]) { + display: block; + } + .wrapper { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + } + img { + user-select: none; + max-height: 100%; + max-width: 100%; + &.show { + display: block; + } + &.hide { + display: none; + } + } + .toggle-btn { + user-select: none; + cursor: pointer; + position: absolute; + display: flex; + align-items: center; + justify-content: center; + opacity: 0.8; + width: 44px; + height: 44px; + font-size: 24px; + color: #fff; + background-color: #606266; + border-color: #fff; + border-radius: 50%; + --size: 22px; + } + .left, + .right { + top: 50%; + transform: translateY(-50%); + } + .left { + left: 5%; + } + .right { + right: 5%; + } + .close { + top: 5%; + right: 5%; + } + .tools-bar { + display: flex; + align-items: center; + justify-content: space-around; + position: absolute; + bottom: 30px; + left: 50%; + width: 282px; + height: 44px; + padding: 0 23px; + background-color: #606266; + border-color: #fff; + color: #e5e5e5; + border-radius: 22px; + transform: translateX(-50%); + --size: 22px; + wc-icon { + cursor: pointer; + } + } + ` + active = 0 + #state = { + scale: 1, + rotate: 0, + duration: 0.2, + x: 0, + y: 0 + } + + pre() { + this.toggleImage(this.active - 1) + } + next() { + this.toggleImage(this.active + 1) + } + toggleImage(index) { + this.active = index + if (this.active < 0) { + this.active = this.list.length - 1 + } + if (this.active > this.list.length - 1) { + this.active = 0 + } + this.resetState() + } + zoomIn() { + this.#state.duration = 0.2 + this.setZoom(this.#state.scale * 1.2) + } + zoomOut() { + this.#state.duration = 0.2 + this.setZoom(this.#state.scale / 1.2) + } + setZoom(val) { + const maxZoom = this['max-zoom'] + const minZoom = this['min-zoom'] + val = Math.max(val, minZoom) + val = Math.min(val, maxZoom) + val = val.toFixed(2) + this.#state.scale = val + this.$requestUpdate() + } + resetState() { + this.#setState({ + scale: 1, + rotate: 0, + duration: 0, + x: 0, + y: 0 + }) + this.$refs.resetBtn.name = + this.$refs.resetBtn.name === 'fullScreen' + ? 'scaleToOriginal' + : 'fullScreen' + this.$requestUpdate() + } + rotateLeft() { + this.setRotate(this.#state.rotate - 90) + } + rotateRight() { + this.setRotate(this.#state.rotate + 90) + } + setRotate(val) { + this.#setState({ + duration: 0.2, + rotate: val + }) + } + + close() { + this.visible = false + } + + #setState(data) { + Object.assign(this.#state, data) + this.$requestUpdate() + } + + mounted() { + this.$on('wheel', e => { + e.preventDefault() + let { scale } = this.#state + this.#setState({ + duration: 0 + }) + scale = e.wheelDelta > 0 ? +scale + 0.08 : scale - 0.08 + this.setZoom(scale) + }) + + bind(this.$refs.images, 'mousedown', e => { + let { clientX: startX, clientY: startY } = e + let { x, y } = this.#state + const onmousemove = bind(document, 'mousemove', e => { + e.preventDefault() + let { clientX, clientY } = e + let deltaX = clientX - startX + let deltaY = clientY - startY + + this.#setState({ + x: deltaX + x, + y: deltaY + y + }) + }) + const onmouseup = bind(document, 'mouseup', _ => { + unbind(document, 'mousemove', onmousemove) + unbind(document, 'mouseup', onmouseup) + }) + }) + } + + render() { + let { scale, rotate, duration, x, y } = this.#state + let styles = styleMap({ + transform: `scale(${scale}) rotate(${rotate}deg) `, + transition: `transform ${duration}s ease-in-out` + }) + let translate = styleMap({ + transform: `translate(${x}px, ${y}px)` + }) + return html` +
+
+ ${this.list.map( + (url, index) => + html`` + )} +
+
+ +
+
+ +
+
+ +
+
+ + + + + +
+
+ ` + } +} + +ImagePreview.reg('image-preview') + +let instance = null + +window.imagePreview = function (options) { + if (!instance) { + instance = new ImagePreview() + document.body.appendChild(instance) + } + + if (Array.isArray(options)) { + instance.list = options + } else { + Object.assign(instance, options) + } + + instance.visible = true + return instance +} diff --git a/src/image/index.js b/src/image/index.js index 97db2ed..7630053 100644 --- a/src/image/index.js +++ b/src/image/index.js @@ -6,7 +6,6 @@ import { css, html, Component, styleMap } from '@bd/core' import '../icon/index.js' -import './preview.js' class Image extends Component { static props = { @@ -17,11 +16,6 @@ class Image extends Component { alt: { type: String, default: null - }, - previewSrcList: { - type: Array, - default: [], - attribute: false } } @@ -60,11 +54,7 @@ class Image extends Component { this.status = 'loaded' this.$requestUpdate() } - onClick() { - if (this.previewSrcList.length) { - window.imagePreview(this.previewSrcList) - } - } + render() { let { lazy, @@ -72,13 +62,13 @@ class Image extends Component { status, fit, alt, - previewSrcList, 'referrer-policy': referrerPolicy } = this + let styles = styleMap({ - 'object-fit': fit, - cursor: previewSrcList.length ? 'pointer' : 'default' + 'object-fit': fit }) + let $slot = '' if (status === 'loading') { @@ -90,7 +80,7 @@ class Image extends Component { } return html` -
+
Date: Fri, 5 May 2023 18:24:34 +0800 Subject: [PATCH 3/3] remove --- src/image/preview.js | 282 ------------------------------------------- 1 file changed, 282 deletions(-) delete mode 100644 src/image/preview.js diff --git a/src/image/preview.js b/src/image/preview.js deleted file mode 100644 index 42120f0..0000000 --- a/src/image/preview.js +++ /dev/null @@ -1,282 +0,0 @@ -/** - * {图片预览组件} - * @author chensbox - * @date 2023/03/06 15:17:25 - */ - -import { css, html, Component, styleMap, bind, unbind } from '@bd/core' -import '../icon/index.js' - -class ImagePreview extends Component { - static props = { - list: { - type: Array, - default: [], - attribute: false - }, - visible: false, - 'max-zoom': 3, - 'min-zoom': 1 / 3 - } - - static styles = css` - :host { - z-index: 1; - position: fixed; - display: none; - width: 100%; - height: 100%; - top: 0; - left: 0; - background: rgba(0, 0, 0, 0.5); - } - :host([visible]) { - display: block; - } - .wrapper { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - } - img { - user-select: none; - max-height: 100%; - max-width: 100%; - &.show { - display: block; - } - &.hide { - display: none; - } - } - .toggle-btn { - user-select: none; - cursor: pointer; - position: absolute; - display: flex; - align-items: center; - justify-content: center; - opacity: 0.8; - width: 44px; - height: 44px; - font-size: 24px; - color: #fff; - background-color: #606266; - border-color: #fff; - border-radius: 50%; - --size: 22px; - } - .left, - .right { - top: 50%; - transform: translateY(-50%); - } - .left { - left: 5%; - } - .right { - right: 5%; - } - .close { - top: 5%; - right: 5%; - } - .tools-bar { - display: flex; - align-items: center; - justify-content: space-around; - position: absolute; - bottom: 30px; - left: 50%; - width: 282px; - height: 44px; - padding: 0 23px; - background-color: #606266; - border-color: #fff; - color: #e5e5e5; - border-radius: 22px; - transform: translateX(-50%); - --size: 22px; - wc-icon { - cursor: pointer; - } - } - ` - active = 0 - #state = { - scale: 1, - rotate: 0, - duration: 0.2, - x: 0, - y: 0 - } - - pre() { - this.toggleImage(this.active - 1) - } - next() { - this.toggleImage(this.active + 1) - } - toggleImage(index) { - this.active = index - if (this.active < 0) { - this.active = this.list.length - 1 - } - if (this.active > this.list.length - 1) { - this.active = 0 - } - this.resetState() - } - zoomIn() { - this.#state.duration = 0.2 - this.setZoom(this.#state.scale * 1.2) - } - zoomOut() { - this.#state.duration = 0.2 - this.setZoom(this.#state.scale / 1.2) - } - setZoom(val) { - const maxZoom = this['max-zoom'] - const minZoom = this['min-zoom'] - val = Math.max(val, minZoom) - val = Math.min(val, maxZoom) - val = val.toFixed(2) - this.#state.scale = val - this.$requestUpdate() - } - resetState() { - this.#setState({ - scale: 1, - rotate: 0, - duration: 0, - x: 0, - y: 0 - }) - this.$refs.resetBtn.name = - this.$refs.resetBtn.name === 'fullScreen' - ? 'scaleToOriginal' - : 'fullScreen' - this.$requestUpdate() - } - rotateLeft() { - this.setRotate(this.#state.rotate - 90) - } - rotateRight() { - this.setRotate(this.#state.rotate + 90) - } - setRotate(val) { - this.#setState({ - duration: 0.2, - rotate: val - }) - } - - close() { - this.visible = false - } - - #setState(data) { - Object.assign(this.#state, data) - this.$requestUpdate() - } - - mounted() { - this.$on('wheel', e => { - e.preventDefault() - let { scale } = this.#state - this.#setState({ - duration: 0 - }) - scale = e.wheelDelta > 0 ? +scale + 0.08 : scale - 0.08 - this.setZoom(scale) - }) - - bind(this.$refs.images, 'mousedown', e => { - let { clientX: startX, clientY: startY } = e - let { x, y } = this.#state - const onmousemove = bind(document, 'mousemove', e => { - e.preventDefault() - let { clientX, clientY } = e - let deltaX = clientX - startX - let deltaY = clientY - startY - - this.#setState({ - x: deltaX + x, - y: deltaY + y - }) - }) - const onmouseup = bind(document, 'mouseup', _ => { - unbind(document, 'mousemove', onmousemove) - unbind(document, 'mouseup', onmouseup) - }) - }) - } - - render() { - let { scale, rotate, duration, x, y } = this.#state - let styles = styleMap({ - transform: `scale(${scale}) rotate(${rotate}deg) `, - transition: `transform ${duration}s ease-in-out` - }) - let translate = styleMap({ - transform: `translate(${x}px, ${y}px)` - }) - return html` -
-
- ${this.list.map( - (url, index) => - html`` - )} -
-
- -
-
- -
-
- -
-
- - - - - -
-
- ` - } -} -ImagePreview.reg('image-preview') - -let instance = null - -window.imagePreview = function (options) { - if (!instance) { - instance = new ImagePreview() - document.body.appendChild(instance) - } - - if (Array.isArray(options)) { - instance.list = options - } else { - Object.assign(instance, options) - } - - instance.visible = true - return instance -}