shadcn_phlexcomponents 0.1.14 → 0.1.16

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/javascript/controllers/accordion_controller.js +107 -0
  3. data/app/javascript/controllers/alert_dialog_controller.js +7 -0
  4. data/app/javascript/controllers/avatar_controller.js +14 -0
  5. data/app/javascript/controllers/checkbox_controller.js +29 -0
  6. data/app/javascript/controllers/collapsible_controller.js +39 -0
  7. data/app/javascript/controllers/combobox_controller.js +278 -0
  8. data/app/javascript/controllers/command_controller.js +207 -0
  9. data/app/javascript/controllers/date_picker_controller.js +258 -0
  10. data/app/javascript/controllers/date_range_picker_controller.js +200 -0
  11. data/app/javascript/controllers/dialog_controller.js +83 -0
  12. data/app/javascript/controllers/dropdown_menu_controller.js +238 -0
  13. data/app/javascript/controllers/dropdown_menu_sub_controller.js +118 -0
  14. data/app/javascript/controllers/form_field_controller.js +20 -0
  15. data/app/javascript/controllers/hover_card_controller.js +73 -0
  16. data/app/javascript/controllers/loading_button_controller.js +14 -0
  17. data/app/javascript/controllers/popover_controller.js +90 -0
  18. data/app/javascript/controllers/progress_controller.js +14 -0
  19. data/app/javascript/controllers/radio_group_controller.js +80 -0
  20. data/app/javascript/controllers/select_controller.js +265 -0
  21. data/app/javascript/controllers/sidebar_controller.js +29 -0
  22. data/app/javascript/controllers/sidebar_trigger_controller.js +15 -0
  23. data/app/javascript/controllers/slider_controller.js +82 -0
  24. data/app/javascript/controllers/switch_controller.js +26 -0
  25. data/app/javascript/controllers/tabs_controller.js +66 -0
  26. data/app/javascript/controllers/theme_switcher_controller.js +32 -0
  27. data/app/javascript/controllers/toast_container_controller.js +48 -0
  28. data/app/javascript/controllers/toast_controller.js +22 -0
  29. data/app/javascript/controllers/toggle_controller.js +20 -0
  30. data/app/javascript/controllers/toggle_group_controller.js +20 -0
  31. data/app/javascript/controllers/tooltip_controller.js +79 -0
  32. data/app/javascript/shadcn_phlexcomponents.js +60 -0
  33. data/app/javascript/utils/command.js +448 -0
  34. data/app/javascript/utils/floating_ui.js +160 -0
  35. data/app/javascript/utils/index.js +288 -0
  36. data/app/{javascript → typescript}/utils/index.ts +7 -0
  37. data/lib/install/install_shadcn_phlexcomponents.rb +10 -3
  38. data/lib/shadcn_phlexcomponents/version.rb +1 -1
  39. metadata +69 -35
  40. /data/app/{javascript → typescript}/controllers/accordion_controller.ts +0 -0
  41. /data/app/{javascript → typescript}/controllers/alert_dialog_controller.ts +0 -0
  42. /data/app/{javascript → typescript}/controllers/avatar_controller.ts +0 -0
  43. /data/app/{javascript → typescript}/controllers/checkbox_controller.ts +0 -0
  44. /data/app/{javascript → typescript}/controllers/collapsible_controller.ts +0 -0
  45. /data/app/{javascript → typescript}/controllers/combobox_controller.ts +0 -0
  46. /data/app/{javascript → typescript}/controllers/command_controller.ts +0 -0
  47. /data/app/{javascript → typescript}/controllers/date_picker_controller.ts +0 -0
  48. /data/app/{javascript → typescript}/controllers/date_range_picker_controller.ts +0 -0
  49. /data/app/{javascript → typescript}/controllers/dialog_controller.ts +0 -0
  50. /data/app/{javascript → typescript}/controllers/dropdown_menu_controller.ts +0 -0
  51. /data/app/{javascript → typescript}/controllers/dropdown_menu_sub_controller.ts +0 -0
  52. /data/app/{javascript → typescript}/controllers/form_field_controller.ts +0 -0
  53. /data/app/{javascript → typescript}/controllers/hover_card_controller.ts +0 -0
  54. /data/app/{javascript → typescript}/controllers/loading_button_controller.ts +0 -0
  55. /data/app/{javascript → typescript}/controllers/popover_controller.ts +0 -0
  56. /data/app/{javascript → typescript}/controllers/progress_controller.ts +0 -0
  57. /data/app/{javascript → typescript}/controllers/radio_group_controller.ts +0 -0
  58. /data/app/{javascript → typescript}/controllers/select_controller.ts +0 -0
  59. /data/app/{javascript → typescript}/controllers/sidebar_controller.ts +0 -0
  60. /data/app/{javascript → typescript}/controllers/sidebar_trigger_controller.ts +0 -0
  61. /data/app/{javascript → typescript}/controllers/slider_controller.ts +0 -0
  62. /data/app/{javascript → typescript}/controllers/switch_controller.ts +0 -0
  63. /data/app/{javascript → typescript}/controllers/tabs_controller.ts +0 -0
  64. /data/app/{javascript → typescript}/controllers/theme_switcher_controller.ts +0 -0
  65. /data/app/{javascript → typescript}/controllers/toast_container_controller.ts +0 -0
  66. /data/app/{javascript → typescript}/controllers/toast_controller.ts +0 -0
  67. /data/app/{javascript → typescript}/controllers/toggle_controller.ts +0 -0
  68. /data/app/{javascript → typescript}/controllers/toggle_group_controller.ts +0 -0
  69. /data/app/{javascript → typescript}/controllers/tooltip_controller.ts +0 -0
  70. /data/app/{javascript → typescript}/shadcn_phlexcomponents.ts +0 -0
  71. /data/app/{javascript → typescript}/utils/command.ts +0 -0
  72. /data/app/{javascript → typescript}/utils/floating_ui.ts +0 -0
@@ -0,0 +1,258 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+ import { useClickOutside } from "stimulus-use";
3
+ import {
4
+ focusTrigger,
5
+ getFocusableElements,
6
+ showContent,
7
+ hideContent,
8
+ lockScroll,
9
+ unlockScroll,
10
+ handleTabNavigation,
11
+ focusElement,
12
+ } from "../utils";
13
+ import { initFloatingUi } from "../utils/floating_ui";
14
+ import { Calendar } from "vanilla-calendar-pro";
15
+ import Inputmask from "inputmask";
16
+ import dayjs from "dayjs";
17
+ import customParseFormat from "dayjs/plugin/customParseFormat";
18
+ import utc from "dayjs/plugin/utc";
19
+ dayjs.extend(customParseFormat);
20
+ dayjs.extend(utc);
21
+ const DAYJS_FORMAT = "YYYY-MM-DD";
22
+ const DatePickerController = class extends Controller {
23
+ // targets
24
+ static targets = [
25
+ "trigger",
26
+ "triggerText",
27
+ "contentContainer",
28
+ "content",
29
+ "input",
30
+ "hiddenInput",
31
+ "inputContainer",
32
+ "calendar",
33
+ "overlay",
34
+ ];
35
+ // values
36
+ static values = { isOpen: Boolean, date: String };
37
+ connect() {
38
+ this.format = this.element.dataset.format || "DD/MM/YYYY";
39
+ this.mask = this.element.dataset.mask === "true";
40
+ this.DOMKeydownListener = this.onDOMKeydown.bind(this);
41
+ this.onClickDateListener = this.onClickDate.bind(this);
42
+ const options = this.getOptions();
43
+ this.calendar = new Calendar(this.calendarTarget, options);
44
+ this.calendar.init();
45
+ if (this.hasInputTarget && this.mask) {
46
+ this.setupInputMask();
47
+ }
48
+ this.calendarTarget.removeAttribute("tabindex");
49
+ useClickOutside(this, {
50
+ element: this.contentTarget,
51
+ dispatchEvent: false,
52
+ });
53
+ }
54
+ contentContainerTargetConnected() {
55
+ // Datepicker is shown as a dialog on small screens
56
+ const styles = window.getComputedStyle(this.contentContainerTarget);
57
+ this.isMobile = styles.translate === "-50%";
58
+ }
59
+ toggle() {
60
+ if (this.isOpenValue) {
61
+ this.close();
62
+ } else {
63
+ this.open();
64
+ }
65
+ }
66
+ open() {
67
+ this.isOpenValue = true;
68
+ }
69
+ close() {
70
+ this.isOpenValue = false;
71
+ }
72
+ inputBlur() {
73
+ let dateDisplay = "";
74
+ const date = this.calendar.context.selectedDates[0];
75
+ if (date) {
76
+ dateDisplay = dayjs(date).format(this.format);
77
+ }
78
+ this.inputTarget.value = dateDisplay;
79
+ this.inputContainerTarget.dataset.focus = "false";
80
+ }
81
+ inputDate(event) {
82
+ const value = event.target.value;
83
+ if (value.length === 0) {
84
+ this.calendar.set({
85
+ selectedDates: [],
86
+ });
87
+ this.dateValue = "";
88
+ }
89
+ if (value.length > 0 && dayjs(value, this.format, true).isValid()) {
90
+ const dayjsDate = dayjs(value, this.format).format(DAYJS_FORMAT);
91
+ this.calendar.set({
92
+ selectedDates: [dayjsDate],
93
+ });
94
+ this.dateValue = dayjsDate;
95
+ }
96
+ }
97
+ setContainerFocus() {
98
+ this.inputContainerTarget.dataset.focus = "true";
99
+ }
100
+ clickOutside(event) {
101
+ const target = event.target;
102
+ // Let trigger handle state
103
+ if (target === this.triggerTarget) return;
104
+ if (this.triggerTarget.contains(target)) return;
105
+ if (this.triggerTarget.id === target.getAttribute("for")) return;
106
+ this.close();
107
+ }
108
+ isOpenValueChanged(isOpen, previousIsOpen) {
109
+ if (isOpen) {
110
+ showContent({
111
+ trigger: this.triggerTarget,
112
+ content: this.contentTarget,
113
+ contentContainer: this.contentContainerTarget,
114
+ });
115
+ // Prevent width from changing when changing to month/year view
116
+ if (!this.contentTarget.dataset.width) {
117
+ const contentWidth = this.contentTarget.offsetWidth;
118
+ this.contentTarget.dataset.width = `${contentWidth}`;
119
+ this.contentTarget.style.maxWidth = `${contentWidth}px`;
120
+ this.contentTarget.style.minWidth = `${contentWidth}px`;
121
+ }
122
+ if (this.isMobile) {
123
+ lockScroll(this.contentTarget.id);
124
+ this.overlayTarget.style.display = "";
125
+ this.overlayTarget.dataset.state = "open";
126
+ } else {
127
+ this.cleanup = initFloatingUi({
128
+ referenceElement: this.hasInputTarget
129
+ ? this.inputTarget
130
+ : this.triggerTarget,
131
+ floatingElement: this.contentContainerTarget,
132
+ side: this.contentTarget.dataset.side,
133
+ align: this.contentTarget.dataset.align,
134
+ sideOffset: 4,
135
+ });
136
+ }
137
+ let elementToFocus = null;
138
+ const focusableElements = getFocusableElements(this.contentTarget);
139
+ const selectedElement = Array.from(focusableElements).find(
140
+ (e) => e.ariaSelected,
141
+ );
142
+ const currentElement = this.contentTarget.querySelector("[aria-current]");
143
+ if (selectedElement) {
144
+ elementToFocus = selectedElement;
145
+ } else if (currentElement) {
146
+ const firstElementChild = currentElement.firstElementChild;
147
+ elementToFocus = firstElementChild;
148
+ } else {
149
+ elementToFocus = focusableElements[0];
150
+ }
151
+ focusElement(elementToFocus);
152
+ this.setupEventListeners();
153
+ } else {
154
+ hideContent({
155
+ trigger: this.triggerTarget,
156
+ content: this.contentTarget,
157
+ contentContainer: this.contentContainerTarget,
158
+ });
159
+ if (this.isMobile) {
160
+ unlockScroll(this.contentTarget.id);
161
+ this.overlayTarget.style.display = "none";
162
+ this.overlayTarget.dataset.state = "closed";
163
+ }
164
+ if (previousIsOpen) {
165
+ focusTrigger(this.triggerTarget);
166
+ }
167
+ this.cleanupEventListeners();
168
+ }
169
+ }
170
+ dateValueChanged(value) {
171
+ if (value && value.length > 0) {
172
+ const dayjsDate = dayjs(value);
173
+ const formattedDate = dayjsDate.format(this.format);
174
+ if (this.hasInputTarget) this.inputTarget.value = formattedDate;
175
+ if (this.hasTriggerTextTarget) {
176
+ this.triggerTarget.dataset.hasValue = "true";
177
+ this.triggerTextTarget.textContent = formattedDate;
178
+ }
179
+ this.hiddenInputTarget.value = dayjsDate.utc().format();
180
+ } else {
181
+ if (this.hasInputTarget) this.inputTarget.value = "";
182
+ if (this.hasTriggerTextTarget) {
183
+ this.triggerTarget.dataset.hasValue = "false";
184
+ if (this.triggerTarget.dataset.placeholder) {
185
+ this.triggerTextTarget.textContent =
186
+ this.triggerTarget.dataset.placeholder;
187
+ } else {
188
+ this.triggerTextTarget.textContent = "";
189
+ }
190
+ }
191
+ this.hiddenInputTarget.value = "";
192
+ }
193
+ }
194
+ disconnect() {
195
+ this.cleanupEventListeners();
196
+ }
197
+ onClickDate(self) {
198
+ const date = self.context.selectedDates[0];
199
+ if (date) {
200
+ this.dateValue = date;
201
+ this.close();
202
+ } else {
203
+ this.dateValue = "";
204
+ }
205
+ }
206
+ setupEventListeners() {
207
+ document.addEventListener("keydown", this.DOMKeydownListener);
208
+ }
209
+ cleanupEventListeners() {
210
+ if (this.cleanup) this.cleanup();
211
+ document.removeEventListener("keydown", this.DOMKeydownListener);
212
+ }
213
+ getOptions() {
214
+ let options = {
215
+ type: "default",
216
+ enableJumpToSelectedDate: true,
217
+ onClickDate: this.onClickDateListener,
218
+ };
219
+ const date = this.element.dataset.value;
220
+ if (date && dayjs(date).isValid()) {
221
+ const dayjsDate = dayjs(date).format(DAYJS_FORMAT);
222
+ options.selectedDates = [dayjsDate];
223
+ }
224
+ try {
225
+ options = {
226
+ ...options,
227
+ ...JSON.parse(this.element.dataset.options || ""),
228
+ };
229
+ } catch {
230
+ // noop
231
+ }
232
+ if (options.selectedDates && options.selectedDates.length > 0) {
233
+ this.dateValue = `${options.selectedDates[0]}`;
234
+ }
235
+ return options;
236
+ }
237
+ onDOMKeydown(event) {
238
+ if (!this.isOpenValue) return;
239
+ const key = event.key;
240
+ if (key === "Escape") {
241
+ this.close();
242
+ } else if (key === "Tab") {
243
+ handleTabNavigation(this.contentTarget, event);
244
+ } else if (
245
+ ["ArrowUp", "ArrowDown", "ArrowRight", "ArrowLeft"].includes(key) &&
246
+ document.activeElement != this.inputTarget
247
+ ) {
248
+ event.preventDefault();
249
+ }
250
+ }
251
+ setupInputMask() {
252
+ const im = new Inputmask(this.format.replace(/[^/]/g, "9"), {
253
+ showMaskOnHover: false,
254
+ });
255
+ im.mask(this.inputTarget);
256
+ }
257
+ };
258
+ export { DatePickerController };
@@ -0,0 +1,200 @@
1
+ import { DatePickerController } from "./date_picker_controller";
2
+ import dayjs from "dayjs";
3
+ import customParseFormat from "dayjs/plugin/customParseFormat";
4
+ import utc from "dayjs/plugin/utc";
5
+ dayjs.extend(customParseFormat);
6
+ dayjs.extend(utc);
7
+ const DELIMITER = " - ";
8
+ const DAYJS_FORMAT = "YYYY-MM-DD";
9
+ const DateRangePickerController = class extends DatePickerController {
10
+ // targets
11
+ static targets = [
12
+ "trigger",
13
+ "triggerText",
14
+ "contentContainer",
15
+ "content",
16
+ "input",
17
+ "hiddenInput",
18
+ "endHiddenInput",
19
+ "inputContainer",
20
+ "calendar",
21
+ "overlay",
22
+ ];
23
+ // values
24
+ static values = {
25
+ isOpen: Boolean,
26
+ date: String,
27
+ endDate: String,
28
+ };
29
+ inputBlur() {
30
+ const dates = this.calendar.context.selectedDates;
31
+ const startDate = dates[0];
32
+ const endDate = dates[1];
33
+ let datesDisplay = "";
34
+ if (startDate) {
35
+ datesDisplay = `${dayjs(startDate).format(this.format)}${DELIMITER}`;
36
+ }
37
+ if (endDate) {
38
+ datesDisplay = `${datesDisplay}${dayjs(endDate).format(this.format)}`;
39
+ }
40
+ this.inputTarget.value = datesDisplay;
41
+ this.inputContainerTarget.dataset.focus = "false";
42
+ }
43
+ inputDate(event) {
44
+ const value = event.target.value;
45
+ const dates = value.split(DELIMITER).filter((d) => d.length > 0);
46
+ if (dates.length > 0) {
47
+ const startDate = dates[0];
48
+ const endDate = dates[1];
49
+ let selectedDates = this.calendar.context.selectedDates;
50
+ if (dayjs(startDate, this.format, true).isValid()) {
51
+ const dayjsDate = dayjs(value, this.format).format(DAYJS_FORMAT);
52
+ selectedDates[0] = dayjsDate;
53
+ }
54
+ if (dayjs(endDate, this.format, true).isValid()) {
55
+ const dayjsDate = dayjs(endDate, this.format).format(DAYJS_FORMAT);
56
+ selectedDates[1] = dayjsDate;
57
+ }
58
+ selectedDates = selectedDates.filter((d) => !!d);
59
+ this.calendar.set({
60
+ selectedDates: selectedDates,
61
+ });
62
+ if (selectedDates[0]) {
63
+ this.dateValue = selectedDates[0];
64
+ }
65
+ if (selectedDates[1]) {
66
+ this.endDateValue = selectedDates[1];
67
+ }
68
+ } else {
69
+ this.calendar.set({
70
+ selectedDates: [],
71
+ });
72
+ this.dateValue = "";
73
+ this.endDateValue = "";
74
+ }
75
+ }
76
+ dateValueChanged(value) {
77
+ this.onClickDateListener = this.onClickDate.bind(this);
78
+ const endDate = this.endDateValue;
79
+ let datesDisplay = "";
80
+ if (value && value.length > 0) {
81
+ const dayjsDate = dayjs(value);
82
+ const formattedDate = dayjsDate.format(this.format);
83
+ this.hiddenInputTarget.value = dayjsDate.utc().format();
84
+ if (endDate) {
85
+ datesDisplay = `${formattedDate}${DELIMITER}${dayjs(endDate).format(this.format)}`;
86
+ } else {
87
+ datesDisplay = `${formattedDate}${DELIMITER}`;
88
+ }
89
+ } else {
90
+ this.hiddenInputTarget.value = "";
91
+ if (endDate) {
92
+ datesDisplay = `${DELIMITER}${dayjs(endDate).format(this.format)}`;
93
+ }
94
+ }
95
+ if (this.hasInputTarget) this.inputTarget.value = datesDisplay;
96
+ if (this.hasTriggerTextTarget) {
97
+ const hasValue = (!!value && value.length > 0) || !!endDate;
98
+ this.triggerTarget.dataset.hasValue = `${hasValue}`;
99
+ if (this.triggerTarget.dataset.placeholder && !hasValue) {
100
+ this.triggerTextTarget.textContent =
101
+ this.triggerTarget.dataset.placeholder;
102
+ } else {
103
+ this.triggerTextTarget.textContent = datesDisplay;
104
+ }
105
+ }
106
+ }
107
+ endDateValueChanged(value) {
108
+ const startDate = this.dateValue;
109
+ let datesDisplay = "";
110
+ if (value && value.length > 0) {
111
+ const dayjsDate = dayjs(value);
112
+ const formattedDate = dayjsDate.format(this.format);
113
+ this.endHiddenInputTarget.value = dayjsDate.utc().format();
114
+ if (startDate) {
115
+ datesDisplay = `${dayjs(startDate).format(this.format)}${DELIMITER}${formattedDate}`;
116
+ } else {
117
+ datesDisplay = `${DELIMITER}${formattedDate}`;
118
+ }
119
+ } else {
120
+ this.endHiddenInputTarget.value = "";
121
+ if (startDate) {
122
+ datesDisplay = `${dayjs(startDate).format(this.format)}${DELIMITER}`;
123
+ }
124
+ }
125
+ if (this.hasInputTarget) this.inputTarget.value = datesDisplay;
126
+ if (this.hasTriggerTextTarget) {
127
+ const hasValue = (!!value && value.length > 0) || !!startDate;
128
+ this.triggerTarget.dataset.hasValue = `${hasValue}`;
129
+ if (this.triggerTarget.dataset.placeholder && !hasValue) {
130
+ this.triggerTextTarget.textContent =
131
+ this.triggerTarget.dataset.placeholder;
132
+ } else {
133
+ this.triggerTextTarget.textContent = datesDisplay;
134
+ }
135
+ }
136
+ }
137
+ getOptions() {
138
+ let options = {
139
+ type: "multiple",
140
+ selectionDatesMode: "multiple-ranged",
141
+ displayMonthsCount: 2,
142
+ monthsToSwitch: 1,
143
+ displayDatesOutside: false,
144
+ enableJumpToSelectedDate: true,
145
+ onClickDate: this.onClickDateListener,
146
+ };
147
+ const selectedDates = [];
148
+ const startDate = this.element.dataset.value;
149
+ const endDate = this.element.dataset.endValue;
150
+ if (startDate && dayjs(startDate).isValid()) {
151
+ const date = dayjs(startDate).format(DAYJS_FORMAT);
152
+ selectedDates.push(date);
153
+ }
154
+ if (endDate && dayjs(endDate).isValid()) {
155
+ const date = dayjs(endDate).format(DAYJS_FORMAT);
156
+ selectedDates.push(date);
157
+ }
158
+ options.selectedDates = selectedDates;
159
+ try {
160
+ options = {
161
+ ...options,
162
+ ...JSON.parse(this.element.dataset.options || ""),
163
+ };
164
+ } catch {
165
+ // noop
166
+ }
167
+ if (options.selectedDates && options.selectedDates.length > 0) {
168
+ this.dateValue = `${options.selectedDates[0]}`;
169
+ if (options.selectedDates[1]) {
170
+ this.endDateValue = `${options.selectedDates[1]}`;
171
+ }
172
+ }
173
+ return options;
174
+ }
175
+ onClickDate(self) {
176
+ const dates = self.context.selectedDates;
177
+ if (dates.length > 0) {
178
+ const startDate = dates[0];
179
+ const endDate = dates[1];
180
+ this.dateValue = startDate;
181
+ if (endDate) {
182
+ this.endDateValue = endDate;
183
+ this.close();
184
+ } else {
185
+ this.endDateValue = "";
186
+ }
187
+ } else {
188
+ this.dateValue = "";
189
+ this.endDateValue = "";
190
+ }
191
+ }
192
+ setupInputMask() {
193
+ const pattern = this.format.replace(/[^\/]/g, "9");
194
+ const im = new Inputmask(`${pattern}${DELIMITER}${pattern}`, {
195
+ showMaskOnHover: false,
196
+ });
197
+ im.mask(this.inputTarget);
198
+ }
199
+ };
200
+ export { DateRangePickerController };
@@ -0,0 +1,83 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+ import {
3
+ focusElement,
4
+ focusTrigger,
5
+ showContent,
6
+ hideContent,
7
+ getFocusableElements,
8
+ anyNestedComponentsOpen,
9
+ handleTabNavigation,
10
+ } from "../utils";
11
+ const DialogController = class extends Controller {
12
+ // targets
13
+ static targets = ["trigger", "content", "overlay"];
14
+ // values
15
+ static values = {
16
+ isOpen: Boolean,
17
+ };
18
+ connect() {
19
+ this.DOMKeydownListener = this.onDOMKeydown.bind(this);
20
+ this.DOMClickListener = this.onDOMClick.bind(this);
21
+ }
22
+ open() {
23
+ this.isOpenValue = true;
24
+ }
25
+ close() {
26
+ this.isOpenValue = false;
27
+ }
28
+ isOpenValueChanged(isOpen, previousIsOpen) {
29
+ if (isOpen) {
30
+ showContent({
31
+ trigger: this.triggerTarget,
32
+ content: this.contentTarget,
33
+ contentContainer: this.contentTarget,
34
+ appendToBody: true,
35
+ overlay: this.overlayTarget,
36
+ });
37
+ const focusableElements = getFocusableElements(this.contentTarget);
38
+ focusElement(focusableElements[0]);
39
+ this.setupEventListeners();
40
+ } else {
41
+ hideContent({
42
+ trigger: this.triggerTarget,
43
+ content: this.contentTarget,
44
+ contentContainer: this.contentTarget,
45
+ overlay: this.overlayTarget,
46
+ });
47
+ if (previousIsOpen) {
48
+ focusTrigger(this.triggerTarget);
49
+ }
50
+ this.cleanupEventListeners();
51
+ }
52
+ }
53
+ disconnect() {
54
+ this.cleanupEventListeners();
55
+ }
56
+ onDOMClick(event) {
57
+ if (!this.isOpenValue) return;
58
+ const target = event.target;
59
+ if (target === this.triggerTarget) return;
60
+ if (this.contentTarget.contains(target)) return;
61
+ const shouldClose = !anyNestedComponentsOpen(this.contentTarget);
62
+ if (shouldClose) this.close();
63
+ }
64
+ onDOMKeydown(event) {
65
+ if (!this.isOpenValue) return;
66
+ const key = event.key;
67
+ if (key === "Escape") {
68
+ const shouldClose = !anyNestedComponentsOpen(this.contentTarget);
69
+ if (shouldClose) this.close();
70
+ } else if (key === "Tab") {
71
+ handleTabNavigation(this.contentTarget, event);
72
+ }
73
+ }
74
+ setupEventListeners() {
75
+ document.addEventListener("keydown", this.DOMKeydownListener);
76
+ document.addEventListener("pointerdown", this.DOMClickListener);
77
+ }
78
+ cleanupEventListeners() {
79
+ document.removeEventListener("keydown", this.DOMKeydownListener);
80
+ document.removeEventListener("pointerdown", this.DOMClickListener);
81
+ }
82
+ };
83
+ export { DialogController };