@cahyo-dimas/freeday 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +447 -0
- package/LICENSE +21 -0
- package/README.md +205 -0
- package/adapters/blazor/freeday-blazor.js +79 -0
- package/adapters/react/components/FdyAutocomplete.tsx +159 -0
- package/adapters/react/components/FdyCascade.tsx +230 -0
- package/adapters/react/components/FdyCfl.tsx +362 -0
- package/adapters/react/components/FdyChart.tsx +69 -0
- package/adapters/react/components/FdyCombo.tsx +166 -0
- package/adapters/react/components/FdyDateRange.tsx +66 -0
- package/adapters/react/components/FdyDatepicker.tsx +354 -0
- package/adapters/react/index.d.ts +37 -0
- package/adapters/react/index.js +9 -0
- package/adapters/react/tsconfig.json +14 -0
- package/adapters/react/useFreeday.js +44 -0
- package/adapters/react/usePopover.ts +64 -0
- package/adapters/vue/components/FdyAutocomplete.vue +174 -0
- package/adapters/vue/components/FdyCascade.vue +241 -0
- package/adapters/vue/components/FdyCfl.vue +354 -0
- package/adapters/vue/components/FdyChart.vue +89 -0
- package/adapters/vue/components/FdyCombo.vue +232 -0
- package/adapters/vue/components/FdyDateRange.vue +78 -0
- package/adapters/vue/components/FdyDatepicker.vue +333 -0
- package/adapters/vue/index.d.ts +44 -0
- package/adapters/vue/index.js +8 -0
- package/adapters/vue/useFreeday.js +44 -0
- package/adapters/vue/usePopover.ts +78 -0
- package/dist/freeday-autocomplete.js +135 -0
- package/dist/freeday-breakpoint.js +51 -0
- package/dist/freeday-carousel.js +111 -0
- package/dist/freeday-cascade.js +256 -0
- package/dist/freeday-cfl.js +213 -0
- package/dist/freeday-chart.js +403 -0
- package/dist/freeday-chip.js +83 -0
- package/dist/freeday-datepicker.js +321 -0
- package/dist/freeday-datetime.js +59 -0
- package/dist/freeday-drawer.js +43 -0
- package/dist/freeday-form.js +181 -0
- package/dist/freeday-mask.js +114 -0
- package/dist/freeday-menu.js +93 -0
- package/dist/freeday-popover.js +69 -0
- package/dist/freeday-rating.js +50 -0
- package/dist/freeday-select.js +194 -0
- package/dist/freeday-slider.js +34 -0
- package/dist/freeday-stepper.js +90 -0
- package/dist/freeday-table.js +475 -0
- package/dist/freeday-tabs.js +68 -0
- package/dist/freeday-timepicker.js +180 -0
- package/dist/freeday-toast.js +84 -0
- package/dist/freeday-tree.js +94 -0
- package/dist/freeday-upload.js +206 -0
- package/dist/freeday.bundle.css +1352 -0
- package/dist/freeday.css +1007 -0
- package/dist/freeday.js +3632 -0
- package/dist/freeday.tokens.css +343 -0
- package/package.json +72 -0
- package/src/base.css +20 -0
- package/src/components/.gitkeep +0 -0
- package/src/components/accordion.css +13 -0
- package/src/components/alert.css +18 -0
- package/src/components/app-shell.css +88 -0
- package/src/components/appbar.css +15 -0
- package/src/components/autocomplete.css +12 -0
- package/src/components/avatar.css +8 -0
- package/src/components/badge.css +27 -0
- package/src/components/breadcrumb.css +9 -0
- package/src/components/breakpoints.css +15 -0
- package/src/components/button.css +58 -0
- package/src/components/card.css +9 -0
- package/src/components/carousel.css +17 -0
- package/src/components/cascade.css +36 -0
- package/src/components/cfl.css +28 -0
- package/src/components/chart.css +55 -0
- package/src/components/chip.css +18 -0
- package/src/components/combo.css +27 -0
- package/src/components/datepicker.css +44 -0
- package/src/components/datetimepicker.css +8 -0
- package/src/components/description-list.css +6 -0
- package/src/components/divider.css +3 -0
- package/src/components/drawer.css +25 -0
- package/src/components/file-upload.css +34 -0
- package/src/components/filterbar.css +25 -0
- package/src/components/form-grid.css +8 -0
- package/src/components/input-group.css +22 -0
- package/src/components/input.css +13 -0
- package/src/components/kbd.css +2 -0
- package/src/components/menu.css +28 -0
- package/src/components/modal.css +22 -0
- package/src/components/pagination.css +8 -0
- package/src/components/progress.css +7 -0
- package/src/components/rating.css +10 -0
- package/src/components/selection.css +25 -0
- package/src/components/skeleton.css +7 -0
- package/src/components/slider.css +12 -0
- package/src/components/spinner.css +6 -0
- package/src/components/states.css +8 -0
- package/src/components/stepper.css +21 -0
- package/src/components/table.css +55 -0
- package/src/components/tabs.css +10 -0
- package/src/components/timeline.css +12 -0
- package/src/components/timepicker.css +22 -0
- package/src/components/toast.css +17 -0
- package/src/components/tooltip.css +6 -0
- package/src/components/tree.css +21 -0
- package/src/freeday-autocomplete.js +135 -0
- package/src/freeday-breakpoint.js +51 -0
- package/src/freeday-carousel.js +111 -0
- package/src/freeday-cascade.js +256 -0
- package/src/freeday-cfl.js +213 -0
- package/src/freeday-chart.js +403 -0
- package/src/freeday-chip.js +83 -0
- package/src/freeday-datepicker.js +321 -0
- package/src/freeday-datetime.js +59 -0
- package/src/freeday-drawer.js +43 -0
- package/src/freeday-form.js +181 -0
- package/src/freeday-mask.js +114 -0
- package/src/freeday-menu.js +93 -0
- package/src/freeday-popover.js +69 -0
- package/src/freeday-rating.js +50 -0
- package/src/freeday-select.js +194 -0
- package/src/freeday-slider.js +34 -0
- package/src/freeday-stepper.js +90 -0
- package/src/freeday-table.js +475 -0
- package/src/freeday-tabs.js +68 -0
- package/src/freeday-timepicker.js +180 -0
- package/src/freeday-toast.js +84 -0
- package/src/freeday-tree.js +94 -0
- package/src/freeday-upload.js +206 -0
- package/tokens/breakpoints.mjs +4 -0
- package/tokens/tokens.json +123 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/* Freeday — combobox enhancer (optional, zero-dependency).
|
|
2
|
+
* Implements the WAI-ARIA APG "select-only combobox" pattern for every
|
|
3
|
+
* [data-fdy-combo] on the page. Progressive enhancement: the markup is the
|
|
4
|
+
* component, this script wires behavior. In a Vue/React/Blazor app you would
|
|
5
|
+
* bind your own state instead — this is the framework-agnostic reference.
|
|
6
|
+
*
|
|
7
|
+
* Expected markup:
|
|
8
|
+
* <div class="fdy-combo" data-fdy-combo data-value="x">
|
|
9
|
+
* <button type="button" class="fdy-combo__button" role="combobox"
|
|
10
|
+
* aria-haspopup="listbox" aria-expanded="false"
|
|
11
|
+
* aria-labelledby="LBL VAL">
|
|
12
|
+
* <span class="fdy-combo__value" id="VAL">Label</span>
|
|
13
|
+
* </button>
|
|
14
|
+
* <ul class="fdy-combo__listbox" role="listbox" hidden>
|
|
15
|
+
* <li class="fdy-combo__option" role="option" data-value="x"
|
|
16
|
+
* aria-selected="true"><span class="fdy-combo__check">✓</span>Label</li>
|
|
17
|
+
* </ul>
|
|
18
|
+
* </div>
|
|
19
|
+
*
|
|
20
|
+
* Emits a bubbling "fdy-change" CustomEvent on the root with detail.value.
|
|
21
|
+
*/
|
|
22
|
+
(function () {
|
|
23
|
+
'use strict';
|
|
24
|
+
|
|
25
|
+
var seq = 0;
|
|
26
|
+
var openClose = null; // close() of the currently-open combo, or null
|
|
27
|
+
|
|
28
|
+
function optionLabel(opt) {
|
|
29
|
+
var check = opt.querySelector('.fdy-combo__check');
|
|
30
|
+
var node = check && check.nextSibling ? check.nextSibling.textContent : opt.textContent;
|
|
31
|
+
return (node || '').trim();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function initCombo(root) {
|
|
35
|
+
if (root.dataset.fdyComboReady === '1') return; // idempotent
|
|
36
|
+
var button = root.querySelector('.fdy-combo__button');
|
|
37
|
+
var listbox = root.querySelector('.fdy-combo__listbox');
|
|
38
|
+
var valueEl = root.querySelector('.fdy-combo__value');
|
|
39
|
+
var options = Array.prototype.slice.call(root.querySelectorAll('.fdy-combo__option'));
|
|
40
|
+
if (!button || !listbox || !valueEl || options.length === 0) return;
|
|
41
|
+
root.dataset.fdyComboReady = '1';
|
|
42
|
+
|
|
43
|
+
seq += 1;
|
|
44
|
+
if (!listbox.id) listbox.id = 'fdy-combo-list-' + seq;
|
|
45
|
+
button.setAttribute('aria-controls', listbox.id);
|
|
46
|
+
options.forEach(function (opt, i) {
|
|
47
|
+
if (!opt.id) opt.id = listbox.id + '-opt-' + i;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
var typed = '';
|
|
51
|
+
var typedTimer = null;
|
|
52
|
+
|
|
53
|
+
function highlightedIndex() {
|
|
54
|
+
for (var i = 0; i < options.length; i++) {
|
|
55
|
+
if (options[i].classList.contains('is-highlighted')) return i;
|
|
56
|
+
}
|
|
57
|
+
return -1;
|
|
58
|
+
}
|
|
59
|
+
function setHighlight(i) {
|
|
60
|
+
options.forEach(function (opt, idx) {
|
|
61
|
+
opt.classList.toggle('is-highlighted', idx === i);
|
|
62
|
+
});
|
|
63
|
+
if (i >= 0) {
|
|
64
|
+
button.setAttribute('aria-activedescendant', options[i].id);
|
|
65
|
+
options[i].scrollIntoView({ block: 'nearest' });
|
|
66
|
+
} else {
|
|
67
|
+
button.removeAttribute('aria-activedescendant');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function isOpen() {
|
|
71
|
+
return !listbox.hidden;
|
|
72
|
+
}
|
|
73
|
+
var _pop = null;
|
|
74
|
+
function popCtl() { if (_pop === null && window.FreedayPopover) _pop = window.FreedayPopover.attach(listbox, button); return _pop; }
|
|
75
|
+
function open() {
|
|
76
|
+
if (openClose && openClose !== close) openClose();
|
|
77
|
+
var p = popCtl(); if (p) p.show(); else listbox.hidden = false;
|
|
78
|
+
button.classList.add('is-open');
|
|
79
|
+
button.setAttribute('aria-expanded', 'true');
|
|
80
|
+
var selected = options.findIndex(function (opt) {
|
|
81
|
+
return opt.getAttribute('aria-selected') === 'true';
|
|
82
|
+
});
|
|
83
|
+
setHighlight(selected < 0 ? 0 : selected);
|
|
84
|
+
openClose = close;
|
|
85
|
+
}
|
|
86
|
+
function close() {
|
|
87
|
+
var p = popCtl(); if (p) p.hide(); else listbox.hidden = true;
|
|
88
|
+
button.classList.remove('is-open');
|
|
89
|
+
button.setAttribute('aria-expanded', 'false');
|
|
90
|
+
button.removeAttribute('aria-activedescendant');
|
|
91
|
+
setHighlight(-1);
|
|
92
|
+
if (openClose === close) openClose = null;
|
|
93
|
+
}
|
|
94
|
+
function choose(opt) {
|
|
95
|
+
options.forEach(function (other) {
|
|
96
|
+
var on = other === opt;
|
|
97
|
+
other.setAttribute('aria-selected', on ? 'true' : 'false');
|
|
98
|
+
var check = other.querySelector('.fdy-combo__check');
|
|
99
|
+
if (check) check.textContent = on ? '✓' : '';
|
|
100
|
+
});
|
|
101
|
+
root.setAttribute('data-value', opt.getAttribute('data-value') || '');
|
|
102
|
+
valueEl.textContent = optionLabel(opt);
|
|
103
|
+
valueEl.classList.remove('fdy-combo__value--placeholder');
|
|
104
|
+
root.dispatchEvent(new CustomEvent('fdy-change', {
|
|
105
|
+
bubbles: true,
|
|
106
|
+
detail: { value: opt.getAttribute('data-value') }
|
|
107
|
+
}));
|
|
108
|
+
close();
|
|
109
|
+
button.focus();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
button.addEventListener('click', function () {
|
|
113
|
+
isOpen() ? close() : open();
|
|
114
|
+
});
|
|
115
|
+
// Pressing an option must not blur the button: a blur fires the focusout
|
|
116
|
+
// handler below, which closes the listbox before the option's click lands —
|
|
117
|
+
// so the pick is lost (real mouse only; synthetic .click() never blurs).
|
|
118
|
+
// preventDefault on mousedown keeps focus on the button without blocking click.
|
|
119
|
+
listbox.addEventListener('mousedown', function (e) { e.preventDefault(); });
|
|
120
|
+
options.forEach(function (opt, i) {
|
|
121
|
+
opt.addEventListener('click', function () { choose(opt); });
|
|
122
|
+
opt.addEventListener('mousemove', function () { setHighlight(i); });
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
root.addEventListener('keydown', function (e) {
|
|
126
|
+
var hi = highlightedIndex();
|
|
127
|
+
switch (e.key) {
|
|
128
|
+
case 'ArrowDown':
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
isOpen() ? setHighlight((hi + 1) % options.length) : open();
|
|
131
|
+
break;
|
|
132
|
+
case 'ArrowUp':
|
|
133
|
+
e.preventDefault();
|
|
134
|
+
isOpen() ? setHighlight((hi - 1 + options.length) % options.length) : open();
|
|
135
|
+
break;
|
|
136
|
+
case 'Home':
|
|
137
|
+
if (isOpen()) { e.preventDefault(); setHighlight(0); }
|
|
138
|
+
break;
|
|
139
|
+
case 'End':
|
|
140
|
+
if (isOpen()) { e.preventDefault(); setHighlight(options.length - 1); }
|
|
141
|
+
break;
|
|
142
|
+
case 'Enter':
|
|
143
|
+
case ' ':
|
|
144
|
+
e.preventDefault();
|
|
145
|
+
if (isOpen() && hi >= 0) choose(options[hi]); else open();
|
|
146
|
+
break;
|
|
147
|
+
case 'Escape':
|
|
148
|
+
if (isOpen()) { e.preventDefault(); close(); button.focus(); }
|
|
149
|
+
break;
|
|
150
|
+
case 'Tab':
|
|
151
|
+
if (isOpen()) close();
|
|
152
|
+
break;
|
|
153
|
+
default:
|
|
154
|
+
if (e.key.length === 1 && /\S/.test(e.key) && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
155
|
+
typed += e.key.toLowerCase();
|
|
156
|
+
clearTimeout(typedTimer);
|
|
157
|
+
typedTimer = setTimeout(function () { typed = ''; }, 500);
|
|
158
|
+
var match = options.findIndex(function (opt) {
|
|
159
|
+
return optionLabel(opt).toLowerCase().indexOf(typed) === 0;
|
|
160
|
+
});
|
|
161
|
+
if (match >= 0) { if (!isOpen()) open(); setHighlight(match); }
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Close when focus leaves the whole combo (e.g. Shift+Tab off the button).
|
|
167
|
+
root.addEventListener('focusout', function (e) {
|
|
168
|
+
if (!root.contains(e.relatedTarget)) close();
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function initAll(context) {
|
|
173
|
+
var scope = context || document;
|
|
174
|
+
Array.prototype.forEach.call(
|
|
175
|
+
scope.querySelectorAll('[data-fdy-combo]'),
|
|
176
|
+
initCombo
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// One global handler closes the open combo on an outside click.
|
|
181
|
+
document.addEventListener('click', function (e) {
|
|
182
|
+
if (openClose && !(e.target.closest && e.target.closest('.fdy-combo'))) {
|
|
183
|
+
openClose();
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (document.readyState === 'loading') {
|
|
188
|
+
document.addEventListener('DOMContentLoaded', function () { initAll(); });
|
|
189
|
+
} else {
|
|
190
|
+
initAll();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
window.FreedayCombo = { init: initCombo, initAll: initAll };
|
|
194
|
+
})();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* Freeday — slider value binding (optional, zero-dependency).
|
|
2
|
+
* Mirrors a [data-fdy-slider] range input's value into <output for="inputId">, with an
|
|
3
|
+
* optional prefix/suffix on the output (data-fdy-prefix / data-fdy-suffix). The range itself
|
|
4
|
+
* is a native input — keyboard and ARIA are built in; this only updates the visible readout.
|
|
5
|
+
*/
|
|
6
|
+
(function () {
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
function formatted(out, value) {
|
|
10
|
+
return (out.getAttribute('data-fdy-prefix') || '') + value + (out.getAttribute('data-fdy-suffix') || '');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function initSlider(input) {
|
|
14
|
+
if (input.dataset.fdySliderReady === '1') return;
|
|
15
|
+
input.dataset.fdySliderReady = '1';
|
|
16
|
+
var out = input.id ? document.querySelector('output[for="' + input.id + '"]') : null;
|
|
17
|
+
if (!out) return;
|
|
18
|
+
function sync() { out.textContent = formatted(out, input.value); }
|
|
19
|
+
input.addEventListener('input', sync);
|
|
20
|
+
sync();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function initAll(context) {
|
|
24
|
+
Array.prototype.forEach.call((context || document).querySelectorAll('[data-fdy-slider]'), initSlider);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (document.readyState === 'loading') {
|
|
28
|
+
document.addEventListener('DOMContentLoaded', function () { initAll(); });
|
|
29
|
+
} else {
|
|
30
|
+
initAll();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
window.FreedaySlider = { init: initSlider, initAll: initAll };
|
|
34
|
+
})();
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/* Freeday — stepper/wizard enhancer (optional, zero-dependency).
|
|
2
|
+
* Drives a step header + panels: prev/next navigation, completed/active state, and
|
|
3
|
+
* clicking a reached step to revisit it (linear — can't skip ahead). Auto-inits
|
|
4
|
+
* [data-fdy-stepper].
|
|
5
|
+
*
|
|
6
|
+
* Markup: <div data-fdy-stepper>
|
|
7
|
+
* <ol class="fdy-stepper">
|
|
8
|
+
* <li class="fdy-step"><button class="fdy-step__btn"><span class="fdy-step__marker">1</span>
|
|
9
|
+
* <span class="fdy-step__label">…</span></button></li>… </ol>
|
|
10
|
+
* <div class="fdy-step-panels">
|
|
11
|
+
* <div class="fdy-step-panel">…</div>… </div>
|
|
12
|
+
* <div class="fdy-step-nav"><button data-fdy-step-prev>…</button>
|
|
13
|
+
* <button data-fdy-step-next>…</button></div></div>
|
|
14
|
+
* Emits bubbling "fdy-step-change" {index} and "fdy-step-finish" (Next on the last step).
|
|
15
|
+
*/
|
|
16
|
+
(function () {
|
|
17
|
+
'use strict';
|
|
18
|
+
|
|
19
|
+
var CHECK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg>';
|
|
20
|
+
|
|
21
|
+
function initStepper(root) {
|
|
22
|
+
if (root.dataset.fdyStepperReady === '1') return;
|
|
23
|
+
root.dataset.fdyStepperReady = '1';
|
|
24
|
+
|
|
25
|
+
var steps = Array.prototype.slice.call(root.querySelectorAll('.fdy-step'));
|
|
26
|
+
var panels = Array.prototype.slice.call(root.querySelectorAll('.fdy-step-panel'));
|
|
27
|
+
var prevBtn = root.querySelector('[data-fdy-step-prev]');
|
|
28
|
+
var nextBtn = root.querySelector('[data-fdy-step-next]');
|
|
29
|
+
if (!steps.length) return;
|
|
30
|
+
|
|
31
|
+
var active = 0;
|
|
32
|
+
for (var i = 0; i < steps.length; i++) {
|
|
33
|
+
if (steps[i].classList.contains('is-active')) { active = i; break; }
|
|
34
|
+
}
|
|
35
|
+
var maxReached = active;
|
|
36
|
+
var nextLabel = nextBtn ? nextBtn.textContent : '';
|
|
37
|
+
|
|
38
|
+
steps.forEach(function (s) {
|
|
39
|
+
var marker = s.querySelector('.fdy-step__marker');
|
|
40
|
+
if (marker && marker.dataset.num == null) marker.dataset.num = marker.textContent.trim();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
function render() {
|
|
44
|
+
steps.forEach(function (s, i) {
|
|
45
|
+
s.classList.toggle('is-active', i === active);
|
|
46
|
+
s.classList.toggle('is-complete', i < active);
|
|
47
|
+
if (i === active) s.setAttribute('aria-current', 'step'); else s.removeAttribute('aria-current');
|
|
48
|
+
var marker = s.querySelector('.fdy-step__marker');
|
|
49
|
+
if (marker) marker.innerHTML = i < active ? CHECK : (marker.dataset.num || String(i + 1));
|
|
50
|
+
var btn = s.querySelector('.fdy-step__btn');
|
|
51
|
+
if (btn) btn.disabled = i > maxReached;
|
|
52
|
+
});
|
|
53
|
+
panels.forEach(function (p, i) { p.hidden = i !== active; });
|
|
54
|
+
if (prevBtn) prevBtn.disabled = active === 0;
|
|
55
|
+
if (nextBtn) nextBtn.textContent = active === steps.length - 1 ? 'Selesai' : (nextLabel || 'Lanjut');
|
|
56
|
+
root.dispatchEvent(new CustomEvent('fdy-step-change', { bubbles: true, detail: { index: active } }));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function go(i) {
|
|
60
|
+
if (i < 0 || i >= steps.length) return;
|
|
61
|
+
active = i;
|
|
62
|
+
if (active > maxReached) maxReached = active;
|
|
63
|
+
render();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (prevBtn) prevBtn.addEventListener('click', function () { go(active - 1); });
|
|
67
|
+
if (nextBtn) nextBtn.addEventListener('click', function () {
|
|
68
|
+
if (active < steps.length - 1) go(active + 1);
|
|
69
|
+
else root.dispatchEvent(new CustomEvent('fdy-step-finish', { bubbles: true }));
|
|
70
|
+
});
|
|
71
|
+
steps.forEach(function (s, i) {
|
|
72
|
+
var btn = s.querySelector('.fdy-step__btn');
|
|
73
|
+
if (btn) btn.addEventListener('click', function () { if (i <= maxReached) go(i); });
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
render();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function initAll(context) {
|
|
80
|
+
Array.prototype.forEach.call((context || document).querySelectorAll('[data-fdy-stepper]'), initStepper);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (document.readyState === 'loading') {
|
|
84
|
+
document.addEventListener('DOMContentLoaded', function () { initAll(); });
|
|
85
|
+
} else {
|
|
86
|
+
initAll();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
window.FreedayStepper = { init: initStepper, initAll: initAll };
|
|
90
|
+
})();
|