@vertz/ui-primitives 0.2.16 → 0.2.18

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 (117) hide show
  1. package/dist/shared/chunk-18y8gfk0.js +308 -0
  2. package/dist/shared/chunk-4085nbdq.js +196 -0
  3. package/dist/shared/chunk-4da5zksy.js +46 -0
  4. package/dist/shared/chunk-7ffg0caj.js +265 -0
  5. package/dist/shared/{chunk-w06tst6x.js → chunk-7kpsyjd7.js} +9 -5
  6. package/dist/shared/chunk-7krvqrwq.js +177 -0
  7. package/dist/shared/chunk-8ak7vdk1.js +151 -0
  8. package/dist/shared/chunk-8nk0ya7a.js +163 -0
  9. package/dist/shared/chunk-8tvzqry6.js +218 -0
  10. package/dist/shared/{chunk-qpfqyrc5.js → chunk-96d9nr7y.js} +1 -1
  11. package/dist/shared/chunk-9hj9p7s2.js +95 -0
  12. package/dist/shared/chunk-avxcmmk6.js +178 -0
  13. package/dist/shared/chunk-bew4bjgf.js +165 -0
  14. package/dist/shared/chunk-dpsgb1xw.js +18 -0
  15. package/dist/shared/chunk-g9qvd20g.js +133 -0
  16. package/dist/shared/chunk-gkddsbmh.js +73 -0
  17. package/dist/shared/chunk-gt0wth9h.js +128 -0
  18. package/dist/shared/chunk-hr9hx58m.js +71 -0
  19. package/dist/shared/{chunk-n92bvn5d.js → chunk-j4cm8avr.js} +85 -59
  20. package/dist/shared/chunk-jz0s6srh.js +161 -0
  21. package/dist/shared/chunk-kg27s15c.js +282 -0
  22. package/dist/shared/chunk-m1ptgp1s.js +142 -0
  23. package/dist/shared/{chunk-9cqe2q6e.js → chunk-n9nwx58j.js} +9 -5
  24. package/dist/shared/chunk-ppcv3ehd.js +85 -0
  25. package/dist/shared/{chunk-vq9tfzh8.js → chunk-rnjm61t0.js} +5 -1
  26. package/dist/shared/chunk-sqs8kyb2.js +288 -0
  27. package/dist/shared/chunk-tfyg0qrp.js +117 -0
  28. package/dist/shared/chunk-ttsyf6ma.js +239 -0
  29. package/dist/shared/chunk-x0we8gcy.js +219 -0
  30. package/dist/shared/{chunk-6pnjrst7.js → chunk-x2hz98qn.js} +2 -2
  31. package/dist/shared/chunk-yr9yzpvq.js +107 -0
  32. package/dist/src/accordion/accordion.d.ts +14 -2
  33. package/dist/src/accordion/accordion.js +2 -1
  34. package/dist/src/badge/badge.d.ts +13 -1
  35. package/dist/src/badge/badge.js +2 -1
  36. package/dist/src/button/button.d.ts +16 -14
  37. package/dist/src/button/button.js +2 -2
  38. package/dist/src/calendar/calendar.d.ts +14 -2
  39. package/dist/src/calendar/calendar.js +2 -1
  40. package/dist/src/carousel/carousel.d.ts +14 -2
  41. package/dist/src/carousel/carousel.js +2 -1
  42. package/dist/src/checkbox/checkbox.d.ts +15 -13
  43. package/dist/src/checkbox/checkbox.js +2 -2
  44. package/dist/src/collapsible/collapsible.d.ts +14 -2
  45. package/dist/src/collapsible/collapsible.js +2 -1
  46. package/dist/src/combobox/combobox.d.ts +14 -2
  47. package/dist/src/combobox/combobox.js +2 -1
  48. package/dist/src/command/command.d.ts +14 -2
  49. package/dist/src/command/command.js +2 -1
  50. package/dist/src/context-menu/context-menu.d.ts +14 -2
  51. package/dist/src/context-menu/context-menu.js +2 -1
  52. package/dist/src/date-picker/date-picker.js +4 -3
  53. package/dist/src/dialog/dialog.d.ts +14 -2
  54. package/dist/src/dialog/dialog.js +2 -1
  55. package/dist/src/dropdown-menu/dropdown-menu.d.ts +13 -1
  56. package/dist/src/dropdown-menu/dropdown-menu.js +3 -2
  57. package/dist/src/hover-card/hover-card.d.ts +14 -2
  58. package/dist/src/hover-card/hover-card.js +2 -1
  59. package/dist/src/index.d.ts +132 -140
  60. package/dist/src/index.js +31 -30
  61. package/dist/src/menu/menu.d.ts +14 -2
  62. package/dist/src/menu/menu.js +2 -1
  63. package/dist/src/menubar/menubar.d.ts +14 -2
  64. package/dist/src/menubar/menubar.js +2 -1
  65. package/dist/src/navigation-menu/navigation-menu.d.ts +14 -2
  66. package/dist/src/navigation-menu/navigation-menu.js +2 -1
  67. package/dist/src/popover/popover.d.ts +14 -2
  68. package/dist/src/popover/popover.js +2 -1
  69. package/dist/src/progress/progress.d.ts +14 -2
  70. package/dist/src/progress/progress.js +2 -1
  71. package/dist/src/radio/radio.d.ts +14 -2
  72. package/dist/src/radio/radio.js +2 -1
  73. package/dist/src/resizable-panel/resizable-panel.d.ts +14 -2
  74. package/dist/src/resizable-panel/resizable-panel.js +2 -1
  75. package/dist/src/scroll-area/scroll-area.d.ts +14 -2
  76. package/dist/src/scroll-area/scroll-area.js +2 -1
  77. package/dist/src/select/select.d.ts +14 -2
  78. package/dist/src/select/select.js +2 -1
  79. package/dist/src/slider/slider.d.ts +14 -2
  80. package/dist/src/slider/slider.js +2 -1
  81. package/dist/src/switch/switch.d.ts +13 -1
  82. package/dist/src/switch/switch.js +2 -1
  83. package/dist/src/tabs/tabs.d.ts +14 -2
  84. package/dist/src/tabs/tabs.js +2 -1
  85. package/dist/src/toast/toast.d.ts +14 -2
  86. package/dist/src/toast/toast.js +2 -1
  87. package/dist/src/toggle/toggle.d.ts +13 -1
  88. package/dist/src/toggle/toggle.js +2 -1
  89. package/dist/src/toggle-group/toggle-group.d.ts +14 -2
  90. package/dist/src/toggle-group/toggle-group.js +2 -1
  91. package/dist/src/tooltip/tooltip.d.ts +14 -2
  92. package/dist/src/tooltip/tooltip.js +2 -1
  93. package/package.json +3 -3
  94. package/dist/shared/chunk-2h5qpc00.js +0 -98
  95. package/dist/shared/chunk-31yptvbf.js +0 -151
  96. package/dist/shared/chunk-3pantb0p.js +0 -108
  97. package/dist/shared/chunk-3s6s6f06.js +0 -61
  98. package/dist/shared/chunk-48v8j0vh.js +0 -267
  99. package/dist/shared/chunk-6dmt4513.js +0 -78
  100. package/dist/shared/chunk-6sqwjfg8.js +0 -169
  101. package/dist/shared/chunk-8qfeqrrz.js +0 -179
  102. package/dist/shared/chunk-bcfzteh0.js +0 -148
  103. package/dist/shared/chunk-cr9sbwns.js +0 -235
  104. package/dist/shared/chunk-cvbf1js1.js +0 -52
  105. package/dist/shared/chunk-dkhst4wv.js +0 -97
  106. package/dist/shared/chunk-e3aj5yw4.js +0 -115
  107. package/dist/shared/chunk-fv1y77tn.js +0 -225
  108. package/dist/shared/chunk-h42bk324.js +0 -58
  109. package/dist/shared/chunk-h9m9x5my.js +0 -119
  110. package/dist/shared/chunk-qq0e0gym.js +0 -73
  111. package/dist/shared/chunk-tk1k1bet.js +0 -93
  112. package/dist/shared/chunk-tvpgeswh.js +0 -216
  113. package/dist/shared/chunk-vcp10kne.js +0 -175
  114. package/dist/shared/chunk-ve006hmy.js +0 -51
  115. package/dist/shared/chunk-vx1ajy2z.js +0 -115
  116. package/dist/shared/chunk-wnttq0gv.js +0 -49
  117. package/dist/shared/chunk-x6qzr3g6.js +0 -100
@@ -1,267 +0,0 @@
1
- // src/calendar/calendar.ts
2
- import { signal } from "@vertz/ui";
3
- var MONTH_NAMES = [
4
- "January",
5
- "February",
6
- "March",
7
- "April",
8
- "May",
9
- "June",
10
- "July",
11
- "August",
12
- "September",
13
- "October",
14
- "November",
15
- "December"
16
- ];
17
- var DAY_NAMES = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
18
- function getDaysInMonth(year, month) {
19
- return new Date(year, month + 1, 0).getDate();
20
- }
21
- function isSameDay(a, b) {
22
- return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
23
- }
24
- function addDays(date, days) {
25
- const result = new Date(date);
26
- result.setDate(result.getDate() + days);
27
- return result;
28
- }
29
- function addMonths(date, months) {
30
- const result = new Date(date);
31
- result.setMonth(result.getMonth() + months);
32
- return result;
33
- }
34
- var Calendar = {
35
- Root(options = {}) {
36
- const now = new Date;
37
- const defaultMonth = options.defaultMonth ?? now;
38
- const weekStartsOn = options.weekStartsOn ?? 0;
39
- const mode = options.mode ?? "single";
40
- const state = {
41
- value: signal(options.defaultValue ?? null),
42
- focusedDate: signal(defaultMonth),
43
- displayMonth: signal(defaultMonth)
44
- };
45
- const root = document.createElement("div");
46
- const header = document.createElement("div");
47
- const title = document.createElement("div");
48
- const prevButton = document.createElement("button");
49
- prevButton.setAttribute("type", "button");
50
- const nextButton = document.createElement("button");
51
- nextButton.setAttribute("type", "button");
52
- const grid = document.createElement("table");
53
- grid.setAttribute("role", "grid");
54
- function updateTitle() {
55
- const month = state.displayMonth.peek();
56
- title.textContent = `${MONTH_NAMES[month.getMonth()]} ${month.getFullYear()}`;
57
- }
58
- function isDateDisabled(date) {
59
- if (options.disabled?.(date))
60
- return true;
61
- if (options.minDate && date < options.minDate && !isSameDay(date, options.minDate)) {
62
- return true;
63
- }
64
- if (options.maxDate && date > options.maxDate && !isSameDay(date, options.maxDate)) {
65
- return true;
66
- }
67
- return false;
68
- }
69
- function isSelected(date) {
70
- const val = state.value.peek();
71
- if (val === null)
72
- return false;
73
- if (val instanceof Date)
74
- return isSameDay(val, date);
75
- if (Array.isArray(val))
76
- return val.some((d) => isSameDay(d, date));
77
- if ("from" in val && "to" in val) {
78
- return isSameDay(val.from, date) || isSameDay(val.to, date);
79
- }
80
- return false;
81
- }
82
- function isInRange(date) {
83
- const val = state.value.peek();
84
- if (val === null || !("from" in val))
85
- return false;
86
- const range = val;
87
- return date > range.from && date < range.to;
88
- }
89
- function selectDate(date) {
90
- if (isDateDisabled(date))
91
- return;
92
- if (mode === "single") {
93
- state.value.value = date;
94
- } else if (mode === "multiple") {
95
- const current = state.value.peek() ?? [];
96
- const existing = current.findIndex((d) => isSameDay(d, date));
97
- if (existing >= 0) {
98
- const next = [...current];
99
- next.splice(existing, 1);
100
- state.value.value = next;
101
- } else {
102
- state.value.value = [...current, date];
103
- }
104
- } else if (mode === "range") {
105
- const current = state.value.peek();
106
- if (!current || "to" in current && current.to) {
107
- state.value.value = { from: date, to: date };
108
- } else {
109
- if (date < current.from) {
110
- state.value.value = { from: date, to: current.from };
111
- } else {
112
- state.value.value = { from: current.from, to: date };
113
- }
114
- }
115
- }
116
- options.onValueChange?.(state.value.peek());
117
- }
118
- function buildGrid() {
119
- grid.innerHTML = "";
120
- const display = state.displayMonth.peek();
121
- const year = display.getFullYear();
122
- const month = display.getMonth();
123
- const daysInMonth = getDaysInMonth(year, month);
124
- const thead = document.createElement("thead");
125
- const headerRow = document.createElement("tr");
126
- for (let i = 0;i < 7; i++) {
127
- const dayIndex = (weekStartsOn + i) % 7;
128
- const th = document.createElement("th");
129
- th.setAttribute("scope", "col");
130
- th.textContent = DAY_NAMES[dayIndex] ?? "";
131
- headerRow.appendChild(th);
132
- }
133
- thead.appendChild(headerRow);
134
- grid.appendChild(thead);
135
- const tbody = document.createElement("tbody");
136
- const firstDay = new Date(year, month, 1);
137
- const firstDayOfWeek = firstDay.getDay();
138
- const offset = (firstDayOfWeek - weekStartsOn + 7) % 7;
139
- const startDate = addDays(firstDay, -offset);
140
- let currentDate = startDate;
141
- const totalCells = offset + daysInMonth;
142
- const totalRows = Math.ceil(totalCells / 7);
143
- for (let row = 0;row < totalRows; row++) {
144
- const tr = document.createElement("tr");
145
- for (let col = 0;col < 7; col++) {
146
- const td = document.createElement("td");
147
- td.setAttribute("role", "gridcell");
148
- const btn = document.createElement("button");
149
- btn.setAttribute("type", "button");
150
- const cellDate = new Date(currentDate);
151
- btn.textContent = String(cellDate.getDate());
152
- btn.setAttribute("data-date", cellDate.toISOString().split("T")[0] ?? "");
153
- const isOutside = cellDate.getMonth() !== month;
154
- if (isOutside) {
155
- btn.setAttribute("data-outside-month", "true");
156
- }
157
- if (isSameDay(cellDate, now)) {
158
- btn.setAttribute("data-today", "true");
159
- }
160
- if (isDateDisabled(cellDate)) {
161
- btn.setAttribute("aria-disabled", "true");
162
- }
163
- if (isSelected(cellDate)) {
164
- btn.setAttribute("aria-selected", "true");
165
- }
166
- if (mode === "range") {
167
- const val = state.value.peek();
168
- if (val && "from" in val) {
169
- if (isSameDay(cellDate, val.from)) {
170
- btn.setAttribute("data-range-start", "true");
171
- }
172
- if (isSameDay(cellDate, val.to)) {
173
- btn.setAttribute("data-range-end", "true");
174
- }
175
- if (isInRange(cellDate)) {
176
- btn.setAttribute("data-in-range", "true");
177
- }
178
- }
179
- }
180
- btn.addEventListener("click", () => {
181
- selectDate(cellDate);
182
- rebuildGrid();
183
- });
184
- td.appendChild(btn);
185
- tr.appendChild(td);
186
- currentDate = addDays(currentDate, 1);
187
- }
188
- tbody.appendChild(tr);
189
- }
190
- grid.appendChild(tbody);
191
- }
192
- function rebuildGrid() {
193
- updateTitle();
194
- buildGrid();
195
- }
196
- function navigateMonth(delta) {
197
- state.displayMonth.value = addMonths(state.displayMonth.peek(), delta);
198
- options.onMonthChange?.(state.displayMonth.peek());
199
- rebuildGrid();
200
- }
201
- prevButton.addEventListener("click", () => navigateMonth(-1));
202
- nextButton.addEventListener("click", () => navigateMonth(1));
203
- grid.addEventListener("keydown", (event) => {
204
- const active = document.activeElement;
205
- if (!active || active.tagName !== "BUTTON")
206
- return;
207
- const dateStr = active.getAttribute("data-date");
208
- if (!dateStr)
209
- return;
210
- const focused = new Date(dateStr + "T00:00:00");
211
- let next = null;
212
- if (event.key === "ArrowLeft") {
213
- event.preventDefault();
214
- next = addDays(focused, -1);
215
- } else if (event.key === "ArrowRight") {
216
- event.preventDefault();
217
- next = addDays(focused, 1);
218
- } else if (event.key === "ArrowUp") {
219
- event.preventDefault();
220
- next = addDays(focused, -7);
221
- } else if (event.key === "ArrowDown") {
222
- event.preventDefault();
223
- next = addDays(focused, 7);
224
- } else if (event.key === "Home") {
225
- event.preventDefault();
226
- const dayOfWeek = (focused.getDay() - weekStartsOn + 7) % 7;
227
- next = addDays(focused, -dayOfWeek);
228
- } else if (event.key === "End") {
229
- event.preventDefault();
230
- const dayOfWeek = (focused.getDay() - weekStartsOn + 7) % 7;
231
- next = addDays(focused, 6 - dayOfWeek);
232
- } else if (event.key === "PageUp") {
233
- event.preventDefault();
234
- next = event.shiftKey ? addMonths(focused, -12) : addMonths(focused, -1);
235
- } else if (event.key === "PageDown") {
236
- event.preventDefault();
237
- next = event.shiftKey ? addMonths(focused, 12) : addMonths(focused, 1);
238
- } else if (event.key === "Enter" || event.key === " ") {
239
- event.preventDefault();
240
- selectDate(focused);
241
- rebuildGrid();
242
- return;
243
- }
244
- if (next) {
245
- state.focusedDate.value = next;
246
- if (next.getMonth() !== state.displayMonth.peek().getMonth() || next.getFullYear() !== state.displayMonth.peek().getFullYear()) {
247
- state.displayMonth.value = new Date(next.getFullYear(), next.getMonth(), 1);
248
- options.onMonthChange?.(state.displayMonth.peek());
249
- rebuildGrid();
250
- }
251
- const dateKey = next.toISOString().split("T")[0];
252
- const btn = grid.querySelector(`button[data-date="${dateKey}"]`);
253
- btn?.focus();
254
- }
255
- });
256
- updateTitle();
257
- buildGrid();
258
- root.appendChild(header);
259
- root.appendChild(grid);
260
- header.appendChild(prevButton);
261
- header.appendChild(title);
262
- header.appendChild(nextButton);
263
- return { root, header, title, prevButton, nextButton, grid, state };
264
- }
265
- };
266
-
267
- export { Calendar };
@@ -1,78 +0,0 @@
1
- import {
2
- createFloatingPosition
3
- } from "./chunk-0mcr52hc.js";
4
- import {
5
- Keys,
6
- isKey
7
- } from "./chunk-jctqs9m4.js";
8
- import {
9
- setDataState,
10
- setDescribedBy,
11
- setHidden,
12
- setHiddenAnimated
13
- } from "./chunk-vvjyx7fe.js";
14
- import {
15
- uniqueId
16
- } from "./chunk-8y1jf6xr.js";
17
-
18
- // src/tooltip/tooltip.ts
19
- import { signal } from "@vertz/ui";
20
- var Tooltip = {
21
- Root(options = {}) {
22
- const { delay = 300, onOpenChange, positioning } = options;
23
- const contentId = uniqueId("tooltip");
24
- const state = { open: signal(false) };
25
- let showTimeout = null;
26
- let floatingCleanup = null;
27
- const trigger = document.createElement("span");
28
- setDescribedBy(trigger, contentId);
29
- const content = document.createElement("div");
30
- content.setAttribute("role", "tooltip");
31
- content.id = contentId;
32
- setHidden(content, true);
33
- setDataState(content, "closed");
34
- function show() {
35
- if (showTimeout !== null)
36
- return;
37
- showTimeout = setTimeout(() => {
38
- state.open.value = true;
39
- setHidden(content, false);
40
- setDataState(content, "open");
41
- if (positioning) {
42
- const effectivePlacement = positioning.placement ?? "top";
43
- const result = createFloatingPosition(trigger, content, {
44
- ...positioning,
45
- placement: effectivePlacement
46
- });
47
- floatingCleanup = result.cleanup;
48
- }
49
- onOpenChange?.(true);
50
- showTimeout = null;
51
- }, delay);
52
- }
53
- function hide() {
54
- if (showTimeout !== null) {
55
- clearTimeout(showTimeout);
56
- showTimeout = null;
57
- }
58
- state.open.value = false;
59
- setDataState(content, "closed");
60
- setHiddenAnimated(content, true);
61
- floatingCleanup?.();
62
- floatingCleanup = null;
63
- onOpenChange?.(false);
64
- }
65
- trigger.addEventListener("mouseenter", show);
66
- trigger.addEventListener("mouseleave", hide);
67
- trigger.addEventListener("focus", show);
68
- trigger.addEventListener("blur", hide);
69
- trigger.addEventListener("keydown", (event) => {
70
- if (isKey(event, Keys.Escape)) {
71
- hide();
72
- }
73
- });
74
- return { trigger, content, state };
75
- }
76
- };
77
-
78
- export { Tooltip };
@@ -1,169 +0,0 @@
1
- import {
2
- focusFirst,
3
- setRovingTabindex
4
- } from "./chunk-e2v1c9ex.js";
5
- import {
6
- Keys,
7
- handleListNavigation,
8
- isKey
9
- } from "./chunk-jctqs9m4.js";
10
- import {
11
- setDataState,
12
- setExpanded,
13
- setHidden,
14
- setHiddenAnimated
15
- } from "./chunk-vvjyx7fe.js";
16
- import {
17
- linkedIds
18
- } from "./chunk-8y1jf6xr.js";
19
-
20
- // src/navigation-menu/navigation-menu.ts
21
- import { signal } from "@vertz/ui";
22
- var NavigationMenu = {
23
- Root(options = {}) {
24
- const { orientation = "horizontal", delayOpen = 200, delayClose = 300 } = options;
25
- const state = { activeItem: signal(null) };
26
- const triggers = [];
27
- const items = new Map;
28
- let openTimeout = null;
29
- let closeTimeout = null;
30
- const root = document.createElement("nav");
31
- const list = document.createElement("div");
32
- const viewport = document.createElement("div");
33
- function cancelTimers() {
34
- if (openTimeout) {
35
- clearTimeout(openTimeout);
36
- openTimeout = null;
37
- }
38
- if (closeTimeout) {
39
- clearTimeout(closeTimeout);
40
- closeTimeout = null;
41
- }
42
- }
43
- function openItem(value) {
44
- cancelTimers();
45
- const current = state.activeItem.peek();
46
- if (current && current !== value) {
47
- const prev = items.get(current);
48
- if (prev) {
49
- setExpanded(prev.trigger, false);
50
- setDataState(prev.trigger, "closed");
51
- setDataState(prev.content, "closed");
52
- setHiddenAnimated(prev.content, true);
53
- }
54
- }
55
- const item = items.get(value);
56
- if (!item)
57
- return;
58
- state.activeItem.value = value;
59
- setExpanded(item.trigger, true);
60
- setHidden(item.content, false);
61
- setDataState(item.trigger, "open");
62
- setDataState(item.content, "open");
63
- }
64
- function closeAll() {
65
- cancelTimers();
66
- const current = state.activeItem.peek();
67
- if (current) {
68
- const item = items.get(current);
69
- if (item) {
70
- setExpanded(item.trigger, false);
71
- setDataState(item.trigger, "closed");
72
- setDataState(item.content, "closed");
73
- setHiddenAnimated(item.content, true);
74
- }
75
- }
76
- state.activeItem.value = null;
77
- }
78
- function Item(value, label) {
79
- const ids = linkedIds("nav-menu");
80
- const trigger = document.createElement("button");
81
- trigger.setAttribute("type", "button");
82
- trigger.id = ids.triggerId;
83
- trigger.setAttribute("aria-controls", ids.contentId);
84
- trigger.setAttribute("data-value", value);
85
- trigger.textContent = label ?? value;
86
- setExpanded(trigger, false);
87
- setDataState(trigger, "closed");
88
- const content = document.createElement("div");
89
- content.id = ids.contentId;
90
- setHidden(content, true);
91
- setDataState(content, "closed");
92
- trigger.addEventListener("click", () => {
93
- if (state.activeItem.peek() === value) {
94
- closeAll();
95
- } else {
96
- openItem(value);
97
- }
98
- });
99
- trigger.addEventListener("mouseenter", () => {
100
- cancelTimers();
101
- openTimeout = setTimeout(() => {
102
- openItem(value);
103
- openTimeout = null;
104
- }, delayOpen);
105
- });
106
- trigger.addEventListener("mouseleave", () => {
107
- cancelTimers();
108
- closeTimeout = setTimeout(() => {
109
- closeAll();
110
- closeTimeout = null;
111
- }, delayClose);
112
- });
113
- content.addEventListener("mouseenter", () => {
114
- cancelTimers();
115
- });
116
- content.addEventListener("mouseleave", () => {
117
- cancelTimers();
118
- closeTimeout = setTimeout(() => {
119
- closeAll();
120
- closeTimeout = null;
121
- }, delayClose);
122
- });
123
- trigger.addEventListener("keydown", (event) => {
124
- if (isKey(event, Keys.Enter, Keys.Space)) {
125
- event.preventDefault();
126
- openItem(value);
127
- queueMicrotask(() => focusFirst(content));
128
- }
129
- if (isKey(event, Keys.Escape)) {
130
- event.preventDefault();
131
- closeAll();
132
- }
133
- });
134
- content.addEventListener("keydown", (event) => {
135
- if (isKey(event, Keys.Escape)) {
136
- event.preventDefault();
137
- event.stopPropagation();
138
- closeAll();
139
- trigger.focus();
140
- }
141
- });
142
- triggers.push(trigger);
143
- setRovingTabindex(triggers, 0);
144
- items.set(value, { trigger, content });
145
- list.appendChild(trigger);
146
- viewport.appendChild(content);
147
- return { trigger, content };
148
- }
149
- function Link(href, label) {
150
- const a = document.createElement("a");
151
- a.href = href;
152
- a.textContent = label;
153
- list.appendChild(a);
154
- return a;
155
- }
156
- list.addEventListener("keydown", (event) => {
157
- if (isKey(event, Keys.ArrowLeft, Keys.ArrowRight, Keys.Home, Keys.End)) {
158
- handleListNavigation(event, triggers, {
159
- orientation: orientation === "horizontal" ? "horizontal" : "vertical"
160
- });
161
- }
162
- });
163
- root.appendChild(list);
164
- root.appendChild(viewport);
165
- return { root, list, viewport, state, Item, Link };
166
- }
167
- };
168
-
169
- export { NavigationMenu };
@@ -1,179 +0,0 @@
1
- import {
2
- createDismiss
3
- } from "./chunk-a6wp8c32.js";
4
- import {
5
- createFloatingPosition,
6
- virtualElement
7
- } from "./chunk-0mcr52hc.js";
8
- import {
9
- Keys,
10
- handleListNavigation,
11
- isKey
12
- } from "./chunk-jctqs9m4.js";
13
- import {
14
- setDataState,
15
- setHidden,
16
- setHiddenAnimated
17
- } from "./chunk-vvjyx7fe.js";
18
- import {
19
- uniqueId
20
- } from "./chunk-8y1jf6xr.js";
21
-
22
- // src/context-menu/context-menu.ts
23
- import { signal } from "@vertz/ui";
24
- var ContextMenu = {
25
- Root(options = {}) {
26
- const { onSelect, positioning } = options;
27
- const state = {
28
- open: signal(false),
29
- activeIndex: signal(-1)
30
- };
31
- const items = [];
32
- let floatingCleanup = null;
33
- let dismissCleanup = null;
34
- const trigger = document.createElement("div");
35
- const contentId = uniqueId("ctx-menu");
36
- const content = document.createElement("div");
37
- content.setAttribute("role", "menu");
38
- content.id = contentId;
39
- content.style.position = "fixed";
40
- setHidden(content, true);
41
- setDataState(content, "closed");
42
- function handleClickOutside(event) {
43
- const target = event.target;
44
- if (!trigger.contains(target) && !content.contains(target)) {
45
- close();
46
- }
47
- }
48
- function open(x, y) {
49
- state.open.value = true;
50
- setHidden(content, false);
51
- setDataState(content, "open");
52
- if (positioning) {
53
- const result = createFloatingPosition(virtualElement(x, y), content, {
54
- strategy: "fixed",
55
- ...positioning
56
- });
57
- floatingCleanup = result.cleanup;
58
- dismissCleanup = createDismiss({
59
- onDismiss: close,
60
- insideElements: [trigger, content],
61
- escapeKey: false
62
- });
63
- } else {
64
- content.style.left = `${x}px`;
65
- content.style.top = `${y}px`;
66
- document.addEventListener("mousedown", handleClickOutside);
67
- }
68
- state.activeIndex.value = 0;
69
- updateActiveItem(0);
70
- items[0]?.focus();
71
- }
72
- function close() {
73
- state.open.value = false;
74
- setDataState(content, "closed");
75
- setHiddenAnimated(content, true);
76
- if (positioning) {
77
- floatingCleanup?.();
78
- floatingCleanup = null;
79
- dismissCleanup?.();
80
- dismissCleanup = null;
81
- } else {
82
- document.removeEventListener("mousedown", handleClickOutside);
83
- }
84
- }
85
- function updateActiveItem(index) {
86
- for (let i = 0;i < items.length; i++) {
87
- items[i]?.setAttribute("tabindex", i === index ? "0" : "-1");
88
- }
89
- }
90
- trigger.addEventListener("contextmenu", (event) => {
91
- event.preventDefault();
92
- if (state.open.peek()) {
93
- close();
94
- }
95
- open(event.clientX, event.clientY);
96
- });
97
- content.addEventListener("keydown", (event) => {
98
- if (isKey(event, Keys.Escape)) {
99
- event.preventDefault();
100
- close();
101
- return;
102
- }
103
- if (isKey(event, Keys.Enter, Keys.Space)) {
104
- event.preventDefault();
105
- const active = items[state.activeIndex.peek()];
106
- if (active) {
107
- const val = active.getAttribute("data-value");
108
- if (val !== null) {
109
- onSelect?.(val);
110
- close();
111
- }
112
- }
113
- return;
114
- }
115
- const result = handleListNavigation(event, items, { orientation: "vertical" });
116
- if (result) {
117
- const idx = items.indexOf(result);
118
- if (idx >= 0) {
119
- state.activeIndex.value = idx;
120
- updateActiveItem(idx);
121
- }
122
- return;
123
- }
124
- if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
125
- const char = event.key.toLowerCase();
126
- const match = items.find((item) => item.textContent?.toLowerCase().startsWith(char));
127
- if (match) {
128
- const idx = items.indexOf(match);
129
- state.activeIndex.value = idx;
130
- updateActiveItem(idx);
131
- match.focus();
132
- }
133
- }
134
- });
135
- function createItem(value, label, parent) {
136
- const item = document.createElement("div");
137
- item.setAttribute("role", "menuitem");
138
- item.setAttribute("data-value", value);
139
- item.setAttribute("tabindex", "-1");
140
- item.textContent = label ?? value;
141
- item.addEventListener("click", () => {
142
- onSelect?.(value);
143
- close();
144
- });
145
- items.push(item);
146
- (parent ?? content).appendChild(item);
147
- return item;
148
- }
149
- function Item(value, label) {
150
- return createItem(value, label);
151
- }
152
- function Group(label) {
153
- const el = document.createElement("div");
154
- el.setAttribute("role", "group");
155
- el.setAttribute("aria-label", label);
156
- content.appendChild(el);
157
- return {
158
- el,
159
- Item: (value, itemLabel) => createItem(value, itemLabel, el)
160
- };
161
- }
162
- function Separator() {
163
- const hr = document.createElement("hr");
164
- hr.setAttribute("role", "separator");
165
- content.appendChild(hr);
166
- return hr;
167
- }
168
- function Label(text) {
169
- const el = document.createElement("div");
170
- el.setAttribute("role", "none");
171
- el.textContent = text;
172
- content.appendChild(el);
173
- return el;
174
- }
175
- return { trigger, content, state, Item, Group, Separator, Label };
176
- }
177
- };
178
-
179
- export { ContextMenu };