tramway 3.1 → 3.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.
@@ -1,198 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- export default class TramwaySelect extends Controller {
4
- static targets = ["dropdown", "showSelectedArea", "hiddenInput", "caretDown", "caretUp"]
5
-
6
- static values = {
7
- items: Array,
8
- dropdownContainer: String,
9
- itemContainer: String,
10
- selectedItemTemplate: String,
11
- dropdownState: String,
12
- selectedItems: Array,
13
- placeholder: String,
14
- selectAsInput: String,
15
- value: Array,
16
- onChange: String,
17
- multiple: Boolean,
18
- autocomplete: Boolean,
19
- autocompleteInput: String
20
- }
21
-
22
- connect() {
23
- this.dropdownState = 'closed';
24
-
25
- this.items = JSON.parse(this.element.dataset.items).map((item, index) => {
26
- return {
27
- index,
28
- text: item.text,
29
- value: item.value.toString(),
30
- selected: false
31
- }
32
- });
33
-
34
- const initialValues = this.element.dataset.value === undefined ? [] : JSON.parse(this.element.dataset.value);
35
-
36
- initialValues.map((value) => {
37
- const itemIndex = this.items.findIndex(x => x.value.toString() === value.toString());
38
- this.items[itemIndex].selected = true;
39
- })
40
-
41
- this.selectedItems = this.items.filter(item => item.selected);
42
-
43
- this.renderSelectedItems();
44
- }
45
-
46
- renderSelectedItems() {
47
- const allItems = this.fillTemplate(this.element.dataset.selectedItemTemplate, this.selectedItems)
48
-
49
- let content = allItems;
50
-
51
- if (this.autocomplete() && this.selectedItems.length === 0) {
52
- content += this.element.dataset.autocompleteInput;
53
- }
54
-
55
- this.showSelectedAreaTarget.innerHTML = content;
56
- this.showSelectedAreaTarget.insertAdjacentHTML("beforeEnd", this.input());
57
- this.updateInputOptions();
58
- }
59
-
60
- fillTemplate(template, items) {
61
- return items.map((item) => {
62
- return template.replace(/{{text}}/g, item.text).replace(/{{value}}/g, item.value)
63
- }).join('')
64
- }
65
-
66
- closeOnClickOutside(event) {
67
- if (this.dropdownState === 'open' && !this.element.contains(event.target)) {
68
- this.closeDropdown();
69
- }
70
- }
71
-
72
- toggleDropdown() {
73
- if (this.dropdownState === 'closed') {
74
- this.openDropdown();
75
- } else {
76
- this.closeDropdown();
77
- }
78
- }
79
-
80
- rerenderItems() {
81
- this.closeDropdown();
82
- this.openDropdown();
83
- }
84
-
85
- openDropdown() {
86
- this.dropdownState = 'open';
87
- this.dropdownTarget.insertAdjacentHTML("afterend", this.template);
88
-
89
- if (this.dropdown()) {
90
- this.dropdown().addEventListener('click', event => event.stopPropagation());
91
- }
92
-
93
- this.caretDownTarget.classList.add('hidden');
94
- this.caretUpTarget.classList.remove('hidden');
95
- }
96
-
97
- dropdown() {
98
- return this.element.querySelector('#dropdown');
99
- }
100
-
101
- closeDropdown() {
102
- this.dropdownState = 'closed';
103
-
104
- if (this.dropdown()) {
105
- this.dropdown().remove();
106
- }
107
-
108
- const onChange = this.element.dataset.onChange;
109
-
110
- if (onChange) {
111
- const [controllerName, actionName] = onChange.split('#');
112
- const controller = this.application.controllers.find(controller => controller.identifier === controllerName)
113
-
114
- if (controller) {
115
- if (typeof controller[actionName] === 'function') {
116
- controller[actionName]({ target: this.element });
117
- } else {
118
- alert(`Action not found: ${actionName}`); // eslint-disable-line no-undef
119
- }
120
- } else {
121
- alert(`Controller not found: ${controllerName}`); // eslint-disable-line no-undef
122
- }
123
- }
124
-
125
- this.caretDownTarget.classList.remove('hidden');
126
- this.caretUpTarget.classList.add('hidden');
127
- }
128
-
129
- get template() {
130
- return this.element.dataset.dropdownContainer.replace(
131
- /{{content}}/g,
132
- this.fillTemplate(this.element.dataset.itemContainer, this.items.filter(item => !item.selected))
133
- );
134
- }
135
-
136
- toggleItem({ currentTarget }) {
137
- const itemIndex = this.items.findIndex(x => x.value === currentTarget.dataset.value);
138
- const itemSelectedIndex = this.selectedItems.findIndex(x => x.value === currentTarget.dataset.value);
139
-
140
- if (!this.multiple()) {
141
- this.selectedItems = [];
142
- this.items.forEach(item => item.selected = false);
143
- this.closeDropdown()
144
- }
145
-
146
- if (itemSelectedIndex !== -1) {
147
- this.selectedItems = this.selectedItems.filter((_, index) => index !== itemSelectedIndex);
148
- this.items[itemIndex].selected = false;
149
- } else {
150
- this.selectedItems.push(this.items[itemIndex]);
151
- this.items[itemIndex].selected = true;
152
- }
153
-
154
- this.renderSelectedItems();
155
-
156
- if (this.multiple()) {
157
- this.rerenderItems();
158
- }
159
- }
160
-
161
- input() {
162
- const placeholder = this.selectedItems.length > 0 ? '' : this.element.dataset.placeholder;
163
- return this.element.dataset.selectAsInput.replace(/{{placeholder}}/g, placeholder);
164
- }
165
-
166
- updateInputOptions() {
167
- this.hiddenInputTarget.innerHTML = '';
168
- this.selectedItems.forEach(selected => {
169
- const option = document.createElement("option");
170
- option.text = selected.text;
171
- option.value = selected.value;
172
- option.setAttribute("selected", true);
173
- this.hiddenInputTarget.append(option);
174
- });
175
-
176
- this.hiddenInputTarget.value = this.selectedItems.map(item => item.value);
177
- }
178
-
179
- multiple() {
180
- return this.element.dataset.multiple == 'true';
181
- }
182
-
183
- autocomplete() {
184
- return this.element.dataset.autocomplete == 'true';
185
- }
186
-
187
- search(event) {
188
- const searchTerm = event.target.value.toLowerCase();
189
- const filteredItems = this.items.filter(item => item.text.toLowerCase().includes(searchTerm) && !item.selected);
190
- const dropdown = this.dropdown();
191
-
192
- if (dropdown) {
193
- dropdown.innerHTML = this.fillTemplate(this.element.dataset.itemContainer, filteredItems);
194
- }
195
- }
196
- }
197
-
198
- export { TramwaySelect }
@@ -1,36 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- export default class UiCheckbox extends Controller {
4
- static targets = ["input", "button", "indicator"]
5
-
6
- connect() {
7
- this.sync()
8
- }
9
-
10
- toggle(event) {
11
- event.preventDefault()
12
-
13
- if (this.inputTarget.disabled) return
14
-
15
- this.inputTarget.click()
16
- this.sync()
17
- }
18
-
19
- sync() {
20
- const checked = this.inputTarget.checked
21
- const state = checked ? "checked" : "unchecked"
22
-
23
- this.buttonTarget.setAttribute("aria-checked", checked.toString())
24
- this.buttonTarget.dataset.state = state
25
- this.buttonTarget.classList.toggle("border-zinc-50", checked)
26
- this.buttonTarget.classList.toggle("bg-zinc-50", checked)
27
- this.buttonTarget.classList.toggle("text-zinc-950", checked)
28
- this.buttonTarget.classList.toggle("border-zinc-800", !checked)
29
- this.buttonTarget.classList.toggle("bg-zinc-950", !checked)
30
- this.buttonTarget.classList.toggle("text-zinc-50", !checked)
31
- this.indicatorTarget.classList.toggle("hidden", !checked)
32
- this.buttonTarget.toggleAttribute("disabled", this.inputTarget.disabled)
33
- }
34
- }
35
-
36
- export { UiCheckbox }