增加slider组件

master
chenjiajian 2023-03-23 11:41:08 +08:00
parent cc99526b36
commit 32f89ab889
2 changed files with 278 additions and 0 deletions

113
src/form/select.js Normal file
View File

@ -0,0 +1,113 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/03/21 16:14:10
*/
import { nextTick, css, html, Component } from '@bd/core'
import '../icon/index.js'
import '../form/input.js'
import '../scroll/index.js'
class Select extends Component {
static props = {
value: {
type: Array,
default: [],
attribute: false,
observer() {
// this.#updateChildrenStat()
}
},
disabled: false,
readonly: false
}
static styles = css`
.icon {
margin-right: 10px;
--size: 14px;
line-height: 100%;
transform: rotate(90deg);
transition: transform 0.2s ease-in-out;
}
.input {
width: 200px;
}
.select {
display: inline-block;
position: relative;
}
.select:focus-within {
.icon {
transform: rotate(-90deg);
}
.option-list {
height: 150px;
border: 1px solid #e4e7ed;
}
}
.option-list {
position: absolute;
margin: 5px 0;
top: 110%;
height: 150px;
width: 100%;
z-index: 1001;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
transition: height 0.2s ease-in-out;
&:after {
// content: '';
// position: absolute;
// left: 20%;
// top: -16px;
// border: 8px solid #fff;
// border-top-color: transparent;
// border-right-color: transparent;
// border-left-color: transparent;
}
}
`
mounted() {
console.log('select mounted')
}
render() {
return html`
<div class="select">
<wc-input readonly class="input">
<wc-icon slot="append" class="icon" name="right" / >
</wc-input>
<wc-scroll class="option-list">
<slot />
</wc-scroll>
</div>
`
}
}
class Option extends Component {
static props = {
value: '2'
}
static styles = [css``]
mounted() {
// console.log(this.value)
// console.log(this.$refs)
// console.log(this.root.innerHTML)
console.log('option mounted')
}
onclick() {
console.log(11)
}
render() {
return html` <div ref="li">${this.value}</div> `
}
}
Select.reg('select')
Option.reg('option')

165
src/slider/index.js Normal file
View File

@ -0,0 +1,165 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/03/21 16:14:10
*/
import { nextTick, css, bind, unbind, html, Component } from '@bd/core'
class Slider extends Component {
static props = {
value: {
type: Number,
default: 0,
observer() {}
},
max: null,
min: null,
step: 1,
disabled: false,
readonly: false,
vertical: false,
'show-tooltip': true
}
static styles = css`
:host {
display: block;
width: 100%;
height: 38px;
}
.slider {
position: relative;
display: flex;
align-items: center;
height: 100%;
}
.runway {
flex: 1;
position: relative;
height: 6px;
background: #e4e7ed;
border-radius: 99rem;
cursor: pointer;
.bar {
flex: 1;
pointer-events: none;
position: absolute;
height: 100%;
width: 0%;
border-radius: 99rem;
background: #409eff;
}
}
.dot-wrapper {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
height: 36px;
width: 36px;
top: 50%;
left: 0%;
cursor: grab;
transform: translate(-50%, -50%);
.dot {
height: 20px;
width: 20px;
border-radius: 50%;
border: 2px solid #409eff;
background: #fff;
transition: transform 0.2s ease-in-out;
&:hover {
transform: scale(1.2);
}
}
}
.tips {
position: absolute;
top: -100%;
border-radius: 4px;
padding: 10px;
z-index: 2000;
font-size: 12px;
line-height: 1.2;
min-width: 10px;
word-wrap: break-word;
color: #fff;
background: #303133;
transform: translateX(-50%);
&:after {
position: absolute;
border: 6px solid transparent;
bottom: -12px;
left: 50%;
transform: translateX(-50%);
content: '';
border-top-color: #303133;
}
}
.cursor-default {
cursor: default;
}
`
mounted() {
console.log('slider mounted')
console.log(this.$refs, 'refs')
this.$bar = this.root.querySelector('.bar')
this.$dotWrap = this.root.querySelector('.dot-wrapper')
this.$runway = this.root.querySelector('.runway')
this.$tips = this.root.querySelector('.tips')
}
onMousedown(e) {
console.log(e)
document.documentElement.classList.toggle('cursor-default')
const start = e.clientX
const preValue = this.value
const onMousemove = bind(document, 'mousemove', e => {
const distance = e.clientX - start
const diff = Math.round((distance / this.$runway.clientWidth) * 100)
let newValue = preValue + diff
newValue = Math.floor(newValue)
if (newValue < 0) {
newValue = 0
}
if (newValue > 100) {
newValue = 100
}
this.$bar.style.width = newValue + '%'
this.$dotWrap.style.left = newValue + '%'
this.$tips.style.left = newValue + '%'
this.value = newValue
})
bind(document, 'mouseup', e => {
unbind(document, 'mousemove', onMousemove)
document.documentElement.classList.toggle('cursor-default')
})
}
onClick(e) {
console.log(e)
const { clientWidth } = e.target
const { offsetX } = e
this.value = Math.floor((offsetX / clientWidth) * 100)
const barWidth = `${this.value}%`
this.$bar.style.width = barWidth
this.$dotWrap.style.left = barWidth
this.$tips.style.left = barWidth
}
render() {
return html`<div class="slider" ref="slider">
<div class="runway" @click=${this.onClick}>
<div class="bar"></div>
<div class="dot-wrapper" @mousedown=${this.onMousedown}>
<div class="dot" ref="dot"></div>
</div>
</div>
<div class="tips">${this.value}</div>
</div>`
}
}
Slider.reg('slider')