stimulus-library 0.3.19 → 0.4.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 +14 -0
- package/dist/controllers/ajax/async_block_controller.d.ts +18 -18
- package/dist/controllers/ajax/lazy_block_controller.d.ts +9 -9
- package/dist/controllers/ajax/load_block_controller.d.ts +19 -19
- package/dist/controllers/ajax/poll_block_controller.d.ts +16 -16
- package/dist/controllers/anchor_spy_controller.d.ts +15 -15
- package/dist/controllers/back_link_controller.d.ts +19 -19
- package/dist/controllers/clipboard_controller.d.ts +18 -18
- package/dist/controllers/confirm_controller.d.ts +13 -13
- package/dist/controllers/confirm_navigation_controller.d.ts +15 -15
- package/dist/controllers/debug_controller.d.ts +6 -6
- package/dist/controllers/disable_with_controller.d.ts +25 -25
- package/dist/controllers/dismissable_controller.d.ts +6 -6
- package/dist/controllers/element_save_controller.d.ts +25 -25
- package/dist/controllers/empty_dom_controller.d.ts +29 -29
- package/dist/controllers/forms/auto_submit_form_controller.d.ts +15 -14
- package/dist/controllers/forms/auto_submit_form_controller.d.ts.map +1 -1
- package/dist/controllers/forms/autosize_controller.d.ts +9 -9
- package/dist/controllers/forms/char_count_controller.d.ts +26 -26
- package/dist/controllers/forms/checkbox_select_all_controller.d.ts +14 -14
- package/dist/controllers/forms/detect_dirty_controller.d.ts +16 -16
- package/dist/controllers/forms/detect_dirty_form_controller.d.ts +19 -19
- package/dist/controllers/forms/disable_inputs_controller.d.ts +16 -16
- package/dist/controllers/forms/enable_inputs_controller.d.ts +16 -16
- package/dist/controllers/forms/form_rc_controller.d.ts +13 -7
- package/dist/controllers/forms/form_rc_controller.d.ts.map +1 -1
- package/dist/controllers/forms/form_save_controller.d.ts +33 -33
- package/dist/controllers/forms/limited_selection_checkboxes_controller.d.ts +17 -17
- package/dist/controllers/forms/navigate_form_errors_controller.d.ts +34 -34
- package/dist/controllers/forms/nested_form_controller.d.ts +21 -21
- package/dist/controllers/forms/password_confirm_controller.d.ts +17 -17
- package/dist/controllers/forms/password_peek_controller.d.ts +8 -8
- package/dist/controllers/forms/remote_form_controller.d.ts +13 -13
- package/dist/controllers/forms/sync_inputs_controller.d.ts +21 -21
- package/dist/controllers/forms/value_warn_controller.d.ts +39 -39
- package/dist/controllers/forms/word_count_controller.d.ts +26 -26
- package/dist/controllers/media/fallback_image_controller.d.ts +27 -27
- package/dist/controllers/media/lightbox_image_controller.d.ts +29 -29
- package/dist/controllers/media/media_player_controller.d.ts +12 -12
- package/dist/controllers/prefetch_controller.d.ts +18 -18
- package/dist/controllers/responsive_iframe_controller.d.ts +23 -23
- package/dist/controllers/scroll/scroll_container_controller.d.ts +21 -21
- package/dist/controllers/scroll/scroll_into_focus_controller.d.ts +15 -15
- package/dist/controllers/scroll/scroll_to_bottom_controller.d.ts +11 -11
- package/dist/controllers/scroll/scroll_to_controller.d.ts +17 -17
- package/dist/controllers/scroll/scroll_to_top_controller.d.ts +11 -11
- package/dist/controllers/self_destruct_controller.d.ts +10 -10
- package/dist/controllers/sticky_controller.d.ts +19 -19
- package/dist/controllers/tables/table_sort_controller.d.ts +20 -20
- package/dist/controllers/tables/table_truncate_controller.d.ts +26 -26
- package/dist/controllers/teleport_controller.d.ts +15 -15
- package/dist/controllers/temporary_state_controller.d.ts +28 -28
- package/dist/controllers/toggle_class_controller.d.ts +35 -35
- package/dist/controllers/turbo_frame_rc_controller.d.ts +20 -20
- package/dist/controllers/turbo_frame_refresh_controller.d.ts +16 -16
- package/dist/controllers/utility/intersection_controller.d.ts +13 -13
- package/dist/controllers/utility/interval_controller.d.ts +13 -13
- package/dist/controllers/utility/presence_controller.d.ts +5 -5
- package/dist/controllers/utility/timeout_controller.d.ts +12 -12
- package/dist/controllers/utility/user_focus_controller.d.ts +10 -10
- package/dist/controllers/visual/clock_controller.d.ts +18 -18
- package/dist/controllers/visual/countdown_controller.d.ts +53 -53
- package/dist/controllers/visual/duration_controller.d.ts +27 -27
- package/dist/controllers/visual/tabs_controller.d.ts +37 -37
- package/dist/controllers/visual/time_distance_controller.d.ts +18 -18
- package/dist/controllers/visual/tree_view_controller.d.ts +29 -29
- package/dist/index.d.ts +66 -66
- package/dist/stimulus-library.cjs.js +2 -0
- package/dist/stimulus-library.cjs.js.map +1 -0
- package/dist/stimulus-library.es.js +2 -0
- package/dist/stimulus-library.es.js.map +1 -0
- package/dist/stimulus-library.umd.js +1 -1
- package/dist/stimulus-library.umd.js.map +1 -1
- package/dist/utilities/base_controller.d.ts +13 -13
- package/dist/utilities/base_controller.d.ts.map +1 -1
- package/dist/utilities/elements.d.ts +13 -13
- package/dist/utilities/ephemeral_controller.d.ts +5 -5
- package/dist/utilities/event_bus.d.ts +3 -3
- package/dist/utilities/requestSubmit.d.ts +2 -2
- package/dist/utilities/scroll.d.ts +10 -10
- package/dist/utilities/turbo.d.ts +1 -1
- package/package.json +16 -10
- package/dist/stimulus-library.js +0 -2
- package/dist/stimulus-library.js.map +0 -1
- package/dist/stimulus-library.modern.js +0 -2
- package/dist/stimulus-library.modern.js.map +0 -1
- package/dist/stimulus-library.module.js +0 -2
- package/dist/stimulus-library.module.js.map +0 -1
- package/src/controllers/ajax/async_block_controller.ts +0 -28
- package/src/controllers/ajax/lazy_block_controller.ts +0 -31
- package/src/controllers/ajax/load_block_controller.ts +0 -59
- package/src/controllers/ajax/poll_block_controller.ts +0 -32
- package/src/controllers/anchor_spy_controller.ts +0 -47
- package/src/controllers/back_link_controller.ts +0 -49
- package/src/controllers/clipboard_controller.ts +0 -47
- package/src/controllers/confirm_controller.ts +0 -50
- package/src/controllers/confirm_navigation_controller.ts +0 -51
- package/src/controllers/debug_controller.ts +0 -11
- package/src/controllers/disable_with_controller.ts +0 -116
- package/src/controllers/dismissable_controller.ts +0 -12
- package/src/controllers/element_save_controller.ts +0 -93
- package/src/controllers/empty_dom_controller.ts +0 -105
- package/src/controllers/forms/auto_submit_form_controller.ts +0 -59
- package/src/controllers/forms/autosize_controller.ts +0 -41
- package/src/controllers/forms/char_count_controller.ts +0 -91
- package/src/controllers/forms/checkbox_select_all_controller.ts +0 -57
- package/src/controllers/forms/detect_dirty_controller.ts +0 -116
- package/src/controllers/forms/detect_dirty_form_controller.ts +0 -127
- package/src/controllers/forms/disable_inputs_controller.ts +0 -44
- package/src/controllers/forms/enable_inputs_controller.ts +0 -44
- package/src/controllers/forms/form_rc_controller.ts +0 -20
- package/src/controllers/forms/form_save_controller.ts +0 -141
- package/src/controllers/forms/limited_selection_checkboxes_controller.ts +0 -44
- package/src/controllers/forms/navigate_form_errors_controller.ts +0 -144
- package/src/controllers/forms/nested_form_controller.ts +0 -68
- package/src/controllers/forms/password_confirm_controller.ts +0 -68
- package/src/controllers/forms/password_peek_controller.ts +0 -27
- package/src/controllers/forms/remote_form_controller.ts +0 -34
- package/src/controllers/forms/sync_inputs_controller.ts +0 -89
- package/src/controllers/forms/value_warn_controller.ts +0 -107
- package/src/controllers/forms/word_count_controller.ts +0 -86
- package/src/controllers/media/fallback_image_controller.ts +0 -108
- package/src/controllers/media/lightbox_image_controller.ts +0 -89
- package/src/controllers/media/media_player_controller.ts +0 -37
- package/src/controllers/prefetch_controller.ts +0 -99
- package/src/controllers/responsive_iframe_controller.ts +0 -75
- package/src/controllers/scroll/scroll_container_controller.ts +0 -73
- package/src/controllers/scroll/scroll_into_focus_controller.ts +0 -34
- package/src/controllers/scroll/scroll_to_bottom_controller.ts +0 -35
- package/src/controllers/scroll/scroll_to_controller.ts +0 -38
- package/src/controllers/scroll/scroll_to_top_controller.ts +0 -35
- package/src/controllers/self_destruct_controller.ts +0 -23
- package/src/controllers/sticky_controller.ts +0 -84
- package/src/controllers/tables/table_sort_controller.ts +0 -105
- package/src/controllers/tables/table_truncate_controller.ts +0 -106
- package/src/controllers/teleport_controller.ts +0 -64
- package/src/controllers/temporary_state_controller.ts +0 -82
- package/src/controllers/toggle_class_controller.ts +0 -149
- package/src/controllers/turbo_frame_rc_controller.ts +0 -77
- package/src/controllers/turbo_frame_refresh_controller.ts +0 -51
- package/src/controllers/utility/intersection_controller.ts +0 -51
- package/src/controllers/utility/interval_controller.ts +0 -34
- package/src/controllers/utility/presence_controller.ts +0 -13
- package/src/controllers/utility/timeout_controller.ts +0 -30
- package/src/controllers/utility/user_focus_controller.ts +0 -40
- package/src/controllers/visual/clock_controller.ts +0 -75
- package/src/controllers/visual/countdown_controller.ts +0 -198
- package/src/controllers/visual/duration_controller.ts +0 -106
- package/src/controllers/visual/tabs_controller.ts +0 -162
- package/src/controllers/visual/time_distance_controller.ts +0 -66
- package/src/controllers/visual/tree_view_controller.ts +0 -154
- package/src/index.ts +0 -71
- package/src/utilities/base_controller.ts +0 -143
- package/src/utilities/elements.ts +0 -47
- package/src/utilities/ephemeral_controller.ts +0 -45
- package/src/utilities/event_bus.ts +0 -3
- package/src/utilities/requestSubmit.ts +0 -23
- package/src/utilities/scroll.ts +0 -101
- package/src/utilities/turbo.ts +0 -3
- package/src/utilities/types.d.ts +0 -4
- package/tsconfig.json +0 -27
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import {Duration, intervalToDuration, isPast} from "date-fns";
|
|
2
|
-
import {BaseController} from "../../utilities/base_controller";
|
|
3
|
-
|
|
4
|
-
export class CountdownController extends BaseController {
|
|
5
|
-
|
|
6
|
-
static values = {deadline: String, removeUnused: Boolean};
|
|
7
|
-
static targets = ["years", "months", "days", "hours", "minutes", "seconds"];
|
|
8
|
-
static classes = ["countingDown", "ended"];
|
|
9
|
-
|
|
10
|
-
// Values
|
|
11
|
-
declare readonly deadlineValue: string;
|
|
12
|
-
declare readonly removeUnusedValue: boolean;
|
|
13
|
-
declare readonly hasRemoveUnusedValue: boolean;
|
|
14
|
-
// Targets
|
|
15
|
-
declare readonly hasYearsTarget: boolean;
|
|
16
|
-
declare readonly yearsTarget: HTMLElement;
|
|
17
|
-
declare readonly hasMonthsTarget: boolean;
|
|
18
|
-
declare readonly monthsTarget: HTMLElement;
|
|
19
|
-
declare readonly hasDaysTarget: boolean;
|
|
20
|
-
declare readonly daysTarget: HTMLElement;
|
|
21
|
-
declare readonly hasHoursTarget: boolean;
|
|
22
|
-
declare readonly hoursTarget: HTMLElement;
|
|
23
|
-
declare readonly hasMinutesTarget: boolean;
|
|
24
|
-
declare readonly minutesTarget: HTMLElement;
|
|
25
|
-
declare readonly hasSecondsTarget: boolean;
|
|
26
|
-
declare readonly secondsTarget: HTMLElement;
|
|
27
|
-
// Classes
|
|
28
|
-
declare readonly countingDownClass: string;
|
|
29
|
-
declare readonly hasCountingDownClass: boolean;
|
|
30
|
-
declare readonly endedClass: string;
|
|
31
|
-
declare readonly hasEndedClass: boolean;
|
|
32
|
-
// Instance Data
|
|
33
|
-
_interval: null | ReturnType<typeof window.setInterval> = null;
|
|
34
|
-
|
|
35
|
-
get _removeUnused(): boolean {
|
|
36
|
-
return this.hasRemoveUnusedValue ? this.removeUnusedValue : false;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
get _endedClasses(): string[] {
|
|
40
|
-
return this.endedClass.split(' ');
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
get _defaultEndedClasses(): string[] {
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
get _countingDownClasses(): string[] {
|
|
48
|
-
return this.countingDownClass.split(' ');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
get _defaultCountingDownClasses(): string[] {
|
|
52
|
-
return [];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
get _deadlineDate() {
|
|
56
|
-
return new Date(this.deadlineValue);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
connect() {
|
|
60
|
-
this._interval = setInterval(this._tick.bind(this), 1000);
|
|
61
|
-
this._addCountingDownClasses();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
disconnect() {
|
|
65
|
-
this._clearTick();
|
|
66
|
-
this._removeCountingDownClasses();
|
|
67
|
-
this._removeEndedClasses();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
deadlineValueChanged() {
|
|
71
|
-
// Countdown had previously ended, restart ticking. Updating mid-tick will just work.
|
|
72
|
-
if (this._interval == null) {
|
|
73
|
-
this._interval = setInterval(this._tick.bind(this), 1000);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
_tick() {
|
|
78
|
-
try {
|
|
79
|
-
const now = new Date();
|
|
80
|
-
let distance: Duration = {};
|
|
81
|
-
|
|
82
|
-
if (isPast(this._deadlineDate)) {
|
|
83
|
-
distance = {years: 0, months: 0, days: 0, hours: 0, minutes: 0, seconds: 0};
|
|
84
|
-
// Countdown has ended, stop ticking
|
|
85
|
-
this._clearTick();
|
|
86
|
-
this._removeCountingDownClasses();
|
|
87
|
-
this._addEndedClasses();
|
|
88
|
-
this.dispatch(this.el, "countdown:ended");
|
|
89
|
-
} else {
|
|
90
|
-
distance = intervalToDuration({start: this._deadlineDate, end: now});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (this.hasYearsTarget) {
|
|
94
|
-
this._updateTarget(this.yearsTarget, this._years(distance));
|
|
95
|
-
}
|
|
96
|
-
if (this.hasMonthsTarget) {
|
|
97
|
-
this._updateTarget(this.monthsTarget, this._months(distance));
|
|
98
|
-
}
|
|
99
|
-
if (this.hasDaysTarget) {
|
|
100
|
-
this._updateTarget(this.daysTarget, this._days(distance));
|
|
101
|
-
}
|
|
102
|
-
if (this.hasHoursTarget) {
|
|
103
|
-
this._updateTarget(this.hoursTarget, this._hours(distance));
|
|
104
|
-
}
|
|
105
|
-
if (this.hasMinutesTarget) {
|
|
106
|
-
this._updateTarget(this.minutesTarget, this._minutes(distance));
|
|
107
|
-
}
|
|
108
|
-
if (this.hasSecondsTarget) {
|
|
109
|
-
this._updateTarget(this.secondsTarget, this._seconds(distance));
|
|
110
|
-
}
|
|
111
|
-
} catch (e) {
|
|
112
|
-
console.error(e);
|
|
113
|
-
this._clearTick();
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
_clearTick() {
|
|
118
|
-
if (this._interval) {
|
|
119
|
-
clearInterval(this._interval);
|
|
120
|
-
this._interval = null;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
_updateTarget(target: HTMLElement, value: number) {
|
|
125
|
-
this._removeTargetIfUnused(target, value);
|
|
126
|
-
target.innerHTML = value.toString();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
_removeTargetIfUnused(target: HTMLElement, value: number) {
|
|
130
|
-
if (this._removeUnused) {
|
|
131
|
-
if (value === 0 && target.dataset.unused) {
|
|
132
|
-
if (Number.parseInt(target.dataset.unused) > Date.now() + 1500) {
|
|
133
|
-
target.remove();
|
|
134
|
-
}
|
|
135
|
-
} else if (value == 0) {
|
|
136
|
-
target.dataset.unused = Date.now().toString();
|
|
137
|
-
} else {
|
|
138
|
-
target.dataset.unused = undefined;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
_years(duration: Duration): number {
|
|
144
|
-
return duration.years || 0;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
_months(duration: Duration): number {
|
|
148
|
-
return duration.months || 0;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
_days(duration: Duration): number {
|
|
152
|
-
return duration.days || 0;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
_hours(duration: Duration): number {
|
|
156
|
-
return duration.hours || 0;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
_minutes(duration: Duration): number {
|
|
160
|
-
return duration.minutes || 0;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
_seconds(duration: Duration): number {
|
|
164
|
-
return duration.seconds || 0;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
private _addEndedClasses(el: HTMLElement = this.el) {
|
|
168
|
-
if (this.hasEndedClass) {
|
|
169
|
-
el.classList.add(...this._endedClasses);
|
|
170
|
-
} else {
|
|
171
|
-
el.classList.add(...this._defaultEndedClasses);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
private _removeEndedClasses(el: HTMLElement = this.el) {
|
|
176
|
-
if (this.hasEndedClass) {
|
|
177
|
-
el.classList.remove(...this._endedClasses);
|
|
178
|
-
} else {
|
|
179
|
-
el.classList.remove(...this._defaultEndedClasses);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private _addCountingDownClasses(el: HTMLElement = this.el) {
|
|
184
|
-
if (this.hasCountingDownClass) {
|
|
185
|
-
el.classList.add(...this._countingDownClasses);
|
|
186
|
-
} else {
|
|
187
|
-
el.classList.add(...this._defaultCountingDownClasses);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
private _removeCountingDownClasses(el: HTMLElement = this.el) {
|
|
192
|
-
if (this.hasCountingDownClass) {
|
|
193
|
-
el.classList.remove(...this._countingDownClasses);
|
|
194
|
-
} else {
|
|
195
|
-
el.classList.remove(...this._defaultCountingDownClasses);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import {Duration, formatDuration, intervalToDuration, toDate} from "date-fns";
|
|
2
|
-
import {BaseController} from "../../utilities/base_controller";
|
|
3
|
-
|
|
4
|
-
export class DurationController extends BaseController {
|
|
5
|
-
static values = {
|
|
6
|
-
timestamp: Number,
|
|
7
|
-
minutes: Boolean,
|
|
8
|
-
seconds: Boolean,
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
declare readonly minutesValue: boolean;
|
|
12
|
-
declare readonly hasMinutesValue: boolean;
|
|
13
|
-
declare readonly secondsValue: boolean;
|
|
14
|
-
declare readonly hasSecondsValue: boolean;
|
|
15
|
-
declare timestampValue: number;
|
|
16
|
-
declare readonly hasTimestampValue: boolean;
|
|
17
|
-
_intervalHandle: number | null = null;
|
|
18
|
-
|
|
19
|
-
get _format(): string[] {
|
|
20
|
-
return [
|
|
21
|
-
"years",
|
|
22
|
-
"months",
|
|
23
|
-
"weeks",
|
|
24
|
-
"days",
|
|
25
|
-
"hours",
|
|
26
|
-
...(this._minutes ? ["minutes"] : []),
|
|
27
|
-
...(this._seconds ? ["seconds"] : []),
|
|
28
|
-
];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
get _output(): string {
|
|
32
|
-
let {years, months, weeks, days, hours, minutes, seconds} = this._duration;
|
|
33
|
-
|
|
34
|
-
years ||= 0;
|
|
35
|
-
months ||= 0;
|
|
36
|
-
weeks ||= 0;
|
|
37
|
-
days ||= 0;
|
|
38
|
-
hours ||= 0;
|
|
39
|
-
minutes ||= 0;
|
|
40
|
-
seconds ||= 0;
|
|
41
|
-
|
|
42
|
-
let largeDenominators = [years, months, weeks, days, hours];
|
|
43
|
-
|
|
44
|
-
if (!this._minutes && !this._seconds && largeDenominators.every((x) => x === 0)) {
|
|
45
|
-
minutes = minutes + seconds / 60.0;
|
|
46
|
-
return `${(minutes / 60).toFixed(1)} hours`;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return formatDuration(this._duration, {format: this._format, delimiter: ", "});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
get _seconds(): boolean {
|
|
53
|
-
return this.hasSecondsValue ? this.secondsValue : true;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
get _minutes(): boolean {
|
|
57
|
-
return this.hasMinutesValue ? this.minutesValue : true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
get _timestamp(): Date {
|
|
61
|
-
if (this.hasTimestampValue) {
|
|
62
|
-
return toDate(this.timestampValue * 1000);
|
|
63
|
-
} else {
|
|
64
|
-
throw new Error("Expected `timestampValue` to be present");
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
get _duration(): Duration {
|
|
69
|
-
return intervalToDuration({start: new Date(), end: this._timestamp});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
get _tickInterval() {
|
|
73
|
-
if (this._seconds) {
|
|
74
|
-
return 1000; // 1 seconds
|
|
75
|
-
} else if (this._minutes) {
|
|
76
|
-
return 15000; // 15 seconds
|
|
77
|
-
} else {
|
|
78
|
-
return 120000; // 2 minutes
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
initialize() {
|
|
83
|
-
this._update = this._update.bind(this);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
connect() {
|
|
87
|
-
this._intervalHandle = window.setInterval(this._update, this._tickInterval);
|
|
88
|
-
this._update();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
disconnect() {
|
|
92
|
-
if (this._intervalHandle) {
|
|
93
|
-
window.clearInterval(this._intervalHandle);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
_update() {
|
|
98
|
-
try {
|
|
99
|
-
this.el.innerHTML = this._output;
|
|
100
|
-
} catch {
|
|
101
|
-
if (this._intervalHandle) {
|
|
102
|
-
window.clearInterval(this._intervalHandle);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import {BaseController} from "../../utilities/base_controller";
|
|
2
|
-
import {clamp} from "lodash-es";
|
|
3
|
-
|
|
4
|
-
export class TabsController extends BaseController {
|
|
5
|
-
|
|
6
|
-
static values = {currentTab: Number, equalize: Boolean};
|
|
7
|
-
static targets = ["link", "content"];
|
|
8
|
-
static classes = ["active", "hide"];
|
|
9
|
-
|
|
10
|
-
declare currentTabValue: number;
|
|
11
|
-
declare hasCurrentTabValue: boolean;
|
|
12
|
-
|
|
13
|
-
declare equalizeValue: boolean;
|
|
14
|
-
declare hasEqualizeValue: boolean;
|
|
15
|
-
declare readonly linkTargets: HTMLElement[];
|
|
16
|
-
declare readonly contentTargets: HTMLElement[];
|
|
17
|
-
declare readonly activeClass: string;
|
|
18
|
-
declare readonly hasActiveClass: boolean;
|
|
19
|
-
declare readonly hideClass: string;
|
|
20
|
-
declare readonly hasHideClass: boolean;
|
|
21
|
-
|
|
22
|
-
get _hideClasses(): string[] {
|
|
23
|
-
return this.hideClass.split(' ');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
get _defaultHideClasses(): string[] {
|
|
27
|
-
return ["hide"];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
get _activeClasses(): string[] {
|
|
31
|
-
return this.activeClass.split(' ');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
get _defaultActiveClasses(): string[] {
|
|
35
|
-
return ["is-active"];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
get _currentTab(): number {
|
|
39
|
-
return this.hasCurrentTabValue ? this.currentTabValue : 0;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
get _equalize(): boolean {
|
|
43
|
-
return this.hasEqualizeValue ? this.equalizeValue : false;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
initialize() {
|
|
47
|
-
this.switchTabs = this.switchTabs.bind(this);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
connect() {
|
|
51
|
-
this.linkTargets.forEach((link) => link.addEventListener("click", this.switchTabs));
|
|
52
|
-
|
|
53
|
-
if (this._equalize) {
|
|
54
|
-
this._setMinHeight();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
this.currentTabValue = this._currentTab;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
disconnect() {
|
|
61
|
-
this.linkTargets.forEach((link) => link.removeEventListener("click", this.switchTabs));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
switchTabs(event: Event) {
|
|
65
|
-
event.preventDefault();
|
|
66
|
-
this.currentTabValue = this.linkTargets.indexOf(event.currentTarget as HTMLElement);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
currentTabValueChanged() {
|
|
70
|
-
let index = this._currentTab;
|
|
71
|
-
index = this._clampIndex(index);
|
|
72
|
-
this._selectTab(index);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
_selectTab(index: number) {
|
|
76
|
-
index = this._clampIndex(index);
|
|
77
|
-
let links = this.linkTargets;
|
|
78
|
-
let panels = this.contentTargets;
|
|
79
|
-
let activePanel = panels[index];
|
|
80
|
-
let activeLink = links[index];
|
|
81
|
-
let otherPanels = [...panels.slice(0, index), ...panels.slice(index + 1)];
|
|
82
|
-
let otherLinks = [...links.slice(0, index), ...links.slice(index + 1)];
|
|
83
|
-
|
|
84
|
-
this._addActiveClasses(activeLink);
|
|
85
|
-
activeLink.setAttribute('aria-selected', "true");
|
|
86
|
-
|
|
87
|
-
this._addActiveClasses(activePanel);
|
|
88
|
-
this._removeHideClasses(activePanel);
|
|
89
|
-
|
|
90
|
-
otherLinks.forEach((link) => {
|
|
91
|
-
link.removeAttribute('aria-selected');
|
|
92
|
-
|
|
93
|
-
this._removeActiveClasses(link);
|
|
94
|
-
});
|
|
95
|
-
otherPanels.forEach((panel) => {
|
|
96
|
-
this._removeActiveClasses(panel);
|
|
97
|
-
this._addHideClasses(panel);
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
_clampIndex(index: number): number {
|
|
102
|
-
return clamp(index, 0, this.contentTargets.length - 1);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
_setMinHeight() {
|
|
106
|
-
let minHeight = 0;
|
|
107
|
-
|
|
108
|
-
// determine the minimum height
|
|
109
|
-
this.contentTargets.forEach((content) => {
|
|
110
|
-
let hidden = content.hasAttribute("tab-hidden");
|
|
111
|
-
if (hidden) {
|
|
112
|
-
this._removeHideClasses(content);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
let height = content.offsetHeight;
|
|
116
|
-
if (height > minHeight) {
|
|
117
|
-
minHeight = height;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (hidden) {
|
|
121
|
-
this._addHideClasses(content);
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
// apply to all tabs
|
|
126
|
-
this.contentTargets.forEach((content) => content.style.minHeight = minHeight + "px");
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
private _addHideClasses(el: HTMLElement = this.el) {
|
|
130
|
-
el.setAttribute("tab-hidden", "true");
|
|
131
|
-
if (this.hasHideClass) {
|
|
132
|
-
el.classList.add(...this._hideClasses);
|
|
133
|
-
} else {
|
|
134
|
-
el.classList.add(...this._defaultHideClasses);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
private _removeHideClasses(el: HTMLElement = this.el) {
|
|
139
|
-
el.removeAttribute("tab-hidden");
|
|
140
|
-
if (this.hasHideClass) {
|
|
141
|
-
el.classList.remove(...this._hideClasses);
|
|
142
|
-
} else {
|
|
143
|
-
el.classList.remove(...this._defaultHideClasses);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
private _addActiveClasses(el: HTMLElement = this.el) {
|
|
148
|
-
if (this.hasActiveClass) {
|
|
149
|
-
el.classList.add(...this._activeClasses);
|
|
150
|
-
} else {
|
|
151
|
-
el.classList.add(...this._defaultActiveClasses);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
private _removeActiveClasses(el: HTMLElement = this.el) {
|
|
156
|
-
if (this.hasActiveClass) {
|
|
157
|
-
el.classList.remove(...this._activeClasses);
|
|
158
|
-
} else {
|
|
159
|
-
el.classList.remove(...this._defaultActiveClasses);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import {Duration, formatDistanceToNow, intervalToDuration, isPast, toDate} from "date-fns";
|
|
2
|
-
import {BaseController} from "../../utilities/base_controller";
|
|
3
|
-
|
|
4
|
-
export class TimeDistanceController extends BaseController {
|
|
5
|
-
static values = {
|
|
6
|
-
timestamp: Number,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
declare timestampValue: number;
|
|
10
|
-
declare readonly hasTimestampValue: boolean;
|
|
11
|
-
|
|
12
|
-
_timeout: number | null = null;
|
|
13
|
-
declare _timestamp: Date;
|
|
14
|
-
|
|
15
|
-
get _duration(): Duration {
|
|
16
|
-
return isPast(this._timestamp) ? intervalToDuration({start: this._timestamp, end: new Date()}) : intervalToDuration({start: new Date(), end: this._timestamp});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
get _nextUpdate(): number | null {
|
|
20
|
-
let duration = this._duration;
|
|
21
|
-
|
|
22
|
-
if (duration.years && duration.years > 0) {
|
|
23
|
-
return null;
|
|
24
|
-
} else if (duration.months && duration.months > 0) {
|
|
25
|
-
return null;
|
|
26
|
-
} else if (duration.days && duration.days > 0) {
|
|
27
|
-
return null;
|
|
28
|
-
} else if (duration.hours && duration.hours > 0) {
|
|
29
|
-
return 1800000; // Update every 30 mins
|
|
30
|
-
} else {
|
|
31
|
-
return 30000; // Update every 30 seconds
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
timestampValueChanged() {
|
|
36
|
-
this._timestamp = toDate(this.timestampValue * 1000);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
initialize() {
|
|
40
|
-
this._update = this._update.bind(this);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
connect() {
|
|
44
|
-
if (!this.hasTimestampValue) {
|
|
45
|
-
throw new Error("Expected `timestampValue` to be present");
|
|
46
|
-
}
|
|
47
|
-
this._update();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
disconnect() {
|
|
51
|
-
if (this._timeout) {
|
|
52
|
-
window.clearTimeout(this._timeout);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
_update() {
|
|
57
|
-
this.el.innerHTML = formatDistanceToNow(this._timestamp, {
|
|
58
|
-
addSuffix: true,
|
|
59
|
-
includeSeconds: true,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
if (this._nextUpdate) {
|
|
63
|
-
this._timeout = window.setTimeout(this._update, this._nextUpdate);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import {useMutation} from "stimulus-use";
|
|
2
|
-
import {BaseController} from "../../utilities/base_controller";
|
|
3
|
-
|
|
4
|
-
export class TreeViewController extends BaseController {
|
|
5
|
-
|
|
6
|
-
static classes = [
|
|
7
|
-
"active",
|
|
8
|
-
"collapsed",
|
|
9
|
-
];
|
|
10
|
-
|
|
11
|
-
declare readonly activeClass: string;
|
|
12
|
-
declare readonly hasActiveClass: boolean;
|
|
13
|
-
declare readonly collapsedClass: string;
|
|
14
|
-
declare readonly hasCollapsedClass: boolean;
|
|
15
|
-
|
|
16
|
-
get _collapsedClasses(): string[] {
|
|
17
|
-
return this.hasCollapsedClass ? this.collapsedClass.split(' ') : this._defaultCollapsedClasses;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
get _defaultCollapsedClasses(): string[] {
|
|
21
|
-
return ['collapsed'];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
get _activeClasses(): string[] {
|
|
25
|
-
return this.hasActiveClass ? this.activeClass.split(' ') : this._defaultActiveClasses;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get _defaultActiveClasses(): string[] {
|
|
29
|
-
return ['active'];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
initialize() {
|
|
33
|
-
this._nodeClicked = this._nodeClicked.bind(this);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
connect() {
|
|
37
|
-
this._setup();
|
|
38
|
-
useMutation(this, {subtree: true, childList: true});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
disconnect() {
|
|
42
|
-
this._teardown();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
_setup() {
|
|
46
|
-
this._setupNode(this.el);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
_setupNode(el: HTMLElement) {
|
|
50
|
-
const process = (e: HTMLElement) => {
|
|
51
|
-
let parent = e.parentElement;
|
|
52
|
-
if (parent) {
|
|
53
|
-
if (!this._nodeActive(parent)) {
|
|
54
|
-
this._hideNode(parent);
|
|
55
|
-
}
|
|
56
|
-
parent.removeEventListener("click", this._nodeClicked);
|
|
57
|
-
parent.addEventListener("click", this._nodeClicked);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
if (el.tagName === 'UL' || el.tagName === 'OL') {
|
|
61
|
-
process(el);
|
|
62
|
-
}
|
|
63
|
-
el.querySelectorAll("ul, ol").forEach(e => process(e as HTMLElement));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
_teardown() {
|
|
67
|
-
this.el.querySelectorAll("ul, ol, li").forEach((el) => this._teardownNode(el as HTMLElement));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
_teardownNode(el: HTMLElement) {
|
|
71
|
-
[el, ...Array.from(el.querySelectorAll('ul, ol, li')) as HTMLElement[]].forEach((x) => {
|
|
72
|
-
x.removeEventListener("click", this._nodeClicked);
|
|
73
|
-
this._removeActiveClasses(x);
|
|
74
|
-
this._removeCollapsedClasses(x);
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
_nodeClicked(event: MouseEvent) {
|
|
79
|
-
if (event) {
|
|
80
|
-
event.stopImmediatePropagation();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
let el = event.target as HTMLElement | null;
|
|
84
|
-
|
|
85
|
-
if (!el || !this._hasNested(el)) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (this._nodeActive(el)) {
|
|
90
|
-
this._hideNode(el);
|
|
91
|
-
} else {
|
|
92
|
-
this._showNode(el);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
_nodeActive(el: HTMLElement): boolean {
|
|
97
|
-
return this._activeClasses.every(klass => el.classList.contains(klass));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
_showNode(el: HTMLElement) {
|
|
101
|
-
this._removeCollapsedClasses(el);
|
|
102
|
-
this._addActiveClasses(el);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
_hideNode(el: HTMLElement) {
|
|
106
|
-
this._removeActiveClasses(el);
|
|
107
|
-
this._addCollapsedClasses(el);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
_hasNested(el: HTMLElement): boolean {
|
|
111
|
-
return el.querySelectorAll("ul, ol").length > 0;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
mutate(entries: MutationRecord[]) {
|
|
115
|
-
for (const mutation of entries) {
|
|
116
|
-
if (mutation.type === "childList") {
|
|
117
|
-
(Array.from(mutation.addedNodes || []) as HTMLElement[]).forEach(el => this._setupNode(el));
|
|
118
|
-
(Array.from(mutation.removedNodes || []) as HTMLElement[]).forEach(el => this._teardownNode(el));
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
private _addCollapsedClasses(el: HTMLElement = this.el) {
|
|
124
|
-
if (this.hasCollapsedClass) {
|
|
125
|
-
el.classList.add(...this._collapsedClasses);
|
|
126
|
-
} else {
|
|
127
|
-
el.classList.add(...this._defaultCollapsedClasses);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
private _removeCollapsedClasses(el: HTMLElement = this.el) {
|
|
132
|
-
if (this.hasCollapsedClass) {
|
|
133
|
-
el.classList.remove(...this._collapsedClasses);
|
|
134
|
-
} else {
|
|
135
|
-
el.classList.remove(...this._defaultCollapsedClasses);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
private _addActiveClasses(el: HTMLElement = this.el) {
|
|
140
|
-
if (this.hasActiveClass) {
|
|
141
|
-
el.classList.add(...this._activeClasses);
|
|
142
|
-
} else {
|
|
143
|
-
el.classList.add(...this._defaultActiveClasses);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
private _removeActiveClasses(el: HTMLElement = this.el) {
|
|
148
|
-
if (this.hasActiveClass) {
|
|
149
|
-
el.classList.remove(...this._activeClasses);
|
|
150
|
-
} else {
|
|
151
|
-
el.classList.remove(...this._defaultActiveClasses);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|