Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev zhiqiang #2

Merged
merged 4 commits into from
Feb 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions example/Main.san
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<hr>
<san-notrecommended />
<hr>
<san-appbar
title="{= bar =}"
<san-appbar
title="{= bar =}"
prop-themeClass="test"
showLeftIcon="1"
on-appbarlefticonclick="labelClicker($event)"
Expand Down Expand Up @@ -52,6 +52,26 @@
<san-slider max="100" min="1" step="1" value="4" disable="0">
</san-slider>
</div>
<popover placement="left" trigger="{{triggerLeft}}" triggerOperation="click" on-show="onShow()" on-hide="onHide()">
<p>This is a popover!</p>
<p>popover content!</p>
</popover>
<popover placement="top" trigger="{{triggerTop}}" triggerOperation="click">
<p>This is a popover!</p>
<p>popover content!</p>
</popover>
<popover placement="bottom" trigger="{{triggerBottom}}" showArrow="false" triggerOperation="click">
<p>This is a popover!</p>
<p>popover content!</p>
</popover>
<popover placement="right" trigger="{{triggerRight}}" triggerOperation="click">
<p>This is a popover!</p>
<p>popover content!</p>
</popover>
<popover trigger="{{triggerFocus}}" triggerOperation="focus">
<p>This is a popover!</p>
<p>popover content!</p>
</popover>
</div>
</template>

Expand All @@ -62,6 +82,7 @@ import AppBar from '../src/AppBar';
import {Card, CardHeader, CardMedia, CardTitle, CardText, CardActions} from '../src/Card';
import Slider from '../src/Slider';
import Icon from '../src/Icon';
import Popover from '../src/Popover';

export default {
components: {
Expand All @@ -75,16 +96,28 @@ export default {
'san-cardtext': CardText,
'san-cardactions': CardActions,
'san-slider': Slider,
'icon': Icon
'icon': Icon,
'popover': Popover
},
initData() {
return {
bar: 'Title',
text: '散落在指尖的阳光,我试着轻轻抓住光影的踪迹,它却在眉宇间投下一片淡淡的阴影。 调皮的阳光掀动了四月的心帘,温暖如约的歌声渐起。 似乎在诉说着,我也可以在漆黑的角落里,找到阴影背后的阳光, 找到阳光与阴影奏出和谐的旋律。我要用一颗敏感赤诚的心迎接每一缕滑过指尖的阳光'
text: '散落在指尖的阳光,我试着轻轻抓住光影的踪迹,它却在眉宇间投下一片淡淡的阴影。 调皮的阳光掀动了四月的心帘,温暖如约的歌声渐起。 似乎在诉说着,我也可以在漆黑的角落里,找到阴影背后的阳光, 找到阳光与阴影奏出和谐的旋律。我要用一颗敏感赤诚的心迎接每一缕滑过指尖的阳光',
triggerLeft: document.getElementById('popover-left'),
triggerTop: document.getElementById('popover-top'),
triggerBottom: document.getElementById('popover-bottom'),
triggerRight: document.getElementById('popover-right'),
triggerFocus: document.getElementById('input')
}
},
labelClicker(data) {
console.log(data);
},
onShow() {
console.log('popover show');
},
onHide() {
console.log('popover hide');
}
}
</script>
Expand Down
7 changes: 7 additions & 0 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
</head>
<body>
<div id="root"></div>
<div class="wrapper">
<button id="popover-left">我是左侧的popover</button>
<button id="popover-top">我是顶部的popover</button>
<button id="popover-bottom">我是底部的popover(不显示小箭头)</button>
<button id="popover-right">我是右侧的popover</button>
<input id="input" name="" placeholder="我是focus出现的popover">
</div>
<script src="/index.js" replace="1"></script>
</body>
</html>
204 changes: 204 additions & 0 deletions src/Popover/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/**
* @file Popover/index.js Popover component for San
* @author zhangzhiqiang(zhiqiangzhang37@gmail.com)
*/

import './index.styl';
import san from 'san';
import template from './index.tpl';

const openKey = 'open';
const animationKey = 'animation';
const showArrowKey = 'showArrow';
const placementKey = 'placement';
const triggerKey = 'trigger';
const triggerOperationKey = 'triggerOperation';
const defaultPlacement = 'bottom';
const defaultTriggerOperation = 'click';
const placementType = [defaultPlacement, 'right', 'top', 'left'];
const triggerOperationType = [defaultTriggerOperation, 'focus'];

function getOffset(ele) {

if (!ele) {
return {};
}

let res = {
offsetTop: 0,
offsetLeft: 0,
offsetWidth: ele.offsetWidth,
offsetHeight: ele.offsetHeight
};
while (ele) {
res.offsetTop += ele.offsetTop;
res.offsetLeft += ele.offsetLeft;
ele = ele.offsetParent;
}

return res;
}

export default san.defineComponent({

template,

initData() {
// default data
return {
[openKey]: false,
[showArrowKey]: true,
[animationKey]: true,
[placementKey]: defaultPlacement,
[triggerOperationKey]: defaultTriggerOperation
};
},
inited() {
// 处理一些初始化数据
this.transBoolean(animationKey);
this.transBoolean(showArrowKey);
this.transBoolean(openKey);
this.compatErrorData(triggerOperationKey, triggerOperationType);
this.compatErrorData(placementKey, placementType);
},
created() {
document.body.appendChild(this.el);
// 默认显示
if (this.data.get(openKey)) {
this.show();
}
this.bindEvent();
},
show() {
let triggerEle = this.getTriggerEle();

if (!triggerEle) {
return;
}

this.data.set(openKey, true);
this.setPosition(triggerEle);
this.fire('show');
},
setPosition(triggerEle) {
let posTop;
let posLeft;
let placement = this.data.get(placementKey);
let {
offsetTop: triggerEleOffsetTop,
offsetLeft: triggerEleOffsetLeft,
offsetWidth: triggerEleOffsetWidth,
offsetHeight: triggerEleOffsetHeight
} = getOffset(triggerEle);
let {
offsetWidth: popoverEleOffsetWidth,
offsetHeight: popoverEleOffsetHeight
} = getOffset(this.el);
let horizonPosTop = triggerEleOffsetTop + triggerEleOffsetHeight / 2 - popoverEleOffsetHeight / 2;
let verticalPosLeft = triggerEleOffsetLeft + triggerEleOffsetWidth / 2 - popoverEleOffsetWidth / 2;
switch (placement) {
case 'right':
posLeft = triggerEleOffsetLeft + triggerEleOffsetWidth;
posTop = horizonPosTop;
break;
case 'bottom':
posLeft = verticalPosLeft;
posTop = triggerEleOffsetTop + triggerEleOffsetHeight;
break;
case 'left':
posLeft = triggerEleOffsetLeft - popoverEleOffsetWidth;
posTop = horizonPosTop;
break;
default:
posLeft = verticalPosLeft;
posTop = triggerEleOffsetTop - popoverEleOffsetHeight;
break;
}
this.data.set('posLeft', posLeft);
this.data.set('posTop', posTop);
},
hide() {
this.data.set(openKey, false);
this.fire('hide');
},
toggle() {
let isOpen = this.data.get(openKey);
if (isOpen) {
this.hide();
}
else {
this.show();
}
},
bindEvent() {
let me = this;
let triggerEle = me.getTriggerEle();

if (!triggerEle) {
return;
}

let hide = me.hide.bind(me);
let triggerOperation = me.data.get(triggerOperationKey);
// 注册显示popover的事件
triggerEle.addEventListener(triggerOperation, () => {
if (!me.data.get(openKey)) {
me.show();
me.data.clickNoHide = true;
}
});

// 注册隐藏popover事件
if (triggerOperation === 'focus') {
triggerEle.addEventListener('blur', hide);
}
else {
// 除了点击popover浮层,点击其他地方都隐藏浮层
me.el.addEventListener(defaultTriggerOperation, () => {
me.data.clickNoHide = true;
});
document.addEventListener(defaultTriggerOperation, e => {
if (!me.data.clickNoHide && me.data.get(openKey)) {
hide();
}
me.data.clickNoHide = false;
});
}

},
getTriggerEle() {
let triggerEle = this.data.get(triggerKey);

if (!triggerEle || !triggerEle.tagName) {
console.error('Please provide trigger');
return;
}

return triggerEle;
},

/**
* 布尔值转换,字符串false转换为布尔值false,其他则按正常转换进行转换
*
* @param {string} key 要转换的数据key
*/
transBoolean(key) {
let value = this.data.get(key);
this.data.set(key, value === 'false' ? false : !!value);
},

/**
* 数据容错,不在可支持列表里就兼容为默认值
*
* @param {string} key 要容错的数据key
* @param {Array} supportList 数据支持列表
*/
compatErrorData(key, supportList) {

let value = this.data.get(key);

if (supportList) {
this.data.set(key, supportList.indexOf(value) !== -1 ? value : supportList[0]);
}
}
});
75 changes: 75 additions & 0 deletions src/Popover/index.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
$arrow-width=11
$border-color=#ccc

.sm-popover
border: solid 1px $border-color
box-shadow: 0 5px 10px 1px #bbb
opacity: 0
border-radius: 5px
padding: 8px
position: absolute
display: inline-block
z-index: 999
background-color: #fff
&.hide
left: -999999999px !important
&.show
opacity: 1
left: 0
&.animation
transition: ease .5s opacity
.arrow
width: 0
height: 0
border: solid ($arrow-width)px transparent
position: absolute
&:after
position: absolute
content: ''
width: 0
height: 0
border: solid ($arrow-width - 1)px transparent
&-bottom,
&-top
border-top-width: 0
border-bottom-color: $border-color
top: -($arrow-width)px
left: 50%
margin-left: -($arrow-width)px
&:after
border-top-width: 0
border-bottom-color: #fff
left: -($arrow-width - 1)px
bottom: -($arrow-width)px
&-left,
&-right
border-right-width: 0
border-left-color: $border-color
top: 50%
right: -($arrow-width)px
margin-top: -($arrow-width)px
&:after
border-right-width: 0
border-left-color: #fff
left: -($arrow-width)px
bottom: -($arrow-width - 1)px


&.top
margin-top: -($arrow-width)px
.arrow
transform: rotate(180deg)
top: initial
bottom: -($arrow-width)px
&.right
margin-left: ($arrow-width)px
.arrow
transform: rotate(180deg)
right: initial
left: -($arrow-width)px
&.bottom
margin-top: ($arrow-width)px
&.left
margin-left: -($arrow-width)px
&.no-arrow
margin: 0
7 changes: 7 additions & 0 deletions src/Popover/index.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div class="sm-popover {{ placement }}{{ !open | yesToBe(' hide') }}{{ open | yesToBe(' show') }}{{ animation | yesToBe(' animation') }}{{ !showArrow | yesToBe(' no-arrow') }}"
style="left: {{ posLeft }}px; top: {{ posTop }}px;">
<div san-if="{{ showArrow }}" class="arrow arrow-{{ placement }}"></div>
<div class="inner">
<slot></slot>
</div>
</div>
4 changes: 4 additions & 0 deletions tool/webpack.base.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ export default {
limit: 100000,
name: assetsPath('fonts/[name].[hash:7].[ext]')
}
},
{
test: /\.(html|tpl)(\?.*)?$/,
loader: 'html-loader'
}
]
},
Expand Down