stimulus-library 0.9.0 → 0.9.2
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/LICENSE +21 -0
- package/README.md +43 -43
- package/dist/controllers/forms/disable_inputs_controller.js +21 -0
- package/dist/controllers/index.js +1 -0
- package/dist/controllers/media/fallback_iframe_controller.js +44 -0
- package/dist/controllers/refresh_page_controller.js +17 -0
- package/dist/controllers/signal/base_controller.js +23 -0
- package/dist/controllers/signal/index.js +2 -0
- package/dist/controllers/signal/signal_action_controller.js +4 -14
- package/dist/controllers/signal/signal_attribute_sync_controller.js +10 -0
- package/dist/controllers/signal/signal_content_sync_controller.js +9 -0
- package/dist/controllers/signal/signal_disable_controller.js +34 -0
- package/dist/controllers/signal/signal_dom_children_controller.js +3 -1
- package/dist/controllers/signal/signal_enable_controller.js +34 -0
- package/dist/controllers/signal/signal_visibility_controller.js +4 -16
- package/dist/controllers/tables/table_filter_controller.js +53 -0
- package/dist/controllers/tables/table_sort_controller.js +17 -4
- package/dist/controllers/tables/table_truncate_controller.js +11 -3
- package/dist/controllers/turbo_frame_refresh_controller.js +2 -1
- package/dist/controllers/visual/countdown_controller.js +2 -0
- package/dist/controllers/visual/index.js +1 -0
- package/dist/controllers/visual/tween_number_controller.js +66 -0
- package/dist/utilities/base_controller.js +3 -0
- package/dist/utilities/easingFunctions.js +143 -0
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Sub-Xaero
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
# Stimulus-Library
|
|
2
|
-
|
|
3
|
-
[Documentation](https://sub-xaero.github.io/stimulus-library/) | [Full List of Controllers](https://sub-xaero.github.io/stimulus-library/)
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-

|
|
7
|
-

|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Installation
|
|
11
|
-
|
|
12
|
-
To get started, you'll need to add the `stimulus-library` package to your project.
|
|
13
|
-
|
|
14
|
-
To do so, either add `stimulus-library` to your package.json manually
|
|
15
|
-
|
|
16
|
-
```json
|
|
17
|
-
{
|
|
18
|
-
"dependencies": {
|
|
19
|
-
"stimulus-library": "latest"
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
or run
|
|
25
|
-
`npm install --save stimulus-library` or `yarn add stimulus-library`
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Then, to get started, import and register the controllers you want to use.
|
|
29
|
-
|
|
30
|
-
*Please Note* as below, that when registering the name for the controller, you should use `kebab-case` and omit the `-controller` suffix.
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
import { Application } from "@hotwired/stimulus";
|
|
34
|
-
import { AutoSubmitFormController } from "stimulus-library";
|
|
35
|
-
|
|
36
|
-
const application = Application.start();
|
|
37
|
-
application.register("auto-submit-form", AutoSubmitFormController);
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Tree-shaking
|
|
41
|
-
If you use the ESM builds of the library, this library fully supports tree-shaking,
|
|
42
|
-
only the controllers you directly import will be bundled with your application.
|
|
43
|
-
|
|
1
|
+
# Stimulus-Library
|
|
2
|
+
|
|
3
|
+
[Documentation](https://sub-xaero.github.io/stimulus-library/) | [Full List of Controllers](https://sub-xaero.github.io/stimulus-library/)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
To get started, you'll need to add the `stimulus-library` package to your project.
|
|
13
|
+
|
|
14
|
+
To do so, either add `stimulus-library` to your package.json manually
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"stimulus-library": "latest"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
or run
|
|
25
|
+
`npm install --save stimulus-library` or `yarn add stimulus-library`
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Then, to get started, import and register the controllers you want to use.
|
|
29
|
+
|
|
30
|
+
*Please Note* as below, that when registering the name for the controller, you should use `kebab-case` and omit the `-controller` suffix.
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
import { Application } from "@hotwired/stimulus";
|
|
34
|
+
import { AutoSubmitFormController } from "stimulus-library";
|
|
35
|
+
|
|
36
|
+
const application = Application.start();
|
|
37
|
+
application.register("auto-submit-form", AutoSubmitFormController);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Tree-shaking
|
|
41
|
+
If you use the ESM builds of the library, this library fully supports tree-shaking,
|
|
42
|
+
only the controllers you directly import will be bundled with your application.
|
|
43
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseController } from "../../utilities/base_controller";
|
|
2
|
+
export class DisableInputsController extends BaseController {
|
|
3
|
+
connect() {
|
|
4
|
+
}
|
|
5
|
+
disable() {
|
|
6
|
+
let shouldClear = this.hasClearValue && this.clearValue;
|
|
7
|
+
this.inputTargets.forEach((el, _) => {
|
|
8
|
+
if (shouldClear) {
|
|
9
|
+
el.value = "";
|
|
10
|
+
}
|
|
11
|
+
el.disabled = true;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
enable() {
|
|
15
|
+
this.inputTargets.forEach((el, _) => el.disabled = false);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
DisableInputsController.targets = ["input"];
|
|
19
|
+
DisableInputsController.values = {
|
|
20
|
+
clear: Boolean,
|
|
21
|
+
};
|
|
@@ -22,6 +22,7 @@ export * from './empty_dom_controller';
|
|
|
22
22
|
export * from './persisted_dismissable_controller';
|
|
23
23
|
export * from './prefetch_controller';
|
|
24
24
|
export * from './print_button_controller';
|
|
25
|
+
export * from './refresh_page_controller';
|
|
25
26
|
export * from './responsive_iframe_controller';
|
|
26
27
|
export * from './self_destruct_controller';
|
|
27
28
|
export * from './sticky_controller';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { BaseController } from "../../utilities/base_controller";
|
|
2
|
+
export class FallbackImageController extends BaseController {
|
|
3
|
+
initialize() {
|
|
4
|
+
this._hasLoadedSuccessfully = this._hasLoadedSuccessfully.bind(this);
|
|
5
|
+
this._success = this._success.bind(this);
|
|
6
|
+
this._fail = this._fail.bind(this);
|
|
7
|
+
}
|
|
8
|
+
connect() {
|
|
9
|
+
let element = this.el;
|
|
10
|
+
element.onerror = this._fail;
|
|
11
|
+
if (element.complete && !this._hasLoadedSuccessfully()) {
|
|
12
|
+
this._fail();
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this._success();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
disconnect() {
|
|
19
|
+
this.removeSuccessClasses();
|
|
20
|
+
this.removeFailClasses();
|
|
21
|
+
}
|
|
22
|
+
_success() {
|
|
23
|
+
this.addSuccessClasses();
|
|
24
|
+
}
|
|
25
|
+
_fail() {
|
|
26
|
+
let element = this.el;
|
|
27
|
+
this.addFailClasses();
|
|
28
|
+
if (this.hasPlaceholderValue && element.src !== this.placeholderValue) {
|
|
29
|
+
this.dispatchEvent(element, this.eventName("placeholder"));
|
|
30
|
+
element.src = this.placeholderValue;
|
|
31
|
+
element.onerror = this._fail;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.dispatchEvent(element, this.eventName("fail"));
|
|
35
|
+
element.style.display = "none";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
_hasLoadedSuccessfully() {
|
|
39
|
+
let element = this.el;
|
|
40
|
+
return element.naturalHeight > 0 && element.naturalWidth > 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
FallbackImageController.values = { placeholder: String };
|
|
44
|
+
FallbackImageController.classes = ["success", "fail"];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseController } from "../utilities";
|
|
2
|
+
export class RefreshPageController extends BaseController {
|
|
3
|
+
get onLoad() {
|
|
4
|
+
return this.hasOnLoadValue ? this.onLoadValue : false;
|
|
5
|
+
}
|
|
6
|
+
connect() {
|
|
7
|
+
if (this.onLoad) {
|
|
8
|
+
this.refresh();
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
refresh() {
|
|
12
|
+
location.reload();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
RefreshPageController.values = {
|
|
16
|
+
onLoad: Boolean,
|
|
17
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BaseController } from "../../utilities/base_controller";
|
|
2
|
+
import { extractPredicates } from "./expressions";
|
|
3
|
+
import { EventBus } from "../../utilities/event_bus";
|
|
4
|
+
import { signalConnectEvent, signalValueEvent } from "./events";
|
|
5
|
+
import { useEventBus } from "../../mixins/use_event_bus";
|
|
6
|
+
export class SignalBaseController extends BaseController {
|
|
7
|
+
connect() {
|
|
8
|
+
EventBus.emit(signalConnectEvent(this.nameValue));
|
|
9
|
+
useEventBus(this, signalValueEvent(this.nameValue), this._onSignal);
|
|
10
|
+
}
|
|
11
|
+
get predicateString() {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
get _predicates() {
|
|
15
|
+
return extractPredicates(this.predicateString);
|
|
16
|
+
}
|
|
17
|
+
allPredicatesMatch(value) {
|
|
18
|
+
return this._predicates.every(predicate => predicate(value));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
SignalBaseController.values = {
|
|
22
|
+
name: String,
|
|
23
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from './signal_action_controller';
|
|
2
|
+
export * from './signal_disable_controller';
|
|
2
3
|
export * from './signal_dom_children_controller';
|
|
4
|
+
export * from './signal_enable_controller';
|
|
3
5
|
export * from './signal_input_controller';
|
|
4
6
|
export * from './signal_visibility_controller';
|
|
@@ -1,23 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { EventBus } from "../../utilities";
|
|
5
|
-
import { signalConnectEvent, signalEventName, signalValueEvent } from "./events";
|
|
6
|
-
export class SignalActionController extends BaseController {
|
|
7
|
-
get _predicates() {
|
|
8
|
-
return extractPredicates(this.whenValue);
|
|
9
|
-
}
|
|
10
|
-
connect() {
|
|
11
|
-
EventBus.emit(signalConnectEvent(this.nameValue));
|
|
12
|
-
useEventBus(this, signalValueEvent(this.nameValue), this._onSignal);
|
|
13
|
-
}
|
|
1
|
+
import { signalEventName } from "./events";
|
|
2
|
+
import { SignalBaseController } from "./base_controller";
|
|
3
|
+
export class SignalActionController extends SignalBaseController {
|
|
14
4
|
_onSignal(payload) {
|
|
15
5
|
let value = payload.value;
|
|
16
6
|
if (!this.hasWhenValue) {
|
|
17
7
|
this.dispatchEvent(this.el, signalEventName(this.nameValue, 'match'));
|
|
18
8
|
return;
|
|
19
9
|
}
|
|
20
|
-
if (this.
|
|
10
|
+
if (this.allPredicatesMatch(value)) {
|
|
21
11
|
this.dispatchEvent(this.el, signalEventName(this.nameValue, 'match'), { detail: { element: this.el, value } });
|
|
22
12
|
}
|
|
23
13
|
else {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SignalBaseController } from "./base_controller";
|
|
2
|
+
export class SignalAttributeSyncController extends SignalBaseController {
|
|
3
|
+
_onSignal(payload) {
|
|
4
|
+
this.el.setAttribute(this.attributeValue, payload.value);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
SignalAttributeSyncController.values = {
|
|
8
|
+
name: String,
|
|
9
|
+
attribute: String,
|
|
10
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { signalEventName } from "./events";
|
|
2
|
+
import { SignalBaseController } from "./base_controller";
|
|
3
|
+
export class SignalDisableController extends SignalBaseController {
|
|
4
|
+
disable() {
|
|
5
|
+
this.el.setAttribute("disabled", "true");
|
|
6
|
+
}
|
|
7
|
+
enable() {
|
|
8
|
+
this.el.removeAttribute("disabled");
|
|
9
|
+
}
|
|
10
|
+
_onSignal(payload) {
|
|
11
|
+
let value = payload.value;
|
|
12
|
+
if (this.whenValue == "default") {
|
|
13
|
+
if (value == "") {
|
|
14
|
+
this.disable();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
this.enable();
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (this.allPredicatesMatch(value)) {
|
|
22
|
+
this.dispatchEvent(this.el, signalEventName(this.nameValue, "disable"), { detail: { predicate: this.whenValue, value } });
|
|
23
|
+
this.disable();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
this.dispatchEvent(this.el, signalEventName(this.nameValue, "enable"), { detail: { predicate: this.whenValue, value } });
|
|
27
|
+
this.enable();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
SignalDisableController.values = {
|
|
32
|
+
name: String,
|
|
33
|
+
when: String,
|
|
34
|
+
};
|
|
@@ -31,7 +31,9 @@ export class SignalDomChildrenController extends BaseController {
|
|
|
31
31
|
}
|
|
32
32
|
emitChildCount() {
|
|
33
33
|
let childCount = this._children.length;
|
|
34
|
-
|
|
34
|
+
let value = childCount.toString();
|
|
35
|
+
this.dispatchEvent(this.el, signalValueEvent(this._name), { detail: { value } });
|
|
36
|
+
EventBus.emit(signalValueEvent(this._name), { element: this.el, value });
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
SignalDomChildrenController.values = {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { signalEventName } from "./events";
|
|
2
|
+
import { SignalBaseController } from "./base_controller";
|
|
3
|
+
export class SignalEnableController extends SignalBaseController {
|
|
4
|
+
disable() {
|
|
5
|
+
this.el.setAttribute("disabled", "true");
|
|
6
|
+
}
|
|
7
|
+
enable() {
|
|
8
|
+
this.el.removeAttribute("disabled");
|
|
9
|
+
}
|
|
10
|
+
_onSignal(payload) {
|
|
11
|
+
let value = payload.value;
|
|
12
|
+
if (this.whenValue == "default") {
|
|
13
|
+
if (value == "") {
|
|
14
|
+
this.enable();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
this.disable();
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (this.allPredicatesMatch(value)) {
|
|
22
|
+
this.dispatchEvent(this.el, signalEventName(this.nameValue, "enable"), { detail: { predicate: this.whenValue, value } });
|
|
23
|
+
this.enable();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
this.dispatchEvent(this.el, signalEventName(this.nameValue, "disable"), { detail: { predicate: this.whenValue, value } });
|
|
27
|
+
this.disable();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
SignalEnableController.values = {
|
|
32
|
+
name: String,
|
|
33
|
+
when: String,
|
|
34
|
+
};
|
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { signalConnectEvent, signalValueEvent, signalVisibilityEvent } from "./events";
|
|
5
|
-
import { EventBus } from "../../utilities";
|
|
6
|
-
import { installClassMethods } from "../../mixins/install_class_methods";
|
|
7
|
-
export class SignalVisibilityController extends BaseController {
|
|
8
|
-
get _predicates() {
|
|
9
|
-
return extractPredicates(this.showValue);
|
|
10
|
-
}
|
|
1
|
+
import { signalVisibilityEvent } from "./events";
|
|
2
|
+
import { SignalBaseController } from "./base_controller";
|
|
3
|
+
export class SignalVisibilityController extends SignalBaseController {
|
|
11
4
|
get defaultHideClasses() {
|
|
12
5
|
return ["hide"];
|
|
13
6
|
}
|
|
14
|
-
connect() {
|
|
15
|
-
installClassMethods(this);
|
|
16
|
-
EventBus.emit(signalConnectEvent(this.nameValue));
|
|
17
|
-
useEventBus(this, signalValueEvent(this.nameValue), this._onSignal);
|
|
18
|
-
}
|
|
19
7
|
_onSignal(payload) {
|
|
20
8
|
let value = payload.value;
|
|
21
9
|
if (this.showValue == "default") {
|
|
@@ -27,7 +15,7 @@ export class SignalVisibilityController extends BaseController {
|
|
|
27
15
|
}
|
|
28
16
|
return;
|
|
29
17
|
}
|
|
30
|
-
if (this.
|
|
18
|
+
if (this.allPredicatesMatch(value)) {
|
|
31
19
|
this.dispatchEvent(this.el, signalVisibilityEvent(this.nameValue, "show"), { detail: { predicate: this.showValue, value } });
|
|
32
20
|
this.removeHideClasses(this.el);
|
|
33
21
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { BaseController } from "../../utilities/base_controller";
|
|
2
|
+
import { useMutationObserver } from "../../mixins/use_mutation_observer";
|
|
3
|
+
export class TableFilterController extends BaseController {
|
|
4
|
+
get _tableBody() {
|
|
5
|
+
return this.el.tBodies[0];
|
|
6
|
+
}
|
|
7
|
+
get _tableRows() {
|
|
8
|
+
return Array.from(this._tableBody.rows);
|
|
9
|
+
}
|
|
10
|
+
connect() {
|
|
11
|
+
useMutationObserver(this, this._tableBody, this.mutate, { childList: true });
|
|
12
|
+
requestAnimationFrame(() => {
|
|
13
|
+
this.filter();
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
filter(event) {
|
|
17
|
+
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
18
|
+
if (this.searchValue == "") {
|
|
19
|
+
this._tableRows.forEach((row) => this._showElement(row));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
let filter = this.searchValue.toLocaleUpperCase();
|
|
23
|
+
this._tableRows.forEach((row) => {
|
|
24
|
+
this.columns(row).forEach((col) => {
|
|
25
|
+
let text = col.textContent || col.innerText;
|
|
26
|
+
if (text.includes(filter)) {
|
|
27
|
+
this._showElement(row);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
this._hideElement(row);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
clear() {
|
|
36
|
+
this.searchValue = "";
|
|
37
|
+
}
|
|
38
|
+
columns(row) {
|
|
39
|
+
return Array.from(row.cells);
|
|
40
|
+
}
|
|
41
|
+
mutate(entries) {
|
|
42
|
+
this.filter();
|
|
43
|
+
}
|
|
44
|
+
_showElement(el) {
|
|
45
|
+
el.style.display = "";
|
|
46
|
+
}
|
|
47
|
+
_hideElement(el) {
|
|
48
|
+
el.style.display = "none";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
TableFilterController.values = {
|
|
52
|
+
search: String,
|
|
53
|
+
};
|
|
@@ -30,13 +30,19 @@ export class TableSortController extends BaseController {
|
|
|
30
30
|
requestAnimationFrame(() => {
|
|
31
31
|
useCollectionEventListener(this, this._tableHeaders, "click", this.sort);
|
|
32
32
|
if (this.hasStartSortValue) {
|
|
33
|
-
this.
|
|
33
|
+
this.sort(this._headerCellByIndex(this.startSortValue));
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
|
-
sort(
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
sort(event_or_target) {
|
|
38
|
+
let headerCell;
|
|
39
|
+
if (event_or_target instanceof Event) {
|
|
40
|
+
event_or_target.preventDefault();
|
|
41
|
+
headerCell = event_or_target.target;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
headerCell = event_or_target;
|
|
45
|
+
}
|
|
40
46
|
let headerCellIndex = this._indexOfHeaderCell(headerCell);
|
|
41
47
|
if (headerCell.dataset.sortable == "false") {
|
|
42
48
|
return;
|
|
@@ -57,6 +63,13 @@ export class TableSortController extends BaseController {
|
|
|
57
63
|
_indexOfHeaderCell(cell) {
|
|
58
64
|
return this._tableHeaders.indexOf(cell);
|
|
59
65
|
}
|
|
66
|
+
_headerCellByIndex(index) {
|
|
67
|
+
let cell = this._tableHeaders.at(index);
|
|
68
|
+
if (!cell) {
|
|
69
|
+
throw new Error(`No cell at index ${index}`);
|
|
70
|
+
}
|
|
71
|
+
return cell;
|
|
72
|
+
}
|
|
60
73
|
_otherHeaderCells(cell) {
|
|
61
74
|
return Array.from(this._tableHeaders).filter(otherCell => otherCell != cell);
|
|
62
75
|
}
|
|
@@ -8,6 +8,12 @@ export class TableTruncateController extends BaseController {
|
|
|
8
8
|
set _truncated(value) {
|
|
9
9
|
this.truncatedValue = value;
|
|
10
10
|
}
|
|
11
|
+
get _expanded() {
|
|
12
|
+
return this.hasExpandedValue ? this.expandedValue : false;
|
|
13
|
+
}
|
|
14
|
+
set _expanded(value) {
|
|
15
|
+
this.expandedValue = value;
|
|
16
|
+
}
|
|
11
17
|
get _tableBody() {
|
|
12
18
|
return this.el.tBodies[0];
|
|
13
19
|
}
|
|
@@ -26,8 +32,8 @@ export class TableTruncateController extends BaseController {
|
|
|
26
32
|
}
|
|
27
33
|
truncate(event) {
|
|
28
34
|
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
29
|
-
this._truncated = true;
|
|
30
35
|
if (this._tableRows.length >= this._limit) {
|
|
36
|
+
this._truncated = true;
|
|
31
37
|
this._tableRows.slice(this._limit).forEach((el) => {
|
|
32
38
|
if (el !== this.showMoreTarget) {
|
|
33
39
|
this._hideElement(el);
|
|
@@ -36,11 +42,12 @@ export class TableTruncateController extends BaseController {
|
|
|
36
42
|
this._showElement(this.showMoreTarget);
|
|
37
43
|
}
|
|
38
44
|
else {
|
|
45
|
+
this._truncated = false;
|
|
39
46
|
this._hideElement(this.showMoreTarget);
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
expand(event) {
|
|
43
|
-
this.
|
|
50
|
+
this._expanded = true;
|
|
44
51
|
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
45
52
|
this._tableRows.slice(this._limit).forEach((el) => {
|
|
46
53
|
if (el !== this.showMoreTarget) {
|
|
@@ -50,7 +57,7 @@ export class TableTruncateController extends BaseController {
|
|
|
50
57
|
this._hideElement(this.showMoreTarget);
|
|
51
58
|
}
|
|
52
59
|
mutate(entries) {
|
|
53
|
-
if (this.
|
|
60
|
+
if (this._tableRows.length >= this._limit && !this._expanded) {
|
|
54
61
|
this._reTruncate();
|
|
55
62
|
}
|
|
56
63
|
}
|
|
@@ -78,4 +85,5 @@ TableTruncateController.targets = ["showMore"];
|
|
|
78
85
|
TableTruncateController.values = {
|
|
79
86
|
limit: Number,
|
|
80
87
|
truncated: Boolean,
|
|
88
|
+
expanded: Boolean,
|
|
81
89
|
};
|
|
@@ -23,7 +23,8 @@ export class TurboFrameRefreshController extends BaseController {
|
|
|
23
23
|
refresh(event) {
|
|
24
24
|
event === null || event === void 0 ? void 0 : event.preventDefault();
|
|
25
25
|
let element = this.el;
|
|
26
|
-
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
element.reload();
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
TurboFrameRefreshController.values = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import intervalToDuration from "date-fns/intervalToDuration";
|
|
2
2
|
import isPast from "date-fns/isPast";
|
|
3
3
|
import { BaseController } from "../../utilities/base_controller";
|
|
4
|
+
import { installClassMethods } from "../../mixins/install_class_methods";
|
|
4
5
|
export class CountdownController extends BaseController {
|
|
5
6
|
constructor() {
|
|
6
7
|
super(...arguments);
|
|
@@ -15,6 +16,7 @@ export class CountdownController extends BaseController {
|
|
|
15
16
|
}
|
|
16
17
|
connect() {
|
|
17
18
|
this._interval = setInterval(this._tick.bind(this), 1000);
|
|
19
|
+
installClassMethods(this);
|
|
18
20
|
this.addCountingDownClasses();
|
|
19
21
|
}
|
|
20
22
|
disconnect() {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { BaseController } from "../../utilities/base_controller";
|
|
2
|
+
import { useIntersection } from "../../mixins/use_intersection";
|
|
3
|
+
import { EasingFunctions } from "../../utilities/easingFunctions";
|
|
4
|
+
export class TweenNumberController extends BaseController {
|
|
5
|
+
get start() {
|
|
6
|
+
if (this.hasStartValue) {
|
|
7
|
+
return this.startValue;
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
throw new Error("Required value `start` is missing");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
get end() {
|
|
14
|
+
if (this.hasEndValue) {
|
|
15
|
+
return this.endValue;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
throw new Error("Required value `end` is missing");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
get durationMs() {
|
|
22
|
+
if (this.hasDurationValue) {
|
|
23
|
+
return this.durationValue;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
throw new Error("Required value `duration` is missing");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
get easingFunction() {
|
|
30
|
+
let str = this.hasEasingValue ? this.easingValue : null;
|
|
31
|
+
let fallback = EasingFunctions.linear;
|
|
32
|
+
if (str == null) {
|
|
33
|
+
return fallback;
|
|
34
|
+
}
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
return EasingFunctions[str] || fallback;
|
|
37
|
+
}
|
|
38
|
+
connect() {
|
|
39
|
+
useIntersection(this, this.el, this.appear);
|
|
40
|
+
}
|
|
41
|
+
appear(_entry) {
|
|
42
|
+
this.tween();
|
|
43
|
+
}
|
|
44
|
+
;
|
|
45
|
+
tween() {
|
|
46
|
+
let startTimestamp = null;
|
|
47
|
+
const step = (timestamp) => {
|
|
48
|
+
if (!startTimestamp) {
|
|
49
|
+
startTimestamp = timestamp;
|
|
50
|
+
}
|
|
51
|
+
const elapsed = timestamp - startTimestamp;
|
|
52
|
+
const progress = Math.min(elapsed / this.durationMs, 1);
|
|
53
|
+
this.element.innerHTML = Math.floor(this.easingFunction(progress) * (this.end - this.start) + this.start).toString();
|
|
54
|
+
if (progress < 1) {
|
|
55
|
+
requestAnimationFrame(step);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
requestAnimationFrame(step);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
TweenNumberController.values = {
|
|
62
|
+
start: Number,
|
|
63
|
+
end: Number,
|
|
64
|
+
duration: Number,
|
|
65
|
+
easing: String,
|
|
66
|
+
};
|
|
@@ -50,6 +50,9 @@ export class BaseController extends Controller {
|
|
|
50
50
|
const element = document.head.querySelector(`meta[name="${name}"]`);
|
|
51
51
|
return (element === null || element === void 0 ? void 0 : element.getAttribute('content')) || null;
|
|
52
52
|
}
|
|
53
|
+
eventName(eventName) {
|
|
54
|
+
return `${this.identifier}:${eventName}`;
|
|
55
|
+
}
|
|
53
56
|
dispatchEvent(element, eventName, options = {}) {
|
|
54
57
|
dispatchEvent(this, element, eventName, options);
|
|
55
58
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
const pow = Math.pow;
|
|
2
|
+
const sqrt = Math.sqrt;
|
|
3
|
+
const sin = Math.sin;
|
|
4
|
+
const cos = Math.cos;
|
|
5
|
+
const PI = Math.PI;
|
|
6
|
+
const c1 = 1.70158;
|
|
7
|
+
const c2 = c1 * 1.525;
|
|
8
|
+
const c3 = c1 + 1;
|
|
9
|
+
const c4 = (2 * PI) / 3;
|
|
10
|
+
const c5 = (2 * PI) / 4.5;
|
|
11
|
+
const bounceOut = function (x) {
|
|
12
|
+
const n1 = 7.5625;
|
|
13
|
+
const d1 = 2.75;
|
|
14
|
+
if (x < 1 / d1) {
|
|
15
|
+
return n1 * x * x;
|
|
16
|
+
}
|
|
17
|
+
else if (x < 2 / d1) {
|
|
18
|
+
return n1 * (x -= 1.5 / d1) * x + 0.75;
|
|
19
|
+
}
|
|
20
|
+
else if (x < 2.5 / d1) {
|
|
21
|
+
return n1 * (x -= 2.25 / d1) * x + 0.9375;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
return n1 * (x -= 2.625 / d1) * x + 0.984375;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
export const EasingFunctions = {
|
|
28
|
+
linear: (x) => x,
|
|
29
|
+
easeInQuad: function (x) {
|
|
30
|
+
return x * x;
|
|
31
|
+
},
|
|
32
|
+
easeOutQuad: function (x) {
|
|
33
|
+
return 1 - (1 - x) * (1 - x);
|
|
34
|
+
},
|
|
35
|
+
easeInOutQuad: function (x) {
|
|
36
|
+
return x < 0.5 ? 2 * x * x : 1 - pow(-2 * x + 2, 2) / 2;
|
|
37
|
+
},
|
|
38
|
+
easeInCubic: function (x) {
|
|
39
|
+
return x * x * x;
|
|
40
|
+
},
|
|
41
|
+
easeOutCubic: function (x) {
|
|
42
|
+
return 1 - pow(1 - x, 3);
|
|
43
|
+
},
|
|
44
|
+
easeInOutCubic: function (x) {
|
|
45
|
+
return x < 0.5 ? 4 * x * x * x : 1 - pow(-2 * x + 2, 3) / 2;
|
|
46
|
+
},
|
|
47
|
+
easeInQuart: function (x) {
|
|
48
|
+
return x * x * x * x;
|
|
49
|
+
},
|
|
50
|
+
easeOutQuart: function (x) {
|
|
51
|
+
return 1 - pow(1 - x, 4);
|
|
52
|
+
},
|
|
53
|
+
easeInOutQuart: function (x) {
|
|
54
|
+
return x < 0.5 ? 8 * x * x * x * x : 1 - pow(-2 * x + 2, 4) / 2;
|
|
55
|
+
},
|
|
56
|
+
easeInQuint: function (x) {
|
|
57
|
+
return x * x * x * x * x;
|
|
58
|
+
},
|
|
59
|
+
easeOutQuint: function (x) {
|
|
60
|
+
return 1 - pow(1 - x, 5);
|
|
61
|
+
},
|
|
62
|
+
easeInOutQuint: function (x) {
|
|
63
|
+
return x < 0.5 ? 16 * x * x * x * x * x : 1 - pow(-2 * x + 2, 5) / 2;
|
|
64
|
+
},
|
|
65
|
+
easeInSine: function (x) {
|
|
66
|
+
return 1 - cos((x * PI) / 2);
|
|
67
|
+
},
|
|
68
|
+
easeOutSine: function (x) {
|
|
69
|
+
return sin((x * PI) / 2);
|
|
70
|
+
},
|
|
71
|
+
easeInOutSine: function (x) {
|
|
72
|
+
return -(cos(PI * x) - 1) / 2;
|
|
73
|
+
},
|
|
74
|
+
easeInExpo: function (x) {
|
|
75
|
+
return x === 0 ? 0 : pow(2, 10 * x - 10);
|
|
76
|
+
},
|
|
77
|
+
easeOutExpo: function (x) {
|
|
78
|
+
return x === 1 ? 1 : 1 - pow(2, -10 * x);
|
|
79
|
+
},
|
|
80
|
+
easeInOutExpo: function (x) {
|
|
81
|
+
return x === 0
|
|
82
|
+
? 0
|
|
83
|
+
: x === 1
|
|
84
|
+
? 1
|
|
85
|
+
: x < 0.5
|
|
86
|
+
? pow(2, 20 * x - 10) / 2
|
|
87
|
+
: (2 - pow(2, -20 * x + 10)) / 2;
|
|
88
|
+
},
|
|
89
|
+
easeInCirc: function (x) {
|
|
90
|
+
return 1 - sqrt(1 - pow(x, 2));
|
|
91
|
+
},
|
|
92
|
+
easeOutCirc: function (x) {
|
|
93
|
+
return sqrt(1 - pow(x - 1, 2));
|
|
94
|
+
},
|
|
95
|
+
easeInOutCirc: function (x) {
|
|
96
|
+
return x < 0.5
|
|
97
|
+
? (1 - sqrt(1 - pow(2 * x, 2))) / 2
|
|
98
|
+
: (sqrt(1 - pow(-2 * x + 2, 2)) + 1) / 2;
|
|
99
|
+
},
|
|
100
|
+
easeInBack: function (x) {
|
|
101
|
+
return c3 * x * x * x - c1 * x * x;
|
|
102
|
+
},
|
|
103
|
+
easeOutBack: function (x) {
|
|
104
|
+
return 1 + c3 * pow(x - 1, 3) + c1 * pow(x - 1, 2);
|
|
105
|
+
},
|
|
106
|
+
easeInOutBack: function (x) {
|
|
107
|
+
return x < 0.5
|
|
108
|
+
? (pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
|
|
109
|
+
: (pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
|
|
110
|
+
},
|
|
111
|
+
easeInElastic: function (x) {
|
|
112
|
+
return x === 0
|
|
113
|
+
? 0
|
|
114
|
+
: x === 1
|
|
115
|
+
? 1
|
|
116
|
+
: -pow(2, 10 * x - 10) * sin((x * 10 - 10.75) * c4);
|
|
117
|
+
},
|
|
118
|
+
easeOutElastic: function (x) {
|
|
119
|
+
return x === 0
|
|
120
|
+
? 0
|
|
121
|
+
: x === 1
|
|
122
|
+
? 1
|
|
123
|
+
: pow(2, -10 * x) * sin((x * 10 - 0.75) * c4) + 1;
|
|
124
|
+
},
|
|
125
|
+
easeInOutElastic: function (x) {
|
|
126
|
+
return x === 0
|
|
127
|
+
? 0
|
|
128
|
+
: x === 1
|
|
129
|
+
? 1
|
|
130
|
+
: x < 0.5
|
|
131
|
+
? -(pow(2, 20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2
|
|
132
|
+
: (pow(2, -20 * x + 10) * sin((20 * x - 11.125) * c5)) / 2 + 1;
|
|
133
|
+
},
|
|
134
|
+
easeInBounce: function (x) {
|
|
135
|
+
return 1 - bounceOut(1 - x);
|
|
136
|
+
},
|
|
137
|
+
easeOutBounce: bounceOut,
|
|
138
|
+
easeInOutBounce: function (x) {
|
|
139
|
+
return x < 0.5
|
|
140
|
+
? (1 - bounceOut(1 - 2 * x)) / 2
|
|
141
|
+
: (1 + bounceOut(2 * x - 1)) / 2;
|
|
142
|
+
},
|
|
143
|
+
};
|