@stimulus-library/mixins 1.2.2 → 1.3.1

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.
@@ -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
  }
@@ -61,15 +61,35 @@ export function useDirtyFormTracking(controller, form) {
61
61
  };
62
62
  }
63
63
  function getElementValue(element) {
64
- return isElementCheckable(element) ? element.checked : element.value;
64
+ if (isElementCheckable(element)) {
65
+ return element.checked;
66
+ }
67
+ else if (isHTMLSelectElement(element) && element.multiple) {
68
+ return JSON.stringify(getMultiSelectValues(element));
69
+ }
70
+ else {
71
+ return element.value;
72
+ }
73
+ }
74
+ function getMultiSelectLoadValues(element) {
75
+ let options = Array.from(element.options);
76
+ options = options.filter(option => option.defaultSelected);
77
+ return options.map(option => option.value);
78
+ }
79
+ function getMultiSelectValues(element) {
80
+ let options = Array.from(element.selectedOptions);
81
+ return options.map(option => option.value);
65
82
  }
66
83
  function getElementLoadValue(element) {
67
84
  const value = element.getAttribute(CACHE_ATTR_NAME);
68
85
  if (isElementCheckable(element)) {
69
86
  return value == null ? element.defaultChecked : value == "true";
70
87
  }
71
- else if (isHTMLSelectElement(element)) {
88
+ else if (isHTMLSelectElement(element) && value == null) {
72
89
  const options = Array.from(element.options);
90
+ if (element.multiple) {
91
+ return JSON.stringify(getMultiSelectLoadValues(element));
92
+ }
73
93
  options.forEach((option) => {
74
94
  if (option.defaultSelected) {
75
95
  return option.value;
@@ -85,12 +105,13 @@ function elementHasCachedLoadValue(element) {
85
105
  return element.hasAttribute(CACHE_ATTR_NAME);
86
106
  }
87
107
  function checkDirty(element) {
108
+ var _a;
88
109
  if (isHTMLInputElement(element) && element.type == "radio") {
89
110
  getOtherRadiosInGroup(element).forEach((radio) => radio.removeAttribute("data-dirty"));
90
111
  }
91
112
  if (isElementDirty(element)) {
92
113
  element.setAttribute("data-dirty", "true");
93
- element.form?.setAttribute("data-dirty", "true");
114
+ (_a = element.form) === null || _a === void 0 ? void 0 : _a.setAttribute("data-dirty", "true");
94
115
  element.dispatchEvent(new CustomEvent("input-dirtied", {
95
116
  bubbles: true,
96
117
  cancelable: true,
@@ -124,23 +145,30 @@ function restoreElementFromLoadValue(element) {
124
145
  const options = Array.from(element.options);
125
146
  options.forEach((option) => {
126
147
  if (option.defaultSelected) {
127
- element.value = option.value;
128
- return;
148
+ option.selected = true;
129
149
  }
130
150
  });
131
151
  }
132
152
  else {
133
- element.value = cacheValue;
153
+ element.multiple ? restoreMultiSelect(element, cacheValue) : element.value = cacheValue;
134
154
  }
135
155
  }
136
156
  else {
137
157
  element.value = cacheValue == null ? element.defaultValue : cacheValue;
138
158
  }
159
+ checkDirty(element);
160
+ }
161
+ function restoreMultiSelect(element, cacheValue) {
162
+ let selectedOptions = JSON.parse(cacheValue);
163
+ Array.from(element.options).forEach((option) => option.selected = selectedOptions.includes(option.value));
139
164
  }
140
165
  function cacheLoadValues(element) {
141
166
  if (!elementHasCachedLoadValue(element) && isElementCheckable(element)) {
142
167
  element.setAttribute(CACHE_ATTR_NAME, element.checked.toString());
143
168
  }
169
+ else if (isHTMLSelectElement(element) && element.multiple) {
170
+ element.setAttribute(CACHE_ATTR_NAME, JSON.stringify(getMultiSelectLoadValues(element)));
171
+ }
144
172
  else {
145
173
  element.setAttribute(CACHE_ATTR_NAME, element.value.toString());
146
174
  }
@@ -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?.debounce) {
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?.debounce) {
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
  }
@@ -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
  }
@@ -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?.disconnect();
6
+ observer === null || observer === void 0 ? void 0 : observer.disconnect();
7
7
  observer = null;
8
8
  };
9
- const observe = (element) => observer?.observe(element);
10
- const unobserve = (element) => observer?.unobserve(element);
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) {
@@ -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?.bind(controller);
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.2.2",
12
+ "version": "1.3.1",
13
13
  "license": "MIT",
14
14
  "author": {
15
15
  "name": "Sub-Xaero",
@@ -37,25 +37,26 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@hotwired/stimulus": "^3.0.0",
40
- "@stimulus-library/utilities": "^1.2.1"
40
+ "@stimulus-library/utilities": "^1.3.1"
41
41
  },
42
42
  "devDependencies": {
43
- "@types/chai": "^4.3.5",
43
+ "@types/chai": "^5.0.1",
44
44
  "@types/mocha": "^10.0.1",
45
+ "@types/node": "^22.13.17",
45
46
  "@types/sinon": "^17.0.1",
46
- "@types/sinon-chai": "^3.2.9",
47
+ "@types/sinon-chai": "^4.0.0",
47
48
  "agadoo": "^3.0.0",
48
49
  "chai": "^5.1.1",
49
50
  "fast-glob": "^3.2.12",
50
51
  "lerna": "^8.0.0",
51
- "mocha": "^10.2.0",
52
+ "mocha": "^11.1.0",
52
53
  "rimraf": "^6.0.1",
53
- "sinon": "^18.0.0",
54
+ "sinon": "^20.0.0",
54
55
  "sinon-chai": "^4.0.0",
55
56
  "standard-version": "^9.5.0",
56
- "ts-node": "^10.9.1",
57
- "typescript": "^5.1.3",
58
- "vite": "^5.0.2"
57
+ "ts-node": "^10.9.2",
58
+ "typescript": "^5.8.2",
59
+ "vite": "^6.2.4"
59
60
  },
60
- "gitHead": "ba6fdce82a376a368600b3793c8ea01d6cfb6e04"
61
+ "gitHead": "0e40d14436b1c5541e9ad6d73553041f9c60cceb"
61
62
  }