Project

General

Profile

1
import { Modal } from '../mixin/index';
2
import { $, docElement, isTouch, query, transitionend } from '../util/index';
3

    
4
var scroll;
5

    
6
export default function (UIkit) {
7

    
8
    UIkit.component('offcanvas', {
9

    
10
        mixins: [Modal],
11

    
12
        args: 'mode',
13

    
14
        props: {
15
            content: String,
16
            mode: String,
17
            flip: Boolean,
18
            overlay: Boolean
19
        },
20

    
21
        defaults: {
22
            content: '.uk-offcanvas-content:first',
23
            mode: 'slide',
24
            flip: false,
25
            overlay: false,
26
            clsPage: 'uk-offcanvas-page',
27
            clsContainer: 'uk-offcanvas-container',
28
            clsPanel: 'uk-offcanvas-bar',
29
            clsFlip: 'uk-offcanvas-flip',
30
            clsContent: 'uk-offcanvas-content',
31
            clsContentAnimation: 'uk-offcanvas-content-animation',
32
            clsSidebarAnimation: 'uk-offcanvas-bar-animation',
33
            clsMode: 'uk-offcanvas',
34
            clsOverlay: 'uk-offcanvas-overlay',
35
            selClose: '.uk-offcanvas-close'
36
        },
37

    
38
        computed: {
39

    
40
            content() {
41
                return $(query(this.$props.content, this.$el));
42
            },
43

    
44
            clsFlip() {
45
                return this.flip ? this.$props.clsFlip : '';
46
            },
47

    
48
            clsOverlay() {
49
                return this.overlay ? this.$props.clsOverlay : '';
50
            },
51

    
52
            clsMode() {
53
                return `${this.$props.clsMode}-${this.mode}`;
54
            },
55

    
56
            clsSidebarAnimation() {
57
                return this.mode === 'none' || this.mode === 'reveal' ? '' : this.$props.clsSidebarAnimation;
58
            },
59

    
60
            clsContentAnimation() {
61
                return this.mode !== 'push' && this.mode !== 'reveal' ? '' : this.$props.clsContentAnimation
62
            },
63

    
64
            transitionElement() {
65
                return this.mode === 'reveal' ? this.panel.parent() : this.panel;
66
            }
67

    
68
        },
69

    
70
        update: {
71

    
72
            write() {
73

    
74
                if (this.isToggled()) {
75

    
76
                    if (this.overlay || this.clsContentAnimation) {
77
                        this.content.width(window.innerWidth - this.scrollbarWidth);
78
                    }
79

    
80
                    if (this.overlay) {
81
                        this.content.height(window.innerHeight);
82
                        scroll && this.content.scrollTop(scroll.y);
83
                    }
84

    
85

    
86
                }
87

    
88
            },
89

    
90
            events: ['resize']
91

    
92
        },
93

    
94
        events: [
95

    
96
            {
97
                name: 'beforeshow',
98

    
99
                self: true,
100

    
101
                handler() {
102

    
103
                    scroll = scroll || {x: window.pageXOffset, y: window.pageYOffset};
104

    
105
                    if (this.mode === 'reveal' && !this.panel.parent().hasClass(this.clsMode)) {
106
                        this.panel.wrap('<div>').parent().addClass(this.clsMode);
107
                    }
108

    
109
                    docElement.css('overflow-y', (!this.clsContentAnimation || this.flip) && this.scrollbarWidth && this.overlay ? 'scroll' : '');
110

    
111
                    this.body.addClass(`${this.clsContainer} ${this.clsFlip} ${this.clsOverlay}`).height();
112
                    this.content.addClass(this.clsContentAnimation);
113
                    this.panel.addClass(`${this.clsSidebarAnimation} ${this.mode !== 'reveal' ? this.clsMode : ''}`);
114
                    this.$el.addClass(this.clsOverlay).css('display', 'block').height();
115

    
116
                }
117
            },
118

    
119
            {
120
                name: 'beforehide',
121

    
122
                self: true,
123

    
124
                handler() {
125
                    this.content.removeClass(this.clsContentAnimation);
126

    
127
                    if (this.mode === 'none' || this.getActive() && this.getActive() !== this) {
128
                        this.panel.trigger(transitionend);
129
                    }
130
                }
131
            },
132

    
133
            {
134
                name: 'hidden',
135

    
136
                self: true,
137

    
138
                handler() {
139

    
140
                    if (this.mode === 'reveal') {
141
                        this.panel.unwrap();
142
                    }
143

    
144
                    if (!this.overlay) {
145
                        scroll = {x: window.pageXOffset, y: window.pageYOffset}
146
                    }
147

    
148
                    this.panel.removeClass(`${this.clsSidebarAnimation} ${this.clsMode}`);
149
                    this.$el.removeClass(this.clsOverlay).css('display', '');
150
                    this.body.removeClass(`${this.clsContainer} ${this.clsFlip} ${this.clsOverlay}`).scrollTop(scroll.y);
151

    
152
                    docElement.css('overflow-y', '');
153
                    this.content.width('').height('');
154

    
155
                    window.scrollTo(scroll.x, scroll.y);
156

    
157
                    scroll = null;
158

    
159
                }
160
            },
161

    
162
            {
163
                name: 'swipeLeft swipeRight',
164

    
165
                handler(e) {
166

    
167
                    if (this.isToggled() && isTouch(e) && (e.type === 'swipeLeft' && !this.flip || e.type === 'swipeRight' && this.flip)) {
168
                        this.hide();
169
                    }
170

    
171
                }
172
            }
173

    
174
        ]
175

    
176
    });
177

    
178
}
(19-19/28)