@stimulus-library/mixins 1.3.0 → 1.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/dist/install_class_methods.js +0 -1
- package/dist/use_dirty_form_tracking.d.ts +9 -0
- package/dist/use_dirty_form_tracking.js +40 -37
- package/dist/use_event_bus.js +1 -1
- package/dist/use_event_listener.js +1 -1
- package/dist/use_geolocation.js +0 -7
- package/dist/use_intersection.js +4 -4
- package/dist/use_localstorage.js +2 -2
- package/dist/use_trix_modifiers.js +0 -4
- package/package.json +6 -6
|
@@ -21,7 +21,6 @@ function addMethodsForClassDefinition(controller, name) {
|
|
|
21
21
|
Object.assign(controller, methods);
|
|
22
22
|
}
|
|
23
23
|
export function installClassMethods(controller) {
|
|
24
|
-
// @ts-ignore
|
|
25
24
|
const classes = controller.constructor.classes || [];
|
|
26
25
|
classes.forEach((classDefinition) => addMethodsForClassDefinition(controller, classDefinition));
|
|
27
26
|
}
|
|
@@ -7,4 +7,13 @@ export declare function useDirtyFormTracking(controller: Controller, form: HTMLF
|
|
|
7
7
|
restore: () => void;
|
|
8
8
|
teardown: () => void;
|
|
9
9
|
};
|
|
10
|
+
export declare function getElementValue(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): boolean | string;
|
|
11
|
+
export declare function getMultiSelectLoadValues(element: HTMLSelectElement): string[];
|
|
12
|
+
export declare function getMultiSelectValues(element: HTMLSelectElement): string[];
|
|
13
|
+
export declare function getElementLoadValue(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): boolean | string;
|
|
14
|
+
export declare function elementHasCachedLoadValue(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): boolean;
|
|
15
|
+
export declare function isElementDirty(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): boolean;
|
|
16
|
+
export declare function restoreElementFromLoadValue(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): void;
|
|
17
|
+
export declare function restoreMultiSelect(element: HTMLSelectElement, cacheValue: string): void;
|
|
18
|
+
export declare function cacheLoadValues(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): void;
|
|
10
19
|
export declare function isDirty(element: HTMLElement): boolean;
|
|
@@ -60,7 +60,34 @@ export function useDirtyFormTracking(controller, form) {
|
|
|
60
60
|
teardown,
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function checkDirty(element) {
|
|
64
|
+
var _a;
|
|
65
|
+
if (isHTMLInputElement(element) && element.type == "radio") {
|
|
66
|
+
getOtherRadiosInGroup(element).forEach((radio) => radio.removeAttribute("data-dirty"));
|
|
67
|
+
}
|
|
68
|
+
if (isElementDirty(element)) {
|
|
69
|
+
element.setAttribute("data-dirty", "true");
|
|
70
|
+
(_a = element.form) === null || _a === void 0 ? void 0 : _a.setAttribute("data-dirty", "true");
|
|
71
|
+
element.dispatchEvent(new CustomEvent("input-dirtied", {
|
|
72
|
+
bubbles: true,
|
|
73
|
+
cancelable: true,
|
|
74
|
+
detail: {
|
|
75
|
+
target: element,
|
|
76
|
+
},
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
element.removeAttribute("data-dirty");
|
|
81
|
+
element.dispatchEvent(new CustomEvent("input-cleaned", {
|
|
82
|
+
bubbles: true,
|
|
83
|
+
cancelable: true,
|
|
84
|
+
detail: {
|
|
85
|
+
target: element,
|
|
86
|
+
},
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export function getElementValue(element) {
|
|
64
91
|
if (isElementCheckable(element)) {
|
|
65
92
|
return element.checked;
|
|
66
93
|
}
|
|
@@ -71,16 +98,16 @@ function getElementValue(element) {
|
|
|
71
98
|
return element.value;
|
|
72
99
|
}
|
|
73
100
|
}
|
|
74
|
-
function getMultiSelectLoadValues(element) {
|
|
101
|
+
export function getMultiSelectLoadValues(element) {
|
|
75
102
|
let options = Array.from(element.options);
|
|
76
103
|
options = options.filter(option => option.defaultSelected);
|
|
77
104
|
return options.map(option => option.value);
|
|
78
105
|
}
|
|
79
|
-
function getMultiSelectValues(element) {
|
|
106
|
+
export function getMultiSelectValues(element) {
|
|
80
107
|
let options = Array.from(element.selectedOptions);
|
|
81
108
|
return options.map(option => option.value);
|
|
82
109
|
}
|
|
83
|
-
function getElementLoadValue(element) {
|
|
110
|
+
export function getElementLoadValue(element) {
|
|
84
111
|
const value = element.getAttribute(CACHE_ATTR_NAME);
|
|
85
112
|
if (isElementCheckable(element)) {
|
|
86
113
|
return value == null ? element.defaultChecked : value == "true";
|
|
@@ -101,39 +128,13 @@ function getElementLoadValue(element) {
|
|
|
101
128
|
}
|
|
102
129
|
return value;
|
|
103
130
|
}
|
|
104
|
-
function elementHasCachedLoadValue(element) {
|
|
131
|
+
export function elementHasCachedLoadValue(element) {
|
|
105
132
|
return element.hasAttribute(CACHE_ATTR_NAME);
|
|
106
133
|
}
|
|
107
|
-
function
|
|
108
|
-
if (isHTMLInputElement(element) && element.type == "radio") {
|
|
109
|
-
getOtherRadiosInGroup(element).forEach((radio) => radio.removeAttribute("data-dirty"));
|
|
110
|
-
}
|
|
111
|
-
if (isElementDirty(element)) {
|
|
112
|
-
element.setAttribute("data-dirty", "true");
|
|
113
|
-
element.form?.setAttribute("data-dirty", "true");
|
|
114
|
-
element.dispatchEvent(new CustomEvent("input-dirtied", {
|
|
115
|
-
bubbles: true,
|
|
116
|
-
cancelable: true,
|
|
117
|
-
detail: {
|
|
118
|
-
target: element,
|
|
119
|
-
},
|
|
120
|
-
}));
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
element.removeAttribute("data-dirty");
|
|
124
|
-
element.dispatchEvent(new CustomEvent("input-cleaned", {
|
|
125
|
-
bubbles: true,
|
|
126
|
-
cancelable: true,
|
|
127
|
-
detail: {
|
|
128
|
-
target: element,
|
|
129
|
-
},
|
|
130
|
-
}));
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
function isElementDirty(element) {
|
|
134
|
+
export function isElementDirty(element) {
|
|
134
135
|
return getElementValue(element) !== getElementLoadValue(element);
|
|
135
136
|
}
|
|
136
|
-
function restoreElementFromLoadValue(element) {
|
|
137
|
+
export function restoreElementFromLoadValue(element) {
|
|
137
138
|
const cacheValue = element.getAttribute(CACHE_ATTR_NAME);
|
|
138
139
|
if (isElementCheckable(element)) {
|
|
139
140
|
element.setAttribute(CACHE_ATTR_NAME, element.checked.toString());
|
|
@@ -157,13 +158,15 @@ function restoreElementFromLoadValue(element) {
|
|
|
157
158
|
}
|
|
158
159
|
checkDirty(element);
|
|
159
160
|
}
|
|
160
|
-
function restoreMultiSelect(element, cacheValue) {
|
|
161
|
+
export function restoreMultiSelect(element, cacheValue) {
|
|
161
162
|
let selectedOptions = JSON.parse(cacheValue);
|
|
162
163
|
Array.from(element.options).forEach((option) => option.selected = selectedOptions.includes(option.value));
|
|
163
164
|
}
|
|
164
|
-
function cacheLoadValues(element) {
|
|
165
|
-
if (
|
|
166
|
-
|
|
165
|
+
export function cacheLoadValues(element) {
|
|
166
|
+
if (isElementCheckable(element)) {
|
|
167
|
+
if (!elementHasCachedLoadValue(element)) {
|
|
168
|
+
element.setAttribute(CACHE_ATTR_NAME, element.checked.toString());
|
|
169
|
+
}
|
|
167
170
|
}
|
|
168
171
|
else if (isHTMLSelectElement(element) && element.multiple) {
|
|
169
172
|
element.setAttribute(CACHE_ATTR_NAME, JSON.stringify(getMultiSelectLoadValues(element)));
|
package/dist/use_event_bus.js
CHANGED
|
@@ -2,7 +2,7 @@ import { debounce, EventBus, wrapArray } from "@stimulus-library/utilities";
|
|
|
2
2
|
import { useMixin } from "./use_mixin";
|
|
3
3
|
export function useEventBus(controller, eventNameOrNames, handler, opts) {
|
|
4
4
|
const options = opts;
|
|
5
|
-
if (options
|
|
5
|
+
if (options === null || options === void 0 ? void 0 : options.debounce) {
|
|
6
6
|
handler = debounce(handler.bind(controller), options.debounce);
|
|
7
7
|
delete options.debounce;
|
|
8
8
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { debounce, wrapArray } from "@stimulus-library/utilities";
|
|
2
2
|
import { useMixin } from "./use_mixin";
|
|
3
3
|
export function useEventListener(controller, element, eventNameOrNames, handler, opts) {
|
|
4
|
-
if (opts
|
|
4
|
+
if (opts === null || opts === void 0 ? void 0 : opts.debounce) {
|
|
5
5
|
handler = debounce(handler.bind(controller), opts.debounce);
|
|
6
6
|
delete opts.debounce;
|
|
7
7
|
}
|
package/dist/use_geolocation.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import { reactive } from "@stimulus-library/utilities";
|
|
2
2
|
import { useMixin } from "./use_mixin";
|
|
3
3
|
export function useGeolocation(controller, options = {}, update, error) {
|
|
4
|
-
// Ensure passed functions are bound to the correct controller scope
|
|
5
4
|
if (update) {
|
|
6
5
|
update = update.bind(controller);
|
|
7
6
|
}
|
|
8
7
|
if (error) {
|
|
9
8
|
error = error.bind(controller);
|
|
10
9
|
}
|
|
11
|
-
// Default options to pass to the navigator.geolocation.watchPosition() method
|
|
12
10
|
const { enableHighAccuracy = true, maximumAge = 30000, timeout = 27000, } = options;
|
|
13
11
|
const isSupported = navigator && "geolocation" in navigator;
|
|
14
|
-
// Create a reactive object to store the geolocation data
|
|
15
12
|
const values = reactive({
|
|
16
13
|
locatedAt: null,
|
|
17
14
|
error: null,
|
|
@@ -34,18 +31,14 @@ export function useGeolocation(controller, options = {}, update, error) {
|
|
|
34
31
|
const setup = () => {
|
|
35
32
|
if (isSupported) {
|
|
36
33
|
watcher = navigator.geolocation.watchPosition((position) => {
|
|
37
|
-
// Update reactive values
|
|
38
34
|
values.locatedAt = position.timestamp;
|
|
39
35
|
values.coords = position.coords;
|
|
40
36
|
values.error = null;
|
|
41
|
-
// Fire user callback if provided
|
|
42
37
|
if (update) {
|
|
43
38
|
update(position);
|
|
44
39
|
}
|
|
45
40
|
}, (err) => {
|
|
46
|
-
// Update reactive values
|
|
47
41
|
values.error = err;
|
|
48
|
-
// Fire user callback if provided
|
|
49
42
|
if (error) {
|
|
50
43
|
error(err);
|
|
51
44
|
}
|
package/dist/use_intersection.js
CHANGED
|
@@ -3,11 +3,11 @@ export function useIntersectionObserver(controller, handler, options) {
|
|
|
3
3
|
handler = handler.bind(controller);
|
|
4
4
|
let observer = new IntersectionObserver(handler, options);
|
|
5
5
|
const teardown = () => {
|
|
6
|
-
observer
|
|
6
|
+
observer === null || observer === void 0 ? void 0 : observer.disconnect();
|
|
7
7
|
observer = null;
|
|
8
8
|
};
|
|
9
|
-
const observe = (element) => observer
|
|
10
|
-
const unobserve = (element) => observer
|
|
9
|
+
const observe = (element) => observer === null || observer === void 0 ? void 0 : observer.observe(element);
|
|
10
|
+
const unobserve = (element) => observer === null || observer === void 0 ? void 0 : observer.unobserve(element);
|
|
11
11
|
return {
|
|
12
12
|
observer,
|
|
13
13
|
teardown,
|
|
@@ -22,7 +22,7 @@ export function useIntersection(controller, element, appear, disappear, options)
|
|
|
22
22
|
if (disappear) {
|
|
23
23
|
disappear = disappear.bind(controller);
|
|
24
24
|
}
|
|
25
|
-
const opts = options
|
|
25
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
26
26
|
const processEntries = (entries) => {
|
|
27
27
|
entries.forEach((entry) => {
|
|
28
28
|
if (entry.isIntersecting) {
|
package/dist/use_localstorage.js
CHANGED
|
@@ -9,7 +9,6 @@ export const StorageSerializers = {
|
|
|
9
9
|
object: {
|
|
10
10
|
deserialize: (v) => JSON.parse(v),
|
|
11
11
|
serialize: (v) => {
|
|
12
|
-
// Change events are triggered with a string value
|
|
13
12
|
if (typeof v === "string") {
|
|
14
13
|
return v;
|
|
15
14
|
}
|
|
@@ -55,6 +54,7 @@ export const StorageSerializers = {
|
|
|
55
54
|
},
|
|
56
55
|
};
|
|
57
56
|
export function useLocalStorage(controller, key, defaultValue, opts) {
|
|
57
|
+
var _a;
|
|
58
58
|
let type;
|
|
59
59
|
const optsMergedWithDefaults = {
|
|
60
60
|
onChange: null,
|
|
@@ -89,7 +89,7 @@ export function useLocalStorage(controller, key, defaultValue, opts) {
|
|
|
89
89
|
else {
|
|
90
90
|
type = "any";
|
|
91
91
|
}
|
|
92
|
-
const onChange = optsMergedWithDefaults.onChange
|
|
92
|
+
const onChange = (_a = optsMergedWithDefaults.onChange) === null || _a === void 0 ? void 0 : _a.bind(controller);
|
|
93
93
|
const data = reactive({
|
|
94
94
|
value: defaultValue,
|
|
95
95
|
});
|
|
@@ -3,7 +3,6 @@ import { Controller } from "@hotwired/stimulus";
|
|
|
3
3
|
export class TrixComposableController extends Controller {
|
|
4
4
|
}
|
|
5
5
|
export function useTrixModifiers(controller) {
|
|
6
|
-
// keep a copy of the lifecycle function of the controller
|
|
7
6
|
const controllerDisconnect = controller.disconnect.bind(controller);
|
|
8
7
|
let observing = false;
|
|
9
8
|
const observerCallback = (entries, observer) => {
|
|
@@ -28,17 +27,14 @@ export function useTrixModifiers(controller) {
|
|
|
28
27
|
editor.addEventListener("trix-paste", pasteHandler);
|
|
29
28
|
const toolbar = editorParent.querySelector("trix-toolbar");
|
|
30
29
|
if (!observing && !toolbar) {
|
|
31
|
-
// toolbar is not in the DOM yet, wait for it to arrive before running setup
|
|
32
30
|
observing = true;
|
|
33
31
|
observer.observe(editorParent, { childList: true });
|
|
34
32
|
return;
|
|
35
33
|
}
|
|
36
34
|
else if (!toolbar) {
|
|
37
|
-
// Fallback, in case this runs twice, or mutation observer logic fails
|
|
38
35
|
throw new Error("Could not find an instance of <trix-toolbar> that is a sibling of this <trix-editor>");
|
|
39
36
|
}
|
|
40
37
|
else {
|
|
41
|
-
// Do not need MutationObserver, all elements are present and correct
|
|
42
38
|
observer.disconnect();
|
|
43
39
|
}
|
|
44
40
|
controllerMethod(controller, "install").call(controller, { toolbar, editor });
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"ruby on rails",
|
|
10
10
|
"ruby-on-rails"
|
|
11
11
|
],
|
|
12
|
-
"version": "1.
|
|
12
|
+
"version": "1.4.0",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "Sub-Xaero",
|
|
@@ -37,12 +37,12 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@hotwired/stimulus": "^3.0.0",
|
|
40
|
-
"@stimulus-library/utilities": "^1.
|
|
40
|
+
"@stimulus-library/utilities": "^1.4.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/chai": "^5.0.1",
|
|
44
44
|
"@types/mocha": "^10.0.1",
|
|
45
|
-
"@types/node": "^
|
|
45
|
+
"@types/node": "^24.0.7",
|
|
46
46
|
"@types/sinon": "^17.0.1",
|
|
47
47
|
"@types/sinon-chai": "^4.0.0",
|
|
48
48
|
"agadoo": "^3.0.0",
|
|
@@ -51,12 +51,12 @@
|
|
|
51
51
|
"lerna": "^8.0.0",
|
|
52
52
|
"mocha": "^11.1.0",
|
|
53
53
|
"rimraf": "^6.0.1",
|
|
54
|
-
"sinon": "^
|
|
54
|
+
"sinon": "^21.0.0",
|
|
55
55
|
"sinon-chai": "^4.0.0",
|
|
56
56
|
"standard-version": "^9.5.0",
|
|
57
57
|
"ts-node": "^10.9.2",
|
|
58
58
|
"typescript": "^5.8.2",
|
|
59
|
-
"vite": "^
|
|
59
|
+
"vite": "^7.0.2"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "81299cf017b9c43a6e1e3bf85dec0d649f2efce4"
|
|
62
62
|
}
|