@unabridged/midwest 0.15.1 → 0.16.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.
@@ -21,6 +21,7 @@ import Chart from '../../../components/midwest/chart_component/chart_component_c
21
21
  export { default as Chart } from '../../../components/midwest/chart_component/chart_component_controller.js';
22
22
  import Range from '../../../components/midwest/form/range_component/range_component_controller.js';
23
23
  import Rating from '../../../components/midwest/rating_component/rating_component_controller.js';
24
+ import Autocomplete from '../../../components/midwest/form/autocomplete_component/autocomplete_component_controller.js';
24
25
 
25
26
  function registerMidwestControllers(application) {
26
27
  application.register("midwest-card", Card);
@@ -42,6 +43,7 @@ function registerMidwestControllers(application) {
42
43
  application.register("midwest-chart", Chart);
43
44
  application.register("midwest-range", Range);
44
45
  application.register("midwest-rating", Rating);
46
+ application.register("midwest-autocomplete", Autocomplete);
45
47
  }
46
48
 
47
49
  export { registerMidwestControllers };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../../../app/assets/javascript/midwest/index.ts"],"sourcesContent":["import Card from '../../../components/midwest/card_component/card_component_controller'\nimport Banner from '../../../components/midwest/banner_component/banner_component_controller'\nimport Input from '../../../components/midwest/form/input_component/input_component_controller'\nimport File from '../../../components/midwest/form/file_component/file_component_controller'\nimport Dropdown from '../../../components/midwest/dropdown_component/dropdown_component_controller'\nimport Prose from '../../../components/midwest/prose_component/prose_component_controller'\nimport Dialog from '../../../components/midwest/dialog_component/dialog_component_controller'\nimport Tabs from '../../../components/midwest/tabs_component/tabs_component_controller'\nimport Tooltip from '../../../components/midwest/tooltip_component/tooltip_component_controller'\nimport Carousel from '../../../components/midwest/carousel_component/carousel_component_controller'\nimport FormLiveSummary from '../../../components/midwest/form/live_summary_component/live_summary_component_controller'\nimport Form from '../../../components/midwest/form/form_controller'\nimport CountdownTimer from '../../../components/midwest/countdown_timer_component/countdown_timer_component_controller'\nimport Badge from '../../../components/midwest/badge_component/badge_component_controller'\nimport Confirmation from '../../../components/midwest/confirmation_component/confirmation_component_controller'\nimport AvatarGroup from '../../../components/midwest/avatar_group_component/avatar_group_component_controller'\nimport Chart from '../../../components/midwest/chart_component/chart_component_controller'\nimport Range from '../../../components/midwest/form/range_component/range_component_controller'\nimport Rating from '../../../components/midwest/rating_component/rating_component_controller'\n/* IMPORTS */\n\nexport { Card, Banner, CountdownTimer, Chart }\n\nexport function registerMidwestControllers (application: any) {\n application.register('midwest-card', Card)\n application.register('midwest-banner', Banner)\n application.register('midwest-countdown-timer', CountdownTimer)\n application.register('midwest-input', Input)\n application.register('midwest-file', File)\n application.register('midwest-dropdown', Dropdown)\n application.register('midwest-prose', Prose)\n application.register('midwest-dialog', Dialog)\n application.register('midwest-tabs', Tabs)\n application.register('midwest-tooltip', Tooltip)\n application.register('midwest-carousel', Carousel)\n application.register('midwest-form-live-summary', FormLiveSummary)\n application.register('midwest-form', Form)\n application.register('midwest-badge', Badge)\n application.register('midwest-confirmation', Confirmation)\n application.register('midwest-avatar-group', AvatarGroup)\n application.register('midwest-chart', Chart)\n application.register('midwest-range', Range)\n application.register('midwest-rating', Rating)\n /* EXPORTS */\n}\n"],"names":["Confirmation"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBO,SAAS,2BAA4B,WAAkB,EAAA;AAC5D,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,kBAAkB,MAAM,CAAA,CAAA;AAC7C,EAAY,WAAA,CAAA,QAAA,CAAS,2BAA2B,cAAc,CAAA,CAAA;AAC9D,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,oBAAoB,QAAQ,CAAA,CAAA;AACjD,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,kBAAkB,MAAM,CAAA,CAAA;AAC7C,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,mBAAmB,OAAO,CAAA,CAAA;AAC/C,EAAY,WAAA,CAAA,QAAA,CAAS,oBAAoB,QAAQ,CAAA,CAAA;AACjD,EAAY,WAAA,CAAA,QAAA,CAAS,6BAA6B,eAAe,CAAA,CAAA;AACjE,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,wBAAwBA,sBAAY,CAAA,CAAA;AACzD,EAAY,WAAA,CAAA,QAAA,CAAS,wBAAwB,WAAW,CAAA,CAAA;AACxD,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,kBAAkB,MAAM,CAAA,CAAA;AAE/C;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../../../app/assets/javascript/midwest/index.ts"],"sourcesContent":["import Card from '../../../components/midwest/card_component/card_component_controller'\nimport Banner from '../../../components/midwest/banner_component/banner_component_controller'\nimport Input from '../../../components/midwest/form/input_component/input_component_controller'\nimport File from '../../../components/midwest/form/file_component/file_component_controller'\nimport Dropdown from '../../../components/midwest/dropdown_component/dropdown_component_controller'\nimport Prose from '../../../components/midwest/prose_component/prose_component_controller'\nimport Dialog from '../../../components/midwest/dialog_component/dialog_component_controller'\nimport Tabs from '../../../components/midwest/tabs_component/tabs_component_controller'\nimport Tooltip from '../../../components/midwest/tooltip_component/tooltip_component_controller'\nimport Carousel from '../../../components/midwest/carousel_component/carousel_component_controller'\nimport FormLiveSummary from '../../../components/midwest/form/live_summary_component/live_summary_component_controller'\nimport Form from '../../../components/midwest/form/form_controller'\nimport CountdownTimer from '../../../components/midwest/countdown_timer_component/countdown_timer_component_controller'\nimport Badge from '../../../components/midwest/badge_component/badge_component_controller'\nimport Confirmation from '../../../components/midwest/confirmation_component/confirmation_component_controller'\nimport AvatarGroup from '../../../components/midwest/avatar_group_component/avatar_group_component_controller'\nimport Chart from '../../../components/midwest/chart_component/chart_component_controller'\nimport Range from '../../../components/midwest/form/range_component/range_component_controller'\nimport Rating from '../../../components/midwest/rating_component/rating_component_controller'\nimport Autocomplete from '../../../components/midwest/form/autocomplete_component/autocomplete_component_controller'\n/* IMPORTS */\n\nexport { Card, Banner, CountdownTimer, Chart }\n\nexport function registerMidwestControllers (application: any) {\n application.register('midwest-card', Card)\n application.register('midwest-banner', Banner)\n application.register('midwest-countdown-timer', CountdownTimer)\n application.register('midwest-input', Input)\n application.register('midwest-file', File)\n application.register('midwest-dropdown', Dropdown)\n application.register('midwest-prose', Prose)\n application.register('midwest-dialog', Dialog)\n application.register('midwest-tabs', Tabs)\n application.register('midwest-tooltip', Tooltip)\n application.register('midwest-carousel', Carousel)\n application.register('midwest-form-live-summary', FormLiveSummary)\n application.register('midwest-form', Form)\n application.register('midwest-badge', Badge)\n application.register('midwest-confirmation', Confirmation)\n application.register('midwest-avatar-group', AvatarGroup)\n application.register('midwest-chart', Chart)\n application.register('midwest-range', Range)\n application.register('midwest-rating', Rating)\n application.register('midwest-autocomplete', Autocomplete)\n /* EXPORTS */\n}\n"],"names":["Confirmation"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAwBO,SAAS,2BAA4B,WAAkB,EAAA;AAC5D,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,kBAAkB,MAAM,CAAA,CAAA;AAC7C,EAAY,WAAA,CAAA,QAAA,CAAS,2BAA2B,cAAc,CAAA,CAAA;AAC9D,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,oBAAoB,QAAQ,CAAA,CAAA;AACjD,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,kBAAkB,MAAM,CAAA,CAAA;AAC7C,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,mBAAmB,OAAO,CAAA,CAAA;AAC/C,EAAY,WAAA,CAAA,QAAA,CAAS,oBAAoB,QAAQ,CAAA,CAAA;AACjD,EAAY,WAAA,CAAA,QAAA,CAAS,6BAA6B,eAAe,CAAA,CAAA;AACjE,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,wBAAwBA,sBAAY,CAAA,CAAA;AACzD,EAAY,WAAA,CAAA,QAAA,CAAS,wBAAwB,WAAW,CAAA,CAAA;AACxD,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,kBAAkB,MAAM,CAAA,CAAA;AAC7C,EAAY,WAAA,CAAA,QAAA,CAAS,wBAAwB,YAAY,CAAA,CAAA;AAE3D;;;;"}
@@ -0,0 +1,262 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+
3
+ class Autocomplete extends Controller {
4
+ static targets = ["input", "dropdown", "list", "tokens", "token", "multipleTokenTemplate", "singleTokenTemplate", "status"];
5
+ static values = {
6
+ options: { type: Array, default: [] },
7
+ url: { type: String, default: "" },
8
+ multiple: { type: Boolean, default: true }
9
+ };
10
+ selectedValues = /* @__PURE__ */ new Map();
11
+ highlightedIndex = -1;
12
+ fetchAbort = null;
13
+ connect() {
14
+ this.loadInitialTokens();
15
+ }
16
+ disconnect() {
17
+ this.fetchAbort?.abort();
18
+ }
19
+ // ── Public actions ─────────────────────────────────────────────────────────
20
+ focusInput() {
21
+ this.inputTarget.focus();
22
+ this.open();
23
+ }
24
+ open() {
25
+ if (this.dropdownTarget.matches(":popover-open"))
26
+ return;
27
+ const query = this.inputTarget.value.trim();
28
+ if (this.urlValue) {
29
+ this.fetch(query);
30
+ } else {
31
+ this.renderOptions(this.filteredOptions(query));
32
+ }
33
+ }
34
+ async search() {
35
+ const query = this.inputTarget.value.trim();
36
+ if (this.urlValue) {
37
+ await this.fetch(query);
38
+ } else {
39
+ this.renderOptions(this.filteredOptions(query));
40
+ }
41
+ this.showDropdown();
42
+ }
43
+ navigate(event) {
44
+ switch (event.key) {
45
+ case "ArrowDown": {
46
+ event.preventDefault();
47
+ if (!this.dropdownTarget.matches(":popover-open"))
48
+ this.open();
49
+ const items = this.visibleOptions();
50
+ this.highlightedIndex = Math.min(this.highlightedIndex + 1, items.length - 1);
51
+ this.syncHighlight(items);
52
+ break;
53
+ }
54
+ case "ArrowUp": {
55
+ event.preventDefault();
56
+ const items = this.visibleOptions();
57
+ this.highlightedIndex = Math.max(this.highlightedIndex - 1, 0);
58
+ this.syncHighlight(items);
59
+ break;
60
+ }
61
+ case "Enter": {
62
+ event.preventDefault();
63
+ const items = this.visibleOptions();
64
+ if (this.highlightedIndex >= 0 && items[this.highlightedIndex]) {
65
+ this.pickItem(items[this.highlightedIndex]);
66
+ }
67
+ break;
68
+ }
69
+ case "Escape":
70
+ this.hideDropdown();
71
+ break;
72
+ case "Backspace":
73
+ if (this.inputTarget.value === "" && this.multipleValue) {
74
+ const entries = Array.from(this.selectedValues.keys());
75
+ if (entries.length > 0)
76
+ this.deselect(entries[entries.length - 1]);
77
+ }
78
+ break;
79
+ }
80
+ }
81
+ visibleOptions() {
82
+ return this.listTarget.querySelectorAll('.midwest-autocomplete-option:not([aria-selected="true"])');
83
+ }
84
+ handleBlur() {
85
+ setTimeout(() => this.hideDropdown(), 150);
86
+ }
87
+ removeToken(event) {
88
+ event.stopPropagation();
89
+ const btn = event.currentTarget;
90
+ const value = btn.dataset.value;
91
+ if (value)
92
+ this.deselect(value);
93
+ }
94
+ // ── Private ────────────────────────────────────────────────────────────────
95
+ get optionIdPrefix() {
96
+ return `ac-opt-${(this.element.dataset.name ?? "field").replace(/\W/g, "-")}`;
97
+ }
98
+ loadInitialTokens() {
99
+ this.tokenTargets.forEach((token) => {
100
+ const value = token.dataset.value ?? "";
101
+ const label = token.querySelector(".value")?.textContent?.trim() ?? value;
102
+ this.selectedValues.set(value, { value, label });
103
+ });
104
+ }
105
+ filteredOptions(query) {
106
+ const q = query.toLowerCase();
107
+ return this.optionsValue.filter(
108
+ (o) => q === "" || o.label.toLowerCase().includes(q) || (o.support?.toLowerCase().includes(q) ?? false)
109
+ );
110
+ }
111
+ async fetch(query) {
112
+ this.fetchAbort?.abort();
113
+ this.fetchAbort = new AbortController();
114
+ this.showLoading();
115
+ try {
116
+ const url = new URL(this.urlValue, window.location.href);
117
+ if (query)
118
+ url.searchParams.set("q", query);
119
+ const res = await globalThis.fetch(url.toString(), {
120
+ signal: this.fetchAbort.signal,
121
+ headers: { Accept: "application/json" }
122
+ });
123
+ const data = await res.json();
124
+ this.renderOptions(data);
125
+ } catch (err) {
126
+ if (err.name !== "AbortError") {
127
+ this.renderEmpty();
128
+ }
129
+ }
130
+ }
131
+ select(option) {
132
+ if (!this.multipleValue) {
133
+ this.selectedValues.forEach((_, val) => this.removeTokenElement(val));
134
+ this.selectedValues.clear();
135
+ }
136
+ this.selectedValues.set(option.value, option);
137
+ this.appendToken(option);
138
+ this.hideDropdown();
139
+ this.inputTarget.value = "";
140
+ this.inputTarget.focus();
141
+ this.announce(`${option.label} selected`);
142
+ this.dispatch("change", { detail: { value: option.value, label: option.label } });
143
+ }
144
+ deselect(value) {
145
+ const option = this.selectedValues.get(value);
146
+ this.selectedValues.delete(value);
147
+ this.removeTokenElement(value);
148
+ if (option)
149
+ this.announce(`${option.label} removed`);
150
+ this.dispatch("change", { detail: { value: null } });
151
+ }
152
+ appendToken(option) {
153
+ const name = this.element.dataset.name ?? "";
154
+ if (this.multipleValue) {
155
+ const fragment = this.multipleTokenTemplateTarget.content.cloneNode(true);
156
+ const badge = fragment.querySelector(".midwest-badge");
157
+ badge.dataset.value = option.value;
158
+ badge.querySelector(".value").textContent = option.label;
159
+ const removeBtn = badge.querySelector(".remove");
160
+ removeBtn.dataset.value = option.value;
161
+ removeBtn.setAttribute("aria-label", `Remove ${option.label}`);
162
+ const input = badge.querySelector("input[type=hidden]");
163
+ input.name = name;
164
+ input.value = option.value;
165
+ this.tokensTarget.appendChild(fragment);
166
+ } else {
167
+ this.tokensTarget.querySelectorAll("[data-value]").forEach((el) => el.remove());
168
+ const fragment = this.singleTokenTemplateTarget.content.cloneNode(true);
169
+ const badge = fragment.querySelector(".midwest-badge");
170
+ badge.dataset.value = option.value;
171
+ badge.querySelector(".value").textContent = option.label;
172
+ const input = badge.querySelector("input[type=hidden]");
173
+ input.name = name;
174
+ input.value = option.value;
175
+ this.tokensTarget.appendChild(fragment);
176
+ }
177
+ }
178
+ removeTokenElement(value) {
179
+ const token = this.tokensTarget.querySelector(`[data-value="${CSS.escape(value)}"]`);
180
+ token?.remove();
181
+ }
182
+ renderOptions(options) {
183
+ this.listTarget.innerHTML = "";
184
+ this.highlightedIndex = -1;
185
+ if (options.length === 0) {
186
+ this.renderEmpty();
187
+ return;
188
+ }
189
+ options.forEach((option, index) => {
190
+ const li = document.createElement("li");
191
+ li.id = `${this.optionIdPrefix}-${index}`;
192
+ li.className = "midwest-autocomplete-option";
193
+ li.setAttribute("role", "option");
194
+ li.setAttribute("aria-selected", this.selectedValues.has(option.value) ? "true" : "false");
195
+ li.dataset.value = option.value;
196
+ li.innerHTML = `
197
+ <span class="midwest-autocomplete-option-label">${this.escapeHtml(option.label)}</span>
198
+ ${option.support ? `<span class="midwest-autocomplete-option-support">${this.escapeHtml(option.support)}</span>` : ""}
199
+ `;
200
+ li.addEventListener("mousedown", (e) => {
201
+ e.preventDefault();
202
+ this.select(option);
203
+ });
204
+ this.listTarget.appendChild(li);
205
+ });
206
+ const availableCount = options.filter((o) => !this.selectedValues.has(o.value)).length;
207
+ if (availableCount === 0) {
208
+ this.renderEmpty("No more options");
209
+ return;
210
+ }
211
+ this.announce(`${availableCount} option${availableCount === 1 ? "" : "s"} available`);
212
+ this.showDropdown();
213
+ }
214
+ renderEmpty(message = "No results") {
215
+ this.listTarget.innerHTML = `<li class="midwest-autocomplete-empty" aria-hidden="true">${this.escapeHtml(message)}</li>`;
216
+ this.announce(message);
217
+ this.showDropdown();
218
+ }
219
+ showLoading() {
220
+ this.listTarget.innerHTML = '<li class="midwest-autocomplete-loading" aria-hidden="true">Loading\u2026</li>';
221
+ this.announce("Loading");
222
+ this.showDropdown();
223
+ }
224
+ showDropdown() {
225
+ if (!this.dropdownTarget.matches(":popover-open"))
226
+ this.dropdownTarget.showPopover();
227
+ this.inputTarget.setAttribute("aria-expanded", "true");
228
+ }
229
+ hideDropdown() {
230
+ if (this.dropdownTarget.matches(":popover-open"))
231
+ this.dropdownTarget.hidePopover();
232
+ this.inputTarget.setAttribute("aria-expanded", "false");
233
+ this.inputTarget.removeAttribute("aria-activedescendant");
234
+ this.highlightedIndex = -1;
235
+ }
236
+ syncHighlight(items) {
237
+ items.forEach((item, i) => item.classList.toggle("is-highlighted", i === this.highlightedIndex));
238
+ const active = items[this.highlightedIndex];
239
+ active?.scrollIntoView({ block: "nearest" });
240
+ if (active) {
241
+ this.inputTarget.setAttribute("aria-activedescendant", active.id);
242
+ } else {
243
+ this.inputTarget.removeAttribute("aria-activedescendant");
244
+ }
245
+ }
246
+ pickItem(item) {
247
+ const value = item.dataset.value ?? "";
248
+ const label = item.querySelector(".midwest-autocomplete-option-label")?.textContent?.trim() ?? value;
249
+ const support = item.querySelector(".midwest-autocomplete-option-support")?.textContent?.trim();
250
+ this.select({ value, label, support });
251
+ }
252
+ announce(message) {
253
+ if (this.hasStatusTarget)
254
+ this.statusTarget.textContent = message;
255
+ }
256
+ escapeHtml(str) {
257
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
258
+ }
259
+ }
260
+
261
+ export { Autocomplete as default };
262
+ //# sourceMappingURL=autocomplete_component_controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autocomplete_component_controller.js","sources":["../../../../../../../../app/components/midwest/form/autocomplete_component/autocomplete_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\ninterface Option {\n value: string\n label: string\n support?: string\n}\n\nexport default class Autocomplete extends Controller<HTMLElement> {\n static targets = ['input', 'dropdown', 'list', 'tokens', 'token', 'multipleTokenTemplate', 'singleTokenTemplate', 'status']\n static values = {\n options: { type: Array, default: [] },\n url: { type: String, default: '' },\n multiple: { type: Boolean, default: true }\n }\n\n declare readonly inputTarget: HTMLInputElement\n declare readonly dropdownTarget: HTMLElement\n declare readonly listTarget: HTMLElement\n declare readonly tokensTarget: HTMLElement\n declare readonly tokenTargets: HTMLElement[]\n declare readonly multipleTokenTemplateTarget: HTMLTemplateElement\n declare readonly singleTokenTemplateTarget: HTMLTemplateElement\n declare readonly statusTarget: HTMLElement\n declare readonly hasStatusTarget: boolean\n\n declare optionsValue: Option[]\n declare urlValue: string\n declare multipleValue: boolean\n\n private selectedValues = new Map<string, Option>()\n private highlightedIndex = -1\n private fetchAbort: AbortController | null = null\n\n connect () {\n this.loadInitialTokens()\n }\n\n disconnect () {\n this.fetchAbort?.abort()\n }\n\n // ── Public actions ─────────────────────────────────────────────────────────\n\n focusInput () {\n this.inputTarget.focus()\n this.open()\n }\n\n open () {\n if (this.dropdownTarget.matches(':popover-open')) return\n const query = this.inputTarget.value.trim()\n if (this.urlValue) {\n this.fetch(query)\n } else {\n this.renderOptions(this.filteredOptions(query))\n }\n }\n\n async search () {\n const query = this.inputTarget.value.trim()\n if (this.urlValue) {\n await this.fetch(query)\n } else {\n this.renderOptions(this.filteredOptions(query))\n }\n this.showDropdown()\n }\n\n navigate (event: KeyboardEvent) {\n switch (event.key) {\n case 'ArrowDown': {\n event.preventDefault()\n if (!this.dropdownTarget.matches(':popover-open')) this.open()\n const items = this.visibleOptions()\n this.highlightedIndex = Math.min(this.highlightedIndex + 1, items.length - 1)\n this.syncHighlight(items)\n break\n }\n\n case 'ArrowUp': {\n event.preventDefault()\n const items = this.visibleOptions()\n this.highlightedIndex = Math.max(this.highlightedIndex - 1, 0)\n this.syncHighlight(items)\n break\n }\n\n case 'Enter': {\n event.preventDefault()\n const items = this.visibleOptions()\n if (this.highlightedIndex >= 0 && items[this.highlightedIndex]) {\n this.pickItem(items[this.highlightedIndex])\n }\n break\n }\n\n case 'Escape':\n this.hideDropdown()\n break\n\n case 'Backspace':\n if (this.inputTarget.value === '' && this.multipleValue) {\n const entries = Array.from(this.selectedValues.keys())\n if (entries.length > 0) this.deselect(entries[entries.length - 1])\n }\n break\n }\n }\n\n private visibleOptions (): NodeListOf<HTMLElement> {\n return this.listTarget.querySelectorAll<HTMLElement>('.midwest-autocomplete-option:not([aria-selected=\"true\"])')\n }\n\n handleBlur () {\n // Delay to let mousedown on an option fire first.\n setTimeout(() => this.hideDropdown(), 150)\n }\n\n removeToken (event: MouseEvent) {\n event.stopPropagation()\n const btn = event.currentTarget as HTMLElement\n const value = btn.dataset.value\n if (value) this.deselect(value)\n }\n\n // ── Private ────────────────────────────────────────────────────────────────\n\n private get optionIdPrefix (): string {\n return `ac-opt-${(this.element.dataset.name ?? 'field').replace(/\\W/g, '-')}`\n }\n\n private loadInitialTokens () {\n this.tokenTargets.forEach(token => {\n const value = token.dataset.value ?? ''\n const label = token.querySelector('.value')?.textContent?.trim() ?? value\n this.selectedValues.set(value, { value, label })\n })\n }\n\n private filteredOptions (query: string): Option[] {\n const q = query.toLowerCase()\n return (this.optionsValue as Option[]).filter(\n o => q === '' || o.label.toLowerCase().includes(q) || (o.support?.toLowerCase().includes(q) ?? false)\n )\n }\n\n private async fetch (query: string) {\n this.fetchAbort?.abort()\n this.fetchAbort = new AbortController()\n\n this.showLoading()\n\n try {\n const url = new URL(this.urlValue, window.location.href)\n if (query) url.searchParams.set('q', query)\n\n const res = await globalThis.fetch(url.toString(), {\n signal: this.fetchAbort.signal,\n headers: { Accept: 'application/json' }\n })\n\n const data: Option[] = await res.json()\n this.renderOptions(data)\n } catch (err) {\n if ((err as Error).name !== 'AbortError') {\n this.renderEmpty()\n }\n }\n }\n\n private select (option: Option) {\n if (!this.multipleValue) {\n // Clear any existing hidden inputs and tokens for single-select\n this.selectedValues.forEach((_, val) => this.removeTokenElement(val))\n this.selectedValues.clear()\n }\n\n this.selectedValues.set(option.value, option)\n this.appendToken(option)\n this.hideDropdown()\n this.inputTarget.value = ''\n this.inputTarget.focus()\n this.announce(`${option.label} selected`)\n\n this.dispatch('change', { detail: { value: option.value, label: option.label } })\n }\n\n private deselect (value: string) {\n const option = this.selectedValues.get(value)\n this.selectedValues.delete(value)\n this.removeTokenElement(value)\n if (option) this.announce(`${option.label} removed`)\n this.dispatch('change', { detail: { value: null } })\n }\n\n private appendToken (option: Option) {\n const name = this.element.dataset.name ?? ''\n\n if (this.multipleValue) {\n const fragment = this.multipleTokenTemplateTarget.content.cloneNode(true) as DocumentFragment\n const badge = fragment.querySelector<HTMLElement>('.midwest-badge')!\n badge.dataset.value = option.value\n badge.querySelector<HTMLElement>('.value')!.textContent = option.label\n const removeBtn = badge.querySelector<HTMLElement>('.remove')!\n removeBtn.dataset.value = option.value\n removeBtn.setAttribute('aria-label', `Remove ${option.label}`)\n const input = badge.querySelector<HTMLInputElement>('input[type=hidden]')!\n input.name = name\n input.value = option.value\n this.tokensTarget.appendChild(fragment)\n } else {\n this.tokensTarget.querySelectorAll<HTMLElement>('[data-value]').forEach(el => el.remove())\n const fragment = this.singleTokenTemplateTarget.content.cloneNode(true) as DocumentFragment\n const badge = fragment.querySelector<HTMLElement>('.midwest-badge')!\n badge.dataset.value = option.value\n badge.querySelector<HTMLElement>('.value')!.textContent = option.label\n const input = badge.querySelector<HTMLInputElement>('input[type=hidden]')!\n input.name = name\n input.value = option.value\n this.tokensTarget.appendChild(fragment)\n }\n }\n\n private removeTokenElement (value: string) {\n const token = this.tokensTarget.querySelector(`[data-value=\"${CSS.escape(value)}\"]`)\n token?.remove()\n }\n\n private renderOptions (options: Option[]) {\n this.listTarget.innerHTML = ''\n this.highlightedIndex = -1\n\n if (options.length === 0) {\n this.renderEmpty()\n return\n }\n\n options.forEach((option, index) => {\n const li = document.createElement('li')\n li.id = `${this.optionIdPrefix}-${index}`\n li.className = 'midwest-autocomplete-option'\n li.setAttribute('role', 'option')\n li.setAttribute('aria-selected', this.selectedValues.has(option.value) ? 'true' : 'false')\n li.dataset.value = option.value\n li.innerHTML = `\n <span class=\"midwest-autocomplete-option-label\">${this.escapeHtml(option.label)}</span>\n ${option.support ? `<span class=\"midwest-autocomplete-option-support\">${this.escapeHtml(option.support)}</span>` : ''}\n `\n li.addEventListener('mousedown', e => {\n e.preventDefault()\n this.select(option)\n })\n this.listTarget.appendChild(li)\n })\n\n const availableCount = options.filter(o => !this.selectedValues.has(o.value)).length\n if (availableCount === 0) {\n this.renderEmpty('No more options')\n return\n }\n this.announce(`${availableCount} option${availableCount === 1 ? '' : 's'} available`)\n this.showDropdown()\n }\n\n private renderEmpty (message = 'No results') {\n this.listTarget.innerHTML = `<li class=\"midwest-autocomplete-empty\" aria-hidden=\"true\">${this.escapeHtml(message)}</li>`\n this.announce(message)\n this.showDropdown()\n }\n\n private showLoading () {\n this.listTarget.innerHTML = '<li class=\"midwest-autocomplete-loading\" aria-hidden=\"true\">Loading…</li>'\n this.announce('Loading')\n this.showDropdown()\n }\n\n private showDropdown () {\n if (!this.dropdownTarget.matches(':popover-open')) this.dropdownTarget.showPopover()\n this.inputTarget.setAttribute('aria-expanded', 'true')\n }\n\n private hideDropdown () {\n if (this.dropdownTarget.matches(':popover-open')) this.dropdownTarget.hidePopover()\n this.inputTarget.setAttribute('aria-expanded', 'false')\n this.inputTarget.removeAttribute('aria-activedescendant')\n this.highlightedIndex = -1\n }\n\n private syncHighlight (items: NodeListOf<HTMLElement>) {\n items.forEach((item, i) => item.classList.toggle('is-highlighted', i === this.highlightedIndex))\n const active = items[this.highlightedIndex]\n active?.scrollIntoView({ block: 'nearest' })\n if (active) {\n this.inputTarget.setAttribute('aria-activedescendant', active.id)\n } else {\n this.inputTarget.removeAttribute('aria-activedescendant')\n }\n }\n\n private pickItem (item: HTMLElement) {\n const value = item.dataset.value ?? ''\n const label = item.querySelector('.midwest-autocomplete-option-label')?.textContent?.trim() ?? value\n const support = item.querySelector('.midwest-autocomplete-option-support')?.textContent?.trim()\n this.select({ value, label, support })\n }\n\n private announce (message: string) {\n if (this.hasStatusTarget) this.statusTarget.textContent = message\n }\n\n private escapeHtml (str: string): string {\n return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,17 +1,23 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
3
  class Input extends Controller {
4
- static targets = ["input"];
4
+ static targets = ["input", "counter"];
5
5
  updateClearButton = null;
6
+ updateCounter = null;
6
7
  connect() {
7
8
  this.applyColor();
8
9
  this.applySearchClear();
10
+ this.applyCounter();
9
11
  }
10
12
  disconnect() {
11
13
  if (this.updateClearButton) {
12
14
  this.inputTarget.removeEventListener("input", this.updateClearButton);
13
15
  this.updateClearButton = null;
14
16
  }
17
+ if (this.updateCounter) {
18
+ this.inputTarget.removeEventListener("input", this.updateCounter);
19
+ this.updateCounter = null;
20
+ }
15
21
  }
16
22
  applyColor() {
17
23
  if (this.inputTarget.type !== "color") {
@@ -21,6 +27,15 @@ class Input extends Controller {
21
27
  this.inputTarget.setAttribute("value", this.inputTarget.value);
22
28
  });
23
29
  }
30
+ applyCounter() {
31
+ if (!this.hasCounterTarget)
32
+ return;
33
+ this.counterTarget.textContent = String(this.inputTarget.value.length);
34
+ this.updateCounter = () => {
35
+ this.counterTarget.textContent = String(this.inputTarget.value.length);
36
+ };
37
+ this.inputTarget.addEventListener("input", this.updateCounter);
38
+ }
24
39
  applySearchClear() {
25
40
  if (this.inputTarget.type !== "search")
26
41
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"input_component_controller.js","sources":["../../../../../../../../app/components/midwest/form/input_component/input_component_controller.ts"],"sourcesContent":["\nimport { Controller } from '@hotwired/stimulus'\n\nexport default class Input extends Controller<HTMLFormElement> {\n static targets = ['input']\n\n declare readonly hasInputTarget: boolean\n declare readonly inputTarget: HTMLInputElement\n declare readonly inputTargets: HTMLInputElement[]\n\n private updateClearButton: (() => void) | null = null\n\n connect () {\n this.applyColor()\n this.applySearchClear()\n }\n\n disconnect () {\n if (this.updateClearButton) {\n this.inputTarget.removeEventListener('input', this.updateClearButton)\n this.updateClearButton = null\n }\n }\n\n applyColor () {\n if (this.inputTarget.type !== 'color') {\n return\n }\n\n this.inputTarget.addEventListener('input', () => {\n this.inputTarget.setAttribute('value', this.inputTarget.value)\n })\n }\n\n private applySearchClear () {\n if (this.inputTarget.type !== 'search') return\n // Browsers that natively render a cancel button (Chrome, Safari, Edge)\n // already handle clearing. Only inject for browsers that don't (Firefox).\n if (CSS.supports('selector(::-webkit-search-cancel-button)')) return\n\n const button = document.createElement('button')\n button.type = 'button'\n button.setAttribute('aria-label', 'Clear search')\n button.classList.add('midwest-input-search-clear')\n button.hidden = this.inputTarget.value.length === 0\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('viewBox', '0 0 24 24')\n svg.setAttribute('fill', 'none')\n svg.setAttribute('stroke', 'currentColor')\n svg.setAttribute('stroke-width', '2')\n svg.setAttribute('aria-hidden', 'true')\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('stroke-linecap', 'round')\n path.setAttribute('stroke-linejoin', 'round')\n path.setAttribute('d', 'M6 18L18 6M6 6l12 12')\n svg.appendChild(path)\n button.appendChild(svg)\n\n const wrapper = document.createElement('div')\n wrapper.classList.add('midwest-input-search-wrapper')\n this.inputTarget.parentElement?.insertBefore(wrapper, this.inputTarget)\n wrapper.appendChild(this.inputTarget)\n wrapper.appendChild(button)\n\n this.updateClearButton = () => {\n button.hidden = this.inputTarget.value.length === 0\n }\n\n this.inputTarget.addEventListener('input', this.updateClearButton)\n\n button.addEventListener('click', () => {\n this.inputTarget.value = ''\n button.hidden = true\n this.inputTarget.dispatchEvent(new Event('input', { bubbles: true }))\n this.inputTarget.focus()\n })\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"input_component_controller.js","sources":["../../../../../../../../app/components/midwest/form/input_component/input_component_controller.ts"],"sourcesContent":["\nimport { Controller } from '@hotwired/stimulus'\n\nexport default class Input extends Controller<HTMLFormElement> {\n static targets = ['input', 'counter']\n\n declare readonly hasInputTarget: boolean\n declare readonly inputTarget: HTMLInputElement\n declare readonly inputTargets: HTMLInputElement[]\n declare readonly hasCounterTarget: boolean\n declare readonly counterTarget: HTMLElement\n\n private updateClearButton: (() => void) | null = null\n private updateCounter: (() => void) | null = null\n\n connect () {\n this.applyColor()\n this.applySearchClear()\n this.applyCounter()\n }\n\n disconnect () {\n if (this.updateClearButton) {\n this.inputTarget.removeEventListener('input', this.updateClearButton)\n this.updateClearButton = null\n }\n if (this.updateCounter) {\n this.inputTarget.removeEventListener('input', this.updateCounter)\n this.updateCounter = null\n }\n }\n\n applyColor () {\n if (this.inputTarget.type !== 'color') {\n return\n }\n\n this.inputTarget.addEventListener('input', () => {\n this.inputTarget.setAttribute('value', this.inputTarget.value)\n })\n }\n\n private applyCounter () {\n if (!this.hasCounterTarget) return\n\n this.counterTarget.textContent = String(this.inputTarget.value.length)\n\n this.updateCounter = () => {\n this.counterTarget.textContent = String(this.inputTarget.value.length)\n }\n\n this.inputTarget.addEventListener('input', this.updateCounter)\n }\n\n private applySearchClear () {\n if (this.inputTarget.type !== 'search') return\n // Browsers that natively render a cancel button (Chrome, Safari, Edge)\n // already handle clearing. Only inject for browsers that don't (Firefox).\n if (CSS.supports('selector(::-webkit-search-cancel-button)')) return\n\n const button = document.createElement('button')\n button.type = 'button'\n button.setAttribute('aria-label', 'Clear search')\n button.classList.add('midwest-input-search-clear')\n button.hidden = this.inputTarget.value.length === 0\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('viewBox', '0 0 24 24')\n svg.setAttribute('fill', 'none')\n svg.setAttribute('stroke', 'currentColor')\n svg.setAttribute('stroke-width', '2')\n svg.setAttribute('aria-hidden', 'true')\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('stroke-linecap', 'round')\n path.setAttribute('stroke-linejoin', 'round')\n path.setAttribute('d', 'M6 18L18 6M6 6l12 12')\n svg.appendChild(path)\n button.appendChild(svg)\n\n const wrapper = document.createElement('div')\n wrapper.classList.add('midwest-input-search-wrapper')\n this.inputTarget.parentElement?.insertBefore(wrapper, this.inputTarget)\n wrapper.appendChild(this.inputTarget)\n wrapper.appendChild(button)\n\n this.updateClearButton = () => {\n button.hidden = this.inputTarget.value.length === 0\n }\n\n this.inputTarget.addEventListener('input', this.updateClearButton)\n\n button.addEventListener('click', () => {\n this.inputTarget.value = ''\n button.hidden = true\n this.inputTarget.dispatchEvent(new Event('input', { bubbles: true }))\n this.inputTarget.focus()\n })\n }\n}\n"],"names":[],"mappings":"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"}