-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(datepicker): fix datepicker style bug
fix datepicker panel to flex style
- Loading branch information
luchunyu
committed
Nov 14, 2018
1 parent
cb2e611
commit 1c6ebbb
Showing
6 changed files
with
467 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/** | ||
* c-timepicker | ||
*/ | ||
@import url('../../styles/variables.css'); | ||
|
||
.c-timepicker { | ||
display: inline-block; | ||
position: relative; | ||
border-radius: 0.2em; | ||
width: 15em; | ||
|
||
& .c-input-wrap { | ||
width: 100%; | ||
} | ||
|
||
& input { | ||
margin: 0; | ||
width: 100%; | ||
} | ||
|
||
& .c-timepicker__icon { | ||
position: absolute; | ||
right: 0.5em; | ||
top: 50%; | ||
transform: translateY(-50%); | ||
color: color(var(--text-color) l(65%)); | ||
} | ||
|
||
& .c-timepicker__hovericon { | ||
z-index: -1; | ||
opacity: 0; | ||
} | ||
|
||
&:hover .c-timepicker__hovericon + .c-timepicker__icon { | ||
z-index: -1; | ||
opacity: 0; | ||
} | ||
|
||
&:hover .c-timepicker__hovericon { | ||
z-index: 2; | ||
opacity: 1; | ||
} | ||
} | ||
|
||
.c-timepicker__panel { | ||
display: flex; | ||
width: 12em; | ||
|
||
& li { | ||
list-style: none; | ||
color: color(var(--text-color)); | ||
-webkit-box-sizing: content-box; | ||
box-sizing: content-box; | ||
margin: 0; | ||
padding: 0 0 0 12px; | ||
width: 100%; | ||
height: 2em; | ||
line-height: 2em; | ||
text-align: left; | ||
cursor: pointer; | ||
} | ||
|
||
& li.active { | ||
font-weight: bold; | ||
color: color(var(--text-color)); | ||
background: color(var(--gray) l(95%)); | ||
} | ||
} | ||
.c-timepicker__wrap { | ||
display: none; | ||
background: #fff; | ||
border: 1px solid #d4d9db; | ||
overflow: hidden; | ||
|
||
& ul { | ||
list-style: none; | ||
width: 100%; | ||
-webkit-box-sizing: border-box; | ||
box-sizing: border-box; | ||
padding: 0 0 12em; | ||
text-align: center; | ||
margin: 0; | ||
} | ||
|
||
& .c-timepicker__item { | ||
flex: 1; | ||
-webkit-box-sizing: border-box; | ||
box-sizing: border-box; | ||
overflow: hidden; | ||
position: relative; | ||
max-height: 14em; | ||
|
||
&:hover { | ||
overflow-y: auto; | ||
} | ||
} | ||
|
||
& .c-timepicker__item + .c-timepicker__item { | ||
border-left: 1px solid color(var(--gray) l(85%)); | ||
} | ||
} | ||
.show { | ||
display: block; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
--- | ||
title: Timepicker | ||
route: /component/timepicker | ||
layout: component | ||
--- | ||
|
||
# Timepicker | ||
|
||
选择或者输入时间 | ||
|
||
## 基本用法 | ||
|
||
```html | ||
<c-timepicker | ||
v-model="time" | ||
:disabled="disabled" | ||
:defaultValue="defaultTime" | ||
@change="timeChange" | ||
></c-timepicker> | ||
|
||
<script> | ||
export default { | ||
data () { | ||
return { | ||
disabled: false, | ||
time: '', | ||
defaultTime: '12:23:45' | ||
} | ||
}, | ||
methods: { | ||
timeChange (time) { | ||
this.time = time | ||
console.log('time changed') | ||
} | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
## API | ||
|
||
### 属性 | ||
|
||
| 属性 | 类型 | 默认值 | 说明 | | ||
|-----|------|-------|-----| | ||
| placeholder | String | 请选择时间 | 未进行选择时的提示 | | ||
| disabled | Boolean | false | 时间框是否被禁用 | | ||
| format | String | hh:mm:ss | 时间格式,如果使用12小时制,可设置'hh:mm:ss a' | | ||
| size | String | | 尺寸大小 | | ||
| defaultValue | moment | | 默认显示的时间 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
<template lang="pug"> | ||
.c-timepicker(@click="openTimePanel") | ||
.c-timepicker__icon.c-timepicker__hovericon(:class="sizeClassName" | ||
v-if="!disabled") | ||
c-icon(name="x-circle") | ||
.c-timepicker__icon(:class="sizeClassName") | ||
c-icon(type="feather" name="clock") | ||
c-input( | ||
v-model="showValue" | ||
:placeholder="placeholder" | ||
:disabled="disabled" | ||
:size="size" | ||
@change="valueChange" | ||
) | ||
.c-timepicker__wrap( | ||
ref="timepickerPanel" | ||
:class="{show: isOpen}" | ||
) | ||
c-timepanel( | ||
:isShown="isOpen" | ||
:hour="hour" | ||
:minute="minute" | ||
:second="second" | ||
:defaultValue="defaultValue" | ||
@change="timeChange" | ||
) | ||
</template> | ||
|
||
<script> | ||
import { VueTypes } from '@util' | ||
import './index.css' | ||
import { getScrollBarSize } from '@util' | ||
import ZIndexManager from '../../scripts/utils/zIndexManager.js' | ||
export default { | ||
name: 'c-timepicker', | ||
props: { | ||
value: String, | ||
size: String, | ||
format: { | ||
type: String, | ||
default: 'hh:mm:ss' | ||
}, | ||
disabled: Boolean, | ||
placeholder: { | ||
type: String, | ||
default: '请输入时间' | ||
}, | ||
defaultValue: [String, Date] | ||
}, | ||
data () { | ||
return { | ||
timepickerPanel: '', | ||
showValue: '', | ||
isOpen: false, | ||
hour: '', | ||
minute: '', | ||
second: '', | ||
lastValue: '' | ||
} | ||
}, | ||
computed: { | ||
sizeClassName () { | ||
return this.size ? `is-size-${this.size}` : '' | ||
} | ||
}, | ||
watch: { | ||
isOpen () { | ||
if (this.isOpen) { | ||
this.resize() | ||
this.lastValue = this.showValue | ||
window.addEventListener('mouseup', this.onBodyClick, true) | ||
} else { | ||
this.checkValue() | ||
window.removeEventListener('mouseup', this.onBodyClick, true) | ||
} | ||
}, | ||
value (newVal) { | ||
if (newVal !== this.showValue) { | ||
this.showValue = newVal | ||
[this.hour, this.minute, this.second] = this.showValue ? this.showValue.split(':') : ['', '', ''] | ||
} | ||
} | ||
}, | ||
mounted () { | ||
this.showValue = this.value | ||
if (this.showValue) { | ||
[this.hour, this.minute, this.second] = this.showValue.split(':') | ||
} | ||
if (typeof document === 'object') { | ||
this.timepickerPanel = this.$el.querySelector('.c-timepicker__wrap') | ||
document.body.appendChild(this.timepickerPanel) | ||
this.resize() | ||
window.addEventListener('resize', this.resize, false) | ||
} | ||
}, | ||
methods: { | ||
valueChange (value) { | ||
console.log(value) | ||
if (this.showValue) { | ||
[this.hour, this.minute, this.second] = this.showValue.split(':') | ||
} else { | ||
this.hour = '' | ||
this.minute = '' | ||
this.second = '' | ||
} | ||
}, | ||
checkValue () { | ||
console.log('check') | ||
if (this.second > 59 || this.minute > 59 || this.hour > 23) { | ||
this.showValue = this.lastValue | ||
// [this.hour, this.minute, this.second] = this.lastValue.split(':') | ||
} | ||
}, | ||
timeChange ({ hour, minute, second }) { | ||
this.hour = hour | ||
this.minute = minute | ||
this.second = second | ||
this.showValue = `${this.hour}:${this.minute}:${this.second}` | ||
}, | ||
onBodyClick (e) { | ||
const isInPicker = this.$el.contains(e.target) | ||
const isInPanel = this.timepickerPanel.contains(e.target) | ||
if (!isInPicker && !isInPanel) { | ||
this.$emit('change', this.showValue) | ||
this.close() | ||
this.$el.focus() | ||
} | ||
}, | ||
close () { | ||
this.isOpen = false | ||
}, | ||
openTimePanel () { | ||
if (this.disabled) return | ||
this.isOpen = true | ||
console.log('open time') | ||
}, | ||
getStyle () { | ||
const clientRect = this.$el.getBoundingClientRect() | ||
const windowH = window.innerHeight | ||
const windowW = window.innerWidth | ||
const marginTop = 2 | ||
const scrollHeight = document.body.scrollWidth > window.innerWidth ? 20 : 0 | ||
const droplistHeight = this.timepickerPanel.clientHeight | ||
const droplistWidth = this.timepickerPanel.clientWidth | ||
const defaultTop = clientRect.top + clientRect.height + marginTop + window.pageYOffset | ||
const clientHeight = clientRect.height + marginTop | ||
const clientY = clientRect.y | ||
const compTop = windowH - droplistHeight - scrollHeight | ||
const marginRight = getScrollBarSize() + 5 // scrollbar width | ||
const left = droplistWidth + clientRect.left + marginRight + window.pageXOffset > windowW ? windowW - droplistWidth - marginRight : clientRect.left + window.pageXOffset | ||
const top = droplistHeight + clientHeight + clientY + scrollHeight > windowH ? compTop : defaultTop | ||
const zIndex = ZIndexManager.next() | ||
return ` | ||
position: absolute; | ||
top: ${top}px; | ||
left: ${left}px; | ||
z-index: ${zIndex}; | ||
` | ||
}, | ||
resize () { | ||
this.$nextTick(() => { | ||
this.timepickerPanel.style.cssText = this.getStyle() | ||
}) | ||
} | ||
} | ||
} | ||
</script> |
Oops, something went wrong.