Project

General

Profile

1
import { Class, Toggable } from '../mixin/index';
2
import { $, getIndex, toJQuery } from '../util/index';
3

    
4
export default function (UIkit) {
5

    
6
    UIkit.component('accordion', {
7

    
8
        mixins: [Class, Toggable],
9

    
10
        props: {
11
            targets: String,
12
            active: null,
13
            collapsible: Boolean,
14
            multiple: Boolean,
15
            toggle: String,
16
            content: String,
17
            transition: String
18
        },
19

    
20
        defaults: {
21
            targets: '> *',
22
            active: false,
23
            animation: [true],
24
            collapsible: true,
25
            multiple: false,
26
            clsOpen: 'uk-open',
27
            toggle: '> .uk-accordion-title',
28
            content: '> .uk-accordion-content',
29
            transition: 'ease'
30
        },
31

    
32
        computed: {
33

    
34
            items() {
35
                var items = $(this.targets, this.$el);
36
                this._changed = !this._items || items.length !== this._items.length || items.toArray().some((el, i) => el !== this._items.get(i));
37
                return this._items = items;
38
            }
39

    
40
        },
41

    
42
        connected() {
43
            this.$emitSync();
44
        },
45

    
46
        events: [
47

    
48
            {
49

    
50
                name: 'click',
51

    
52
                delegate() {
53
                    return `${this.targets} ${this.$props.toggle}`;
54
                },
55

    
56
                handler(e) {
57
                    e.preventDefault();
58
                    this.toggle(this.items.find(this.$props.toggle).index(e.currentTarget));
59
                }
60

    
61
            }
62

    
63
        ],
64

    
65
        update() {
66

    
67
            if (!this.items || !this._changed) {
68
                return;
69
            }
70

    
71
            this.items.each((i, el) => {
72
                el = $(el);
73
                this.toggleNow(el.find(this.content), el.hasClass(this.clsOpen));
74
            });
75

    
76
            var active = this.active !== false && toJQuery(this.items.eq(Number(this.active))) || !this.collapsible && toJQuery(this.items.eq(0));
77
            if (active && !active.hasClass(this.clsOpen)) {
78
                this.toggle(active, false);
79
            }
80

    
81
        },
82

    
83
        methods: {
84

    
85
            toggle(item, animate) {
86

    
87
                var index = getIndex(item, this.items),
88
                    active = this.items.filter(`.${this.clsOpen}`);
89

    
90
                item = this.items.eq(index);
91

    
92
                item.add(!this.multiple && active).each((i, el) => {
93

    
94
                    el = $(el);
95

    
96
                    var isItem = el.is(item), state = isItem && !el.hasClass(this.clsOpen);
97

    
98
                    if (!state && isItem && !this.collapsible && active.length < 2) {
99
                        return;
100
                    }
101

    
102
                    el.toggleClass(this.clsOpen, state);
103

    
104
                    var content = el[0]._wrapper ? el[0]._wrapper.children().first() : el.find(this.content);
105

    
106
                    if (!el[0]._wrapper) {
107
                        el[0]._wrapper = content.wrap('<div>').parent().attr('hidden', state);
108
                    }
109

    
110
                    this._toggleImmediate(content, true);
111
                    this.toggleElement(el[0]._wrapper, state, animate).then(() => {
112
                        if (el.hasClass(this.clsOpen) === state) {
113

    
114
                            if (!state) {
115
                                this._toggleImmediate(content, false);
116
                            }
117

    
118
                            el[0]._wrapper = null;
119
                            content.unwrap();
120
                        }
121
                    });
122

    
123
                })
124
            }
125

    
126
        }
127

    
128
    });
129

    
130
}
(1-1/28)