@csedl/hotwire-svelte-helpers 0.1.0 → 0.1.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.
@@ -0,0 +1,7 @@
1
+ <component name="ProjectDictionaryState">
2
+ <dictionary name="project">
3
+ <words>
4
+ <w>Hotwire</w>
5
+ </words>
6
+ </dictionary>
7
+ </component>
package/README.md CHANGED
@@ -1,44 +1,49 @@
1
- # Stimulus Dropdown
1
+ # Hotwire Svelte Helpers
2
+
3
+ is the successor of the `@csedl/stimulus-dropdown` package
2
4
 
3
5
  Dropdown with stimulus, based on floating-UI.
4
6
 
5
7
  **Links:**
6
- - [Online Demo App](https://stimulus-dropdown.sedlmair.ch/)
7
- - [Ruby Gem: csedl-stimulus-dropdown](https://gitlab.com/sedl/csedl-stimulus-dropdown)
8
+ - [Online Demo App](https://hotwire-svelte-helpers.sedlmair.ch/)
9
+ - [Ruby Gem: csedl-stimulus-dropdownSvelte](https://gitlab.com/sedl/csedl-stimulus-dropdown)
8
10
  - [How we are building a Rails App](https://dev.to/chmich/setup-vite-svelte-inertia-stimulus-bootstrap-foundation-on-rails-7-overview-1bk1)
9
11
 
10
12
  ## Import and config
11
13
 
12
14
  ```javascript
13
- import {StimulusDropdown} from "@csedl/stimulus-dropdown"
14
- StimulusDropdown.debug = false
15
+ import {HotwireSvelteHelpers} from "@csedl/hotwire-svelte-helpers"
16
+ HotwireSvelteHelpers.debug = true
17
+ HotwireSvelteHelpers.initializeOverlays()
15
18
  ```
16
19
 
17
20
  All configurations and their defaults are as follows:
18
21
 
19
22
  ```javascript
20
- debug: false
21
- closeButtonSelector: '.close-button'
22
- dropdownContentSelector: '.content'
23
- // when a data-src attribute is added to the panel, the content-tag is replaced by the result of the xhr-response
24
- tooltipContentSelector: '.content'
25
- // same as dropdownContentSelector
26
- addArrow: true
27
- // add element with id #arrow within the panel, on opening
28
- persistTooltipOnClick: false
29
- // clicking on the tooltip-label causes the tooltip-panel to persist open
30
- // this may mostly be helpful for development, so you may make it environment-dependent
23
+ HotwireSvelteHelpers.initializeOverlays({
24
+ debug: false,
25
+ closeButtonSelector: '.close-button',
26
+ dropdownContentSelector: '.content',
27
+ // when a data-src attribute is added to the panel, the content-tag is replaced by the result of the xhr-response
28
+ tooltipContentSelector: '.content',
29
+ // same as dropdownContentSelector
30
+ addArrow: true,
31
+ // add element with id #arrow within the panel, on opening
32
+ persistTooltipOnClick: false
33
+ // clicking on the tooltip-label causes the tooltip-panel to persist open
34
+ // this may mostly be helpful for development, so you may make it environment-dependent
35
+ })
31
36
  ```
32
37
 
33
38
  ## Example
34
39
 
35
- There is a [online example app](https://stimulus-dropdown.sedlmair.ch/)
40
+ There is a [online example app](https://hotwire-svelte-helpers.sedlmair.ch/)
36
41
 
37
42
  ```html
38
43
  <div data-controller="csedl-dropdown" data-panel-id="dropdown-panel-3h5k7l4">
39
44
  Button
40
45
  </div>
41
- <div id="dropdown-panel-3h5k7l4" class="hide dropdown-panel-example-class">
46
+ <div id="dropdown-panel-3h5k7l4" class="hide dropdownSvelte-panel-example-class">
42
47
  ... any content
43
48
  </div>
44
49
  ```
@@ -53,35 +58,35 @@ There is a [online example app](https://stimulus-dropdown.sedlmair.ch/)
53
58
 
54
59
  ## Close on click outside
55
60
 
56
- When a dropdown is open, it closes when clicking outside a panel.
61
+ When a dropdownSvelte is open, it closes when clicking outside a panel.
57
62
 
58
63
  This behaviour can be stopped on:
59
64
 
60
- - The clicked element or its parent elements has the `data-dropdown-persist` (not: `data-dropdown-persist="false"`) attribute.
65
+ - The clicked element or its parent elements has the `data-dropdownSvelte-persist` (not: `data-dropdownSvelte-persist="false"`) attribute.
61
66
  - the event has the attribute `event.detail.dataDropdownPersist` set to true.
62
67
 
63
68
  ## Flexibility
64
69
 
65
- The functions of this package are intended to give flexibility on various ways building a dropdown.
70
+ The functions of this package are intended to give flexibility on various ways building a dropdownSvelte.
66
71
 
67
72
  - Stimulus Controller with Rails Helper
68
73
  - Example: [Stimulus controller within this package](https://gitlab.com/sedl/csedl-stimulus-dropdown-js/-/blob/main/src/dropdown-controller.js?ref_type=heads)
69
74
  - Stimulus with Svelte component
70
75
  - Example: [Stimulus controller on example app](https://gitlab.com/sedl/stimulusfloatingdropdown/-/blob/main/app/frontend/javascript/svelte-dropdown-controller.js?ref_type=heads)
71
76
 
72
- **Important:** When creating or initializing the dropdown,
77
+ **Important:** When creating or initializing the dropdownSvelte,
73
78
  always call the initialize function before attaching a listener to the panel's close event.
74
79
  The initialize function adds a `close` event listener to the panel that executes the `onPanelClose` function.
75
80
  If your custom close function destroys the panel, this has to be done after the `onPanelClose` is fired by the `close` event.
76
81
 
77
82
  ## Requirements
78
83
 
79
- - The class `dropdown-panel-example-class` must be set to `position: absolute;`.
84
+ - The class `dropdownSvelte-panel-example-class` must be set to `position: absolute;`.
80
85
  - The class `hide` must be set to `display: none;`.
81
86
 
82
87
  ## Options
83
88
 
84
- - If there is an element with ID `arrow` inside the dropdown panel, it is treated as described on [floating-ui](https://floating-ui.com/docs/arrow).
89
+ - If there is an element with ID `arrow` inside the dropdownSvelte panel, it is treated as described on [floating-ui](https://floating-ui.com/docs/arrow).
85
90
  - The `data-placement` attribute on the panel can be used to control positioning, see [floating-ui/placements](https://floating-ui.com/docs/tutorial#placements).
86
91
 
87
92
  ## Events
@@ -109,12 +114,12 @@ Event Triggers on the panel element:
109
114
  If the panels are rendered to a different location than the button (see z-index on [rails-app](https://gitlab.com/sedl/stimulusfloatingdropdown)), within a scrollable (e.g.) container, the button would scroll away from the panel. For such cases, add this both data-attributes to the scrollable element:
110
115
 
111
116
  ```html
112
- <div data-controller="csedl-place-dropdown-panels" data-on="scroll" data-run-after="500" style="overflow: scroll;">
117
+ <div data-controller="csedl-place-dropdownSvelte-panels" data-on="scroll" data-run-after="500" style="overflow: scroll;">
113
118
  ...
114
119
  </div>
115
120
  ```
116
121
 
117
- Now, on scrolling, it searches for all dropdown-buttons (by class-name `has-open-panel`) and triggers the `place-panel` event there.
122
+ Now, on scrolling, it searches for all dropdownSvelte-buttons (by class-name `has-open-panel`) and triggers the `place-panel` event there.
118
123
 
119
124
  **Options**
120
125
 
@@ -151,15 +156,15 @@ makes a tooltip.
151
156
 
152
157
  It adds the class `tooltip-is-visible` to the tooltip label while the tooltip is visible.
153
158
 
154
- `data-src` attribute is working similar to dropdown
159
+ `data-src` attribute is working similar to dropdownSvelte
155
160
 
156
161
  ## Rails Helpers
157
162
 
158
163
  There is a corresponding rails gem, on [GitLab](https://gitlab.com/sedl/csedl-stimulus-dropdown)
159
164
 
160
- ## Stimulus Usage in stimulus-dropdown
165
+ ## Stimulus Usage in stimulus-dropdownSvelte
161
166
 
162
- This package uses Stimulus unconventionally to initialize and toggle external dropdown or tooltip panels
167
+ This package uses Stimulus unconventionally to initialize and toggle external dropdownSvelte or tooltip panels
163
168
  (via data-panel-id) rather than managing child elements within the controller’s scope,
164
169
  as is typical in Stimulus documentation.
165
170
 
package/index.js CHANGED
@@ -1,19 +1,12 @@
1
1
 
2
- import StimulusDropdown from "./src/config.js";
2
+ import HotwireSvelteHelpers from "./src/lib/config.js";
3
+ import { cleanMount, unmountAllDetached } from './src/svelte/cleanMount';
4
+ import {initializeDropdown, onPanelOpen, getOrSetPanelId, debugLog} from './src/lib/utils.js'
3
5
 
4
- import { Application } from "@hotwired/stimulus"
5
- window.Stimulus = Application.start()
6
6
 
7
- // initialize dropdowns
8
- import dc from './src/dropdown-controller'
9
- Stimulus.register('csedl-dropdown', dc)
10
7
 
11
- // initialize tooltips
12
- import ttc from './src/tooltip-controller'
13
- Stimulus.register('csedl-tooltip', ttc)
14
-
15
- // initialize place-panel controller
16
- import ppc from './src/move-panels-controller'
17
- Stimulus.register('csedl-move-panels', ppc)
18
-
19
- export { StimulusDropdown }
8
+ export {
9
+ HotwireSvelteHelpers,
10
+ cleanMount, unmountAllDetached,
11
+ initializeDropdown, onPanelOpen, getOrSetPanelId, debugLog
12
+ }
package/package.json CHANGED
@@ -1,11 +1,17 @@
1
1
  {
2
2
  "name": "@csedl/hotwire-svelte-helpers",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Hotwire + Svelte helpers for Rails: Stimulus floating dropdowns/toolips + Svelte global panels/modals + Rails form error mapping + Turbo-friendly utilities. Build together with the rubygem svelte-on-rails and its npm-package.",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
8
8
  },
9
+ "exports": {
10
+ ".": [
11
+ "./index.js",
12
+ "./src/utils.js"
13
+ ]
14
+ },
9
15
  "repository": {
10
16
  "type": "git",
11
17
  "url": "git+https://gitlab.com/sedl/csedl-hotwire-svelte-helpers"
@@ -20,7 +26,7 @@
20
26
  "bugs": {
21
27
  "url": "https://gitlab.com/sedl/csedl-stimulus-dropdown-js/-/issues"
22
28
  },
23
- "homepage": "https://gitlab.com/sedl/csedl-stimulus-dropdown-js",
29
+ "homepage": "https://gitlab.com/sedl/csedl-hotwire-svelte-helpers",
24
30
  "dependencies": {
25
31
  "@floating-ui/dom": ">=1.5.1",
26
32
  "@hotwired/stimulus": ">=3.2.1"
@@ -0,0 +1,74 @@
1
+ import {debugLog} from "./utils.js";
2
+ import { Application } from "@hotwired/stimulus"
3
+ import dc from '../stimulus/dropdown-controller'
4
+ import ttc from '../stimulus/tooltip-controller'
5
+ import ppc from '../stimulus/move-panels-controller'
6
+
7
+ // DEFAULTS
8
+ let _debug = false;
9
+
10
+ let _close_on_click_outside_listener_added = false;
11
+
12
+ const HotwireSvelteHelpers = {
13
+
14
+ // debug
15
+
16
+ get debug() {
17
+ return _debug;
18
+ },
19
+ set debug(value) {
20
+ if (typeof value !== "boolean") {
21
+ throw new Error("Debug value must be true or false");
22
+ }
23
+ _debug = value;
24
+ debugLog('debugging active')
25
+ },
26
+
27
+ overlays: {
28
+ closeButtonSelector: '.close-button',
29
+ dropdownContentSelector: '.content',
30
+ tooltipContentSelector: '.content',
31
+ addArrow: true,
32
+ persistTooltipOnClick: false,
33
+ closeOnClickOutsideListenerAdded: false,
34
+ },
35
+
36
+ initializeOverlays(options = {}) {
37
+ const overlays = this.overlays;
38
+
39
+ if (options.closeButtonSelector !== undefined) {
40
+ overlays.closeButtonSelector = options.closeButtonSelector;
41
+ }
42
+
43
+ if (options.dropdownContentSelector !== undefined) {
44
+ overlays.dropdownContentSelector = options.dropdownContentSelector;
45
+ }
46
+
47
+ if (options.tooltipContentSelector !== undefined) {
48
+ overlays.tooltipContentSelector = options.tooltipContentSelector;
49
+ }
50
+
51
+ if (options.addArrow !== undefined) {
52
+ overlays.addArrow = options.addArrow;
53
+ }
54
+
55
+ if (options.persistTooltipOnClick !== undefined) {
56
+ overlays.persistTooltipOnClick = options.persistTooltipOnClick;
57
+ }
58
+
59
+ window.Stimulus = Application.start()
60
+
61
+ Stimulus.register('csedl-dropdown', dc)
62
+ Stimulus.register('csedl-tooltip', ttc)
63
+ Stimulus.register('csedl-move-panels', ppc)
64
+
65
+ debugLog('Overlays active, driven by Stimulus')
66
+
67
+ return overlays;
68
+ }
69
+
70
+ };
71
+
72
+ window.HotwireSvelteHelpers = HotwireSvelteHelpers;
73
+
74
+ export default HotwireSvelteHelpers;
@@ -28,7 +28,7 @@ export function getAllOpenPanels(scopeElement) {
28
28
  }
29
29
  }
30
30
 
31
- debugLog(`FOUND ${elements.length} OPEN DROPDOWNS`)
31
+ debugLog(`FOUND ${elements.length} OPEN DROPDOWNS for ${buttons.length} buttons`)
32
32
 
33
33
  return (elements)
34
34
  }
@@ -10,7 +10,7 @@ export function onPanelOpen(event, button) {
10
10
  closeOnOutsideClick(event)
11
11
 
12
12
  // add arrow
13
- if (window.StimulusDropdown.addArrow) {
13
+ if (window.HotwireSvelteHelpers.overlays.addArrow) {
14
14
  if (!panel.querySelector(':scope > #arrow')) {
15
15
  const arrowTag = document.createElement('div');
16
16
  arrowTag.id = 'arrow';
@@ -28,7 +28,7 @@ export function onPanelOpen(event, button) {
28
28
  }
29
29
 
30
30
  // Set status attribute
31
- panel.setAttribute('data-stimulus-dropdown-panel-status', 'open');
31
+ panel.setAttribute('data-stimulus-overlay-panel-status', 'open');
32
32
  button.classList.add('has-open-panel');
33
33
 
34
34
  // Dispatch events
@@ -39,8 +39,8 @@ export function onPanelOpen(event, button) {
39
39
  button.dispatchEvent(buttonOpenEvent);
40
40
 
41
41
  // Add listener for closing on outside click
42
- if (!window.StimulusDropdown.closeOnClickOutsideListenerAdded) {
43
- window.StimulusDropdown.closeOnClickOutsideListenerAdded = true;
42
+ if (!window.HotwireSvelteHelpers.overlays.closeOnClickOutsideListenerAdded) {
43
+ window.HotwireSvelteHelpers.overlays.closeOnClickOutsideListenerAdded = true;
44
44
  window.addEventListener('click', closeOnOutsideClick);
45
45
  debugLog('Listener for close panels on click outside added');
46
46
  }
@@ -58,7 +58,7 @@ export function onPanelOpen(event, button) {
58
58
  } else {
59
59
  const button = document.querySelector(`[data-panel-id="${panel.id}"]`);
60
60
  const ctrl = button.getAttribute('data-controller');
61
- const config = window.StimulusDropdown;
61
+ const config = window.HotwireSvelteHelpers.overlays;
62
62
  const contentSelector = config.dropdownContentSelector;
63
63
 
64
64
  if (ctrl === 'csedl-dropdown' && contentSelector) {
@@ -92,13 +92,13 @@ export function onPanelClose(button) {
92
92
 
93
93
  // Update status attributes
94
94
  button.classList.remove('has-open-panel');
95
- panel.setAttribute('data-stimulus-dropdown-panel-status', 'closed');
95
+ panel.setAttribute('data-stimulus-overlay-panel-status', 'closed');
96
96
 
97
97
  // Remove outside click listener if no panels are open
98
- const openPanels = document.querySelectorAll("[data-stimulus-dropdown-panel-status='open']");
98
+ const openPanels = document.querySelectorAll("[data-stimulus-overlay-panel-status='open']");
99
99
  debugLog(`panel closed, still open: ${openPanels.length}`);
100
- if (window.StimulusDropdown.closeOnClickOutsideListenerAdded && openPanels.length === 0) {
101
- window.StimulusDropdown.closeOnClickOutsideListenerAdded = false;
100
+ if (window.HotwireSvelteHelpers.closeOnClickOutsideListenerAdded && openPanels.length === 0) {
101
+ window.HotwireSvelteHelpers.closeOnClickOutsideListenerAdded = false;
102
102
  window.removeEventListener('click', closeOnOutsideClick);
103
103
  debugLog('Listener for close panels on click outside removed');
104
104
  }
@@ -114,10 +114,10 @@ export function closeOnOutsideClick(ev) {
114
114
  let btn = ev.target;
115
115
  let parentPanelIds = [];
116
116
 
117
- const persistElement = ev.target.closest('[data-dropdown-persist]');
117
+ const persistElement = ev.target.closest('[data-overlay-persist]');
118
118
  if (persistElement) {
119
- if (persistElement.getAttribute('data-dropdown-persist') !== 'false') {
120
- debugLog('closing panel prevented because the target element has attribute "data-dropdown-persist"');
119
+ if (persistElement.getAttribute('data-overlay-persist') !== 'false') {
120
+ debugLog('closing panel prevented because the target element has attribute "data-overlay-persist"');
121
121
  return false;
122
122
  }
123
123
  }
@@ -125,7 +125,7 @@ export function closeOnOutsideClick(ev) {
125
125
  debugLog('closeOnOutsideClick called, event.target:', ev.target);
126
126
 
127
127
  while (true) {
128
- const parentPanel = btn.closest("[data-stimulus-dropdown-panel-status='open']");
128
+ const parentPanel = btn.closest("[data-stimulus-overlay-panel-status='open']");
129
129
  if (parentPanel) {
130
130
  parentPanelIds.push(parentPanel.id);
131
131
  btn = document.querySelector(`[data-panel-id="${parentPanel.id}"]`);
@@ -134,7 +134,7 @@ export function closeOnOutsideClick(ev) {
134
134
  }
135
135
  }
136
136
 
137
- const openPanels = document.querySelectorAll("[data-stimulus-dropdown-panel-status='open']");
137
+ const openPanels = document.querySelectorAll("[data-stimulus-overlay-panel-status='open']");
138
138
  for (const panel of openPanels) {
139
139
  if (!parentPanelIds.includes(panel.id)) {
140
140
  const ev = new Event('close');
@@ -157,7 +157,7 @@ export function initializeDropdown(button) {
157
157
  }
158
158
 
159
159
  // Add close button functionality
160
- const selector = window.StimulusDropdown.closeButtonSelector;
160
+ const selector = window.HotwireSvelteHelpers.overlays.closeButtonSelector;
161
161
  const closeButtons = panel.querySelectorAll(selector);
162
162
  for (const btn of closeButtons) {
163
163
  btn.addEventListener('click', () => {
@@ -179,13 +179,13 @@ export function initializeDropdown(button) {
179
179
  // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
180
180
 
181
181
  export function debugLog(message, object) {
182
- if (window.StimulusDropdown.debug) {
182
+ if (window.HotwireSvelteHelpers.debug) {
183
183
 
184
184
  if (object) {
185
- console.log(`[stimulus-dropdown] ${message}`, object);
185
+ console.log(`[HSH] ${message}`, object);
186
186
 
187
187
  } else {
188
- console.log(`[stimulus-dropdown] ${message}`);
188
+ console.log(`[HSH] ${message}`);
189
189
  }
190
190
 
191
191
  }
@@ -1,6 +1,6 @@
1
1
  import {Controller} from "@hotwired/stimulus"
2
- import {initializeDropdown, onPanelOpen} from "./utils.js";
3
- import {debugLog} from "./utils.js";
2
+ import {initializeDropdown, onPanelOpen} from "../lib/utils.js";
3
+ import {debugLog} from "../lib/utils.js";
4
4
 
5
5
  export default class extends Controller {
6
6
 
@@ -10,6 +10,8 @@ export default class extends Controller {
10
10
 
11
11
  this.element.addEventListener('click', (e) => this.toggle(e))
12
12
 
13
+ debugLog('dropdown connected')
14
+
13
15
  }
14
16
 
15
17
 
@@ -1,6 +1,6 @@
1
1
  import {Controller} from "@hotwired/stimulus"
2
- import {positionAllPanels, getAllOpenPanels} from "./floating-ui-functions";
3
- import {debugLog} from "./utils.js";
2
+ import {positionAllPanels, getAllOpenPanels} from "../lib/floating-ui-functions";
3
+ import {debugLog} from "../lib/utils.js";
4
4
 
5
5
  export default class extends Controller {
6
6
 
@@ -1,6 +1,6 @@
1
1
  import {Controller} from "@hotwired/stimulus"
2
- import {positionPanelByButton} from "./floating-ui-functions.js";
3
- import {debugLog, onPanelOpen} from "./utils.js";
2
+ import {positionPanelByButton} from "../lib/floating-ui-functions.js";
3
+ import {debugLog, onPanelOpen} from "../lib/utils.js";
4
4
 
5
5
  export default class extends Controller {
6
6
 
@@ -17,7 +17,7 @@ export default class extends Controller {
17
17
  }
18
18
  this.element.addEventListener('mouseenter', (e) => this.start_opening(e, panel_id, delay_sec * 1000))
19
19
  this.element.addEventListener('mouseleave', (e) => this.close(e, panel_id))
20
- if (window.StimulusDropdown.persistTooltipOnClick) {
20
+ if (window.HotwireSvelteHelpers.persistTooltipOnClick) {
21
21
  this.element.addEventListener('click', (e) => this.toggleByClick(e, panel_id))
22
22
  }
23
23
  }
@@ -0,0 +1,80 @@
1
+ import { mount, unmount } from 'svelte';
2
+ import { debugLog } from '../lib/utils.js';
3
+
4
+ const mountedByTarget = new WeakMap();
5
+ const trackedTargets = new Set();
6
+
7
+ function getTargetRecordList(target) {
8
+ let records = mountedByTarget.get(target);
9
+
10
+ if (!records) {
11
+ records = [];
12
+ mountedByTarget.set(target, records);
13
+ trackedTargets.add(target);
14
+ }
15
+
16
+ return records;
17
+ }
18
+
19
+ export function cleanMount(component, options = {}) {
20
+
21
+ if (!options.target) {
22
+ throw new Error('[HSH] cleanMount: target is required');
23
+ }
24
+
25
+ if (!component) {
26
+ throw new Error('[HSH] cleanMount: component is required');
27
+ }
28
+
29
+ const instance = mount(component, options);
30
+
31
+ const records = getTargetRecordList(options.target);
32
+ records.push({
33
+ target: options.target,
34
+ component: component,
35
+ instance: instance
36
+ });
37
+
38
+ debugLog(`cleanMount: mounted, stored: ${records.length} components`, instance)
39
+
40
+ return instance;
41
+ }
42
+
43
+ export function unmountAllDetached() {
44
+ let unmountedCount = 0;
45
+
46
+ for (const target of Array.from(trackedTargets)) {
47
+ const records = mountedByTarget.get(target);
48
+
49
+ if (!records || records.length === 0) {
50
+ trackedTargets.delete(target);
51
+ mountedByTarget.delete(target);
52
+ continue;
53
+ }
54
+
55
+ if (target.isConnected) {
56
+ continue;
57
+ }
58
+
59
+ for (const record of records) {
60
+ try {
61
+ unmount(record.instance);
62
+ unmountedCount++;
63
+ } catch (error) {
64
+ console.error('[HSH] unmountAllDetached: failed to unmount component', error);
65
+ }
66
+ }
67
+
68
+ records.length = 0;
69
+ trackedTargets.delete(target);
70
+ mountedByTarget.delete(target);
71
+ }
72
+
73
+ if (unmountedCount === 0) {
74
+ debugLog('unmountAllDetached: nothing to unmount')
75
+ } else {
76
+ debugLog(`unmountAllDetached: unmounted ${unmountedCount} components`)
77
+ }
78
+
79
+ return unmountedCount;
80
+ }
package/src/config.js DELETED
@@ -1,114 +0,0 @@
1
- import {debugLog} from "./utils.js";
2
-
3
- // DEFAULTS
4
- let _debug = false;
5
- let _close_button_selector = '.close-button';
6
- let _dropdown_content_selector = '.content';
7
- let _tooltip_content_selector = '.content';
8
- let _add_arrow = true;
9
- let _persist_tooltip_on_click = false;
10
-
11
- let _close_on_click_outside_listener_added = false;
12
-
13
- const StimulusDropdown = {
14
-
15
- // debug
16
-
17
- get debug() {
18
- return _debug;
19
- },
20
- set debug(value) {
21
- if (typeof value !== "boolean") {
22
- throw new Error("Debug value must be true or false");
23
- }
24
- _debug = value;
25
- debugLog('debugging active')
26
- },
27
-
28
- // close button selector
29
-
30
- get closeButtonSelector() {
31
- return _close_button_selector;
32
- },
33
- set closeButtonSelector(string) {
34
- if (typeof string !== "string") {
35
- throw new Error("Close Button Selector must be a string");
36
- }
37
- _close_button_selector = string;
38
- debugLog(`close button selector is: «${string}»`);
39
- },
40
-
41
- // content selector
42
-
43
- get dropdownContentSelector() {
44
- return _dropdown_content_selector;
45
- },
46
- set dropdownContentSelector(string) {
47
- if (typeof string !== "string") {
48
- throw new Error("Content Selector must be a string");
49
- }
50
- _dropdown_content_selector = string;
51
- debugLog(`dropdown content selector is: «${string}»`);
52
- },
53
-
54
- // tooltip content selector
55
-
56
- get tooltipContentSelector() {
57
- return _tooltip_content_selector;
58
- },
59
- set tooltipContentSelector(string) {
60
- if (typeof string !== "string") {
61
- throw new Error("Tooltip Content Selector must be a string");
62
- }
63
- _tooltip_content_selector = string;
64
- debugLog(`tooltip content selector is: «${string}»`);
65
- },
66
-
67
- // add arrow
68
-
69
- get addArrow() {
70
- return _add_arrow;
71
- },
72
- set addArrow(boolean) {
73
- if (typeof boolean !== "boolean") {
74
- throw new Error("Tooltip Content Selector must be a string");
75
- }
76
- _add_arrow = boolean;
77
- debugLog(`add-arrow is set to: «${boolean}»`);
78
- },
79
-
80
- // add arrow
81
-
82
- get persistTooltipOnClick() {
83
- return _persist_tooltip_on_click;
84
- },
85
- set persistTooltipOnClick(boolean) {
86
- if (typeof boolean !== "boolean") {
87
- throw new Error("Tooltip Content Selector must be a string");
88
- }
89
- _persist_tooltip_on_click = boolean;
90
- debugLog(`Persist tooltip on click is set to: «${boolean}»`);
91
- },
92
-
93
- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
94
- // INTERNAL USE
95
- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
96
-
97
- // closeOnClickOutsideListenerAdded
98
-
99
- get closeOnClickOutsideListenerAdded() {
100
- return _close_on_click_outside_listener_added;
101
- },
102
- set closeOnClickOutsideListenerAdded(bool) {
103
- if (typeof bool !== "boolean") {
104
- throw new Error("closeOnClickOutsideListenerAdded must be a boolean");
105
- }
106
- _close_on_click_outside_listener_added = bool;
107
- debugLog(`closeOnClickOutsideListenerAdded is: «${bool}»`);
108
- },
109
-
110
- };
111
-
112
- window.StimulusDropdown = StimulusDropdown;
113
-
114
- export default StimulusDropdown;