Skip to content

Commit 7e38b67

Browse files
committed
3.0.0-beta.9 release
1 parent 1f42ea0 commit 7e38b67

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1308
-120
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
# Change Log
44

5+
# [v3.0.0-beta.9](https://github.com/framework7io/framework7/compare/v3.0.0-beta.8...v3.0.0-beta.9) - June 12, 2018
6+
* Core
7+
* All new Tooltip component
8+
* Template7 update to latest 1.3.6
9+
* Better `@global` parsing in `js` and `js_if` helpers
10+
* Phenome
11+
* Now `f7route` and `f7router` are passed as props for components loaded by router (Page, Routable Tabs, Routable Modals).
12+
* `$f7route` and `$f7router` are now also available only on components loaded by router (Page, Routable Tabs, Routable Modals) and may not be available in custom children components. For children components they must be passed done using props
13+
* Added `tooltip` support for `Link` and `Button` components
14+
515
# [v3.0.0-beta.8](https://github.com/framework7io/framework7/compare/v3.0.0-beta.7...v3.0.0-beta.8) - June 11, 2018
616
* Phenome
717
* Transform object rest spread syntax to Object.assign in Vue/React components

packages/core/components/fab/fab.less

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,10 @@
222222
.fab-label {
223223
position: absolute;
224224
top: 50%;
225-
padding: 4px 8px;
225+
padding: 4px 12px;
226226
border-radius: 4px;
227227
background: #fff;
228-
color: #666;
228+
color: #333;
229229
white-space: nowrap;
230230
transform: translateY(-50%);
231231
pointer-events: none;

packages/core/components/modal/modal-class.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class Modal extends Framework7Class {
2222
modal.useModulesParams(defaults);
2323

2424
modal.params = Utils.extend(defaults, params);
25+
modal.opened = false;
2526

2627
// Install Modules
2728
modal.useModules();
@@ -30,6 +31,7 @@ class Modal extends Framework7Class {
3031
}
3132
onOpen() {
3233
const modal = this;
34+
modal.opened = true;
3335
openedModals.push(modal);
3436
$('html').addClass(`with-modal-${modal.type.toLowerCase()}`);
3537
modal.$el.trigger(`modal:open ${modal.type.toLowerCase()}:open`, modal);
@@ -42,6 +44,7 @@ class Modal extends Framework7Class {
4244
}
4345
onClose() {
4446
const modal = this;
47+
modal.opened = false;
4548
if (!modal.type || !modal.$el) return;
4649
openedModals.splice(openedModals.indexOf(modal), 1);
4750
$('html').removeClass(`with-modal-${modal.type.toLowerCase()}`);
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
import $ from 'dom7';
2+
import Utils from '../../utils/utils';
3+
import Support from '../../utils/support';
4+
import Framework7Class from '../../utils/class';
5+
6+
class Tooltip extends Framework7Class {
7+
constructor(app, params = {}) {
8+
// Extends with open/close Modal methods;
9+
super(app, params);
10+
11+
const tooltip = this;
12+
13+
const defaults = {};
14+
15+
// Extend defaults with modules params
16+
tooltip.useModulesParams(defaults);
17+
18+
tooltip.params = Utils.extend(defaults, params);
19+
20+
const { el } = tooltip.params;
21+
if (!el) return tooltip;
22+
23+
const $el = $(el);
24+
if ($el.length === 0) return tooltip;
25+
26+
const $tooltipEl = $(tooltip.render()).eq(0);
27+
28+
Utils.extend(tooltip, {
29+
app,
30+
$el,
31+
el: $el && $el[0],
32+
$tooltipEl,
33+
tooltipEl: $tooltipEl && $tooltipEl[0],
34+
text: tooltip.params.text || '',
35+
});
36+
37+
$el[0].f7Tooltip = tooltip;
38+
39+
const touchesStart = {};
40+
let isTouched;
41+
function handleTouchStart(e) {
42+
if (isTouched) return;
43+
isTouched = true;
44+
touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
45+
touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
46+
tooltip.show(this);
47+
}
48+
function handleTouchMove(e) {
49+
if (!isTouched) return;
50+
const x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
51+
const y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
52+
const distance = (
53+
((x - touchesStart.x) ** 2) +
54+
((y - touchesStart.y) ** 2)
55+
) ** 0.5;
56+
if (distance > 50) {
57+
isTouched = false;
58+
tooltip.hide();
59+
}
60+
}
61+
function handleTouchEnd() {
62+
if (!isTouched) return;
63+
isTouched = false;
64+
tooltip.hide();
65+
}
66+
function handleMouseEnter() {
67+
tooltip.show(this);
68+
}
69+
function handleMouseLeave() {
70+
tooltip.hide();
71+
}
72+
function handleTransitionEnd() {
73+
if (!$tooltipEl.hasClass('tooltip-in')) {
74+
$tooltipEl.removeClass('tooltip-out').remove();
75+
}
76+
}
77+
78+
tooltip.attachEvents = function attachEvents() {
79+
if (Support.touch) {
80+
const passive = Support.passiveListener ? { passive: true } : false;
81+
$el.on(app.touchEvents.start, handleTouchStart, passive);
82+
app.on('touchmove', handleTouchMove);
83+
app.on('touchend:passive', handleTouchEnd);
84+
return;
85+
}
86+
$tooltipEl.on('transitionend webkitTransitionEnd', handleTransitionEnd);
87+
$el.on('mouseenter', handleMouseEnter);
88+
$el.on('mouseleave', handleMouseLeave);
89+
};
90+
tooltip.detachEvents = function detachEvents() {
91+
if (Support.touch) {
92+
const passive = Support.passiveListener ? { passive: true } : false;
93+
$el.off(app.touchEvents.start, handleTouchStart, passive);
94+
app.off('touchmove', handleTouchMove);
95+
app.off('touchend:passive', handleTouchEnd);
96+
return;
97+
}
98+
$tooltipEl.off('transitionend webkitTransitionEnd', handleTransitionEnd);
99+
$el.off('mouseenter', handleMouseEnter);
100+
$el.off('mouseleave', handleMouseLeave);
101+
};
102+
103+
// Install Modules
104+
tooltip.useModules();
105+
106+
tooltip.init();
107+
108+
return tooltip;
109+
}
110+
position(targetEl) {
111+
const tooltip = this;
112+
const { $tooltipEl, app } = tooltip;
113+
$tooltipEl.css({ left: '', top: '' });
114+
const $targetEl = $(targetEl || tooltip.el);
115+
const [width, height] = [$tooltipEl.width(), $tooltipEl.height()];
116+
117+
$tooltipEl.css({ left: '', top: '' });
118+
119+
let targetWidth;
120+
let targetHeight;
121+
let targetOffsetLeft;
122+
let targetOffsetTop;
123+
if ($targetEl && $targetEl.length > 0) {
124+
targetWidth = $targetEl.outerWidth();
125+
targetHeight = $targetEl.outerHeight();
126+
127+
const targetOffset = $targetEl.offset();
128+
targetOffsetLeft = targetOffset.left - app.left;
129+
targetOffsetTop = targetOffset.top - app.top;
130+
131+
const targetParentPage = $targetEl.parents('.page');
132+
if (targetParentPage.length > 0) {
133+
targetOffsetTop -= targetParentPage[0].scrollTop;
134+
}
135+
}
136+
let [left, top] = [0, 0, 0];
137+
138+
// Top Position
139+
let position = 'top';
140+
141+
if (height < targetOffsetTop) {
142+
// On top
143+
top = targetOffsetTop - height;
144+
} else if (height < app.height - targetOffsetTop - targetHeight) {
145+
// On bottom
146+
position = 'bottom';
147+
top = targetOffsetTop + targetHeight;
148+
} else {
149+
// On middle
150+
position = 'middle';
151+
top = ((targetHeight / 2) + targetOffsetTop) - (height / 2);
152+
if (top <= 0) {
153+
top = 8;
154+
} else if (top + height >= app.height) {
155+
top = app.height - height - 8;
156+
}
157+
}
158+
159+
// Horizontal Position
160+
if (position === 'top' || position === 'bottom') {
161+
left = ((targetWidth / 2) + targetOffsetLeft) - (width / 2);
162+
if (left < 8) left = 8;
163+
if (left + width > app.width) left = app.width - width - 8;
164+
if (left < 0) left = 0;
165+
} else if (position === 'middle') {
166+
left = targetOffsetLeft - width;
167+
if (left < 8 || (left + width > app.width)) {
168+
if (left < 8) left = targetOffsetLeft + targetWidth;
169+
if (left + width > app.width) left = app.width - width - 8;
170+
}
171+
}
172+
173+
// Apply Styles
174+
$tooltipEl.css({ top: `${top}px`, left: `${left}px` });
175+
}
176+
show(aroundEl) {
177+
const tooltip = this;
178+
const { app, $tooltipEl, $el } = tooltip;
179+
app.root.append($tooltipEl);
180+
tooltip.position(aroundEl);
181+
const $aroundEl = $(aroundEl);
182+
$el.trigger('tooltip:show', tooltip);
183+
$tooltipEl.trigger('tooltip:show', tooltip);
184+
if ($aroundEl.length && $aroundEl[0] !== $el[0]) {
185+
$aroundEl.trigger('tooltip:show', tooltip);
186+
}
187+
tooltip.emit('local::show tooltipShow', tooltip);
188+
$tooltipEl.removeClass('tooltip-out').addClass('tooltip-in');
189+
return tooltip;
190+
}
191+
hide() {
192+
const tooltip = this;
193+
const { $tooltipEl, $el } = tooltip;
194+
$el.trigger('tooltip:hide', tooltip);
195+
$tooltipEl.trigger('tooltip:hide', tooltip);
196+
tooltip.emit('local::hide tooltipHide', tooltip);
197+
$tooltipEl.addClass('tooltip-out').removeClass('tooltip-in');
198+
return tooltip;
199+
}
200+
render() {
201+
const tooltip = this;
202+
if (tooltip.params.render) return tooltip.params.render.call(tooltip, tooltip);
203+
const { cssClass, text } = tooltip.params;
204+
return `
205+
<div class="tooltip ${cssClass || ''}">
206+
<div class="tooltip-content">${text || ''}</div>
207+
</div>
208+
`.trim();
209+
}
210+
init() {
211+
const tooltip = this;
212+
tooltip.attachEvents();
213+
}
214+
destroy() {
215+
const tooltip = this;
216+
if (!tooltip.$el || tooltip.destroyed) return;
217+
tooltip.$el.trigger('tooltip:beforedestroy', tooltip);
218+
tooltip.emit('local::beforeDestroy tooltipBeforeDestroy', tooltip);
219+
tooltip.$tooltipEl.remove();
220+
delete tooltip.$el[0].f7Tooltip;
221+
tooltip.detachEvents();
222+
Utils.deleteProps(tooltip);
223+
tooltip.destroyed = true;
224+
}
225+
}
226+
export default Tooltip;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.ios {
2+
@import (multiple) '../../less/colors-ios.less';
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.md {
2+
@import (multiple) '../../less/colors-md.less';
3+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import $ from 'dom7';
2+
import Tooltip from './tooltip-class';
3+
import ConstructorMethods from '../../utils/constructor-methods';
4+
5+
export default {
6+
name: 'tooltip',
7+
static: {
8+
Tooltip,
9+
},
10+
create() {
11+
const app = this;
12+
app.tooltip = ConstructorMethods({
13+
defaultSelector: '.tooltip',
14+
constructor: Tooltip,
15+
app,
16+
domProp: 'f7Tooltip',
17+
});
18+
app.tooltip.show = function show(el) {
19+
const $el = $(el);
20+
if ($el.length === 0) return undefined;
21+
const tooltip = $el[0].f7Tooltip;
22+
if (!tooltip) return undefined;
23+
tooltip.show($el[0]);
24+
return tooltip;
25+
};
26+
app.tooltip.hide = function hide(el) {
27+
const $el = $(el);
28+
if ($el.length === 0) return undefined;
29+
const tooltip = $el[0].f7Tooltip;
30+
if (!tooltip) return undefined;
31+
tooltip.hide();
32+
return tooltip;
33+
};
34+
},
35+
params: {
36+
tooltip: {
37+
el: null,
38+
text: null,
39+
cssClass: null,
40+
render: null,
41+
},
42+
},
43+
on: {
44+
tabMounted(tabEl) {
45+
const app = this;
46+
$(tabEl).find('.tooltip-init').each((index, el) => {
47+
const text = $(el).attr('data-tooltip');
48+
if (!text) return;
49+
app.tooltip.create({ el, text });
50+
});
51+
},
52+
tabBeforeRemove(tabEl) {
53+
$(tabEl).find('.tooltip-init').each((index, el) => {
54+
if (el.f7Tooltip) el.f7Tooltip.destroy();
55+
});
56+
},
57+
pageInit(page) {
58+
const app = this;
59+
page.$el.find('.tooltip-init').each((index, el) => {
60+
const text = $(el).attr('data-tooltip');
61+
if (!text) return;
62+
app.tooltip.create({ el, text });
63+
});
64+
},
65+
pageBeforeRemove(page) {
66+
page.$el.find('.tooltip-init').each((index, el) => {
67+
if (el.f7Tooltip) el.f7Tooltip.destroy();
68+
});
69+
},
70+
},
71+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* === Tooltip === */
2+
.tooltip {
3+
position: absolute;
4+
z-index: 20000;
5+
background: rgba(0,0,0,0.87);
6+
border-radius: 4px;
7+
padding: 8px 16px;
8+
color: #fff;
9+
font-size: 14px;
10+
box-sizing: border-box;
11+
line-height: 1.2;
12+
opacity: 0;
13+
transform: scale(0.9);
14+
transition-duration: 150ms;
15+
transition-property: opacity, transform;
16+
z-index: 99000;
17+
font-weight: 500;
18+
font-weight: 500;
19+
&.tooltip-in {
20+
transform: scale(1);
21+
opacity: 1;
22+
}
23+
&.tooltip-out {
24+
opacity: 0;
25+
transform: scale(1);
26+
}
27+
.device-desktop & {
28+
font-size: 12px;
29+
padding: 6px 8px;
30+
}
31+
}
32+
33+
& when (@includeIosTheme) {
34+
@import url('./tooltip-ios.less');
35+
}
36+
& when (@includeMdTheme) {
37+
@import url('./tooltip-md.less');
38+
}

0 commit comments

Comments
 (0)