@avenue-ticketing/ui 0.9.0 → 0.11.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.
- package/dist/react/datetime-picker.js +1 -1
- package/dist/react/datetime-picker.js.map +1 -1
- package/dist/react/dialog.js +1 -1
- package/dist/react/dialog.js.map +1 -1
- package/dist/react/dropdown.d.ts +4 -0
- package/dist/react/dropdown.js +106 -7
- package/dist/react/dropdown.js.map +1 -1
- package/dist/react/popover.js +1 -1
- package/dist/react/popover.js.map +1 -1
- package/dist/react/select.d.ts +2 -0
- package/dist/react/select.js +92 -3
- package/dist/react/select.js.map +1 -1
- package/dist/react/sheet.js +1 -1
- package/dist/react/sheet.js.map +1 -1
- package/dist/react/table-pagination.js +92 -3
- package/dist/react/table-pagination.js.map +1 -1
- package/dist/react/table-view/column-menu.js +92 -3
- package/dist/react/table-view/column-menu.js.map +1 -1
- package/dist/react/table-view/index.js +92 -3
- package/dist/react/table-view/index.js.map +1 -1
- package/package.json +2 -2
- package/source.css +1 -0
|
@@ -200,6 +200,85 @@ var Button = React5.forwardRef(
|
|
|
200
200
|
}
|
|
201
201
|
);
|
|
202
202
|
Button.displayName = "Button";
|
|
203
|
+
|
|
204
|
+
// src/lib/typeahead.ts
|
|
205
|
+
var TYPEAHEAD_TIMEOUT_MS = 500;
|
|
206
|
+
function createTypeaheadState() {
|
|
207
|
+
return { search: "", timer: null };
|
|
208
|
+
}
|
|
209
|
+
function resetTypeahead(state) {
|
|
210
|
+
state.search = "";
|
|
211
|
+
if (state.timer) {
|
|
212
|
+
clearTimeout(state.timer);
|
|
213
|
+
state.timer = null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function getItemLabel(item) {
|
|
217
|
+
const aria = item.getAttribute("aria-label")?.trim();
|
|
218
|
+
if (aria) return aria;
|
|
219
|
+
const marked = item.querySelector("[data-menu-label]");
|
|
220
|
+
if (marked?.textContent) return marked.textContent.replace(/\s+/g, " ").trim();
|
|
221
|
+
return (item.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
222
|
+
}
|
|
223
|
+
function normalizeSearch(value) {
|
|
224
|
+
return value.trim().toLocaleLowerCase();
|
|
225
|
+
}
|
|
226
|
+
function isTypeaheadTarget(target) {
|
|
227
|
+
if (!(target instanceof HTMLElement)) return true;
|
|
228
|
+
if (target.isContentEditable) return false;
|
|
229
|
+
const tag = target.tagName;
|
|
230
|
+
return tag !== "INPUT" && tag !== "TEXTAREA" && tag !== "SELECT";
|
|
231
|
+
}
|
|
232
|
+
function handleTypeaheadKeyDown(event, items, state, options) {
|
|
233
|
+
if (options?.enabled === false || items.length === 0) return false;
|
|
234
|
+
if (event.ctrlKey || event.metaKey || event.altKey) return false;
|
|
235
|
+
if (event.key.length !== 1 || !isTypeaheadTarget(event.target)) return false;
|
|
236
|
+
event.preventDefault();
|
|
237
|
+
const timeoutMs = options?.timeoutMs ?? TYPEAHEAD_TIMEOUT_MS;
|
|
238
|
+
const char = event.key;
|
|
239
|
+
const prevSearch = state.search;
|
|
240
|
+
const repeatSingleChar = prevSearch.length === 1 && prevSearch === char;
|
|
241
|
+
if (repeatSingleChar) {
|
|
242
|
+
state.search = prevSearch;
|
|
243
|
+
} else {
|
|
244
|
+
state.search = prevSearch + char;
|
|
245
|
+
}
|
|
246
|
+
if (state.timer) clearTimeout(state.timer);
|
|
247
|
+
state.timer = setTimeout(() => {
|
|
248
|
+
state.search = "";
|
|
249
|
+
state.timer = null;
|
|
250
|
+
}, timeoutMs);
|
|
251
|
+
const labels = items.map((item) => normalizeSearch(getItemLabel(item)));
|
|
252
|
+
let needle = normalizeSearch(state.search);
|
|
253
|
+
let matches = items.map((item, index) => ({ item, index, label: labels[index] })).filter(({ label }) => label.startsWith(needle));
|
|
254
|
+
if (matches.length === 0 && state.search.length > 1) {
|
|
255
|
+
state.search = char;
|
|
256
|
+
needle = normalizeSearch(char);
|
|
257
|
+
matches = items.map((item, index) => ({ item, index, label: labels[index] })).filter(({ label }) => label.startsWith(needle));
|
|
258
|
+
}
|
|
259
|
+
if (matches.length === 0) return true;
|
|
260
|
+
const focused = document.activeElement;
|
|
261
|
+
const focusedIndex = focused ? items.indexOf(focused) : -1;
|
|
262
|
+
if (repeatSingleChar && focusedIndex !== -1) {
|
|
263
|
+
const currentMatch = matches.findIndex(
|
|
264
|
+
({ index }) => index === focusedIndex
|
|
265
|
+
);
|
|
266
|
+
if (currentMatch !== -1) {
|
|
267
|
+
const next = matches[(currentMatch + 1) % matches.length];
|
|
268
|
+
next?.item.focus();
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (focusedIndex !== -1) {
|
|
273
|
+
const nextAfterFocus = matches.find(({ index }) => index > focusedIndex);
|
|
274
|
+
if (nextAfterFocus) {
|
|
275
|
+
nextAfterFocus.item.focus();
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
matches[0]?.item.focus();
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
203
282
|
var DROPDOWN_PANEL_OPEN_EASING = "cubic-bezier(0,0.55,0.45,1)";
|
|
204
283
|
var DROPDOWN_PANEL_CLOSE_EASING = "cubic-bezier(0.55,0,1,0.45)";
|
|
205
284
|
var DROPDOWN_MENU_MIN_WIDTH_PX = 192;
|
|
@@ -491,7 +570,7 @@ function DropdownMobileBottomSheetPortal({
|
|
|
491
570
|
"div",
|
|
492
571
|
{
|
|
493
572
|
className: cn(
|
|
494
|
-
"fixed inset-0 bg-black/40 dark:bg-
|
|
573
|
+
"fixed inset-0 bg-black/40 dark:bg-primary/4",
|
|
495
574
|
isAnimating ? "opacity-100" : "opacity-0"
|
|
496
575
|
),
|
|
497
576
|
style: {
|
|
@@ -573,6 +652,7 @@ var DropdownContent = ({
|
|
|
573
652
|
closeOnEscape = true,
|
|
574
653
|
minWidth = "trigger",
|
|
575
654
|
loop = true,
|
|
655
|
+
typeahead = true,
|
|
576
656
|
mobileOptions,
|
|
577
657
|
slideEntrance = true,
|
|
578
658
|
slideEntranceOffsetPx: slideEntranceOffsetPxProp,
|
|
@@ -587,6 +667,7 @@ var DropdownContent = ({
|
|
|
587
667
|
const [pos, setPos] = useState({ top: -9999, left: -9999, side });
|
|
588
668
|
const [triggerW, setTriggerW] = useState(0);
|
|
589
669
|
const menuRef = useRef(null);
|
|
670
|
+
const typeaheadStateRef = useRef(createTypeaheadState());
|
|
590
671
|
const resolvedMobile = resolveDropdownMobileSheet(mobileOptions);
|
|
591
672
|
const isMobileSheet = isMobile && resolvedMobile.sheet;
|
|
592
673
|
const slideOffsetPx = slideEntranceOffsetPxProp ?? DROPDOWN_MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_DEFAULT_PX;
|
|
@@ -661,6 +742,9 @@ var DropdownContent = ({
|
|
|
661
742
|
menuRef.current.focus();
|
|
662
743
|
}
|
|
663
744
|
}, [isAnimating]);
|
|
745
|
+
useEffect(() => {
|
|
746
|
+
if (!open) resetTypeahead(typeaheadStateRef.current);
|
|
747
|
+
}, [open]);
|
|
664
748
|
useEffect(() => {
|
|
665
749
|
if (!open) return;
|
|
666
750
|
const handler = (e) => {
|
|
@@ -715,11 +799,16 @@ var DropdownContent = ({
|
|
|
715
799
|
case "Tab":
|
|
716
800
|
setOpen(false);
|
|
717
801
|
break;
|
|
802
|
+
default:
|
|
803
|
+
handleTypeaheadKeyDown(e, items, typeaheadStateRef.current, {
|
|
804
|
+
enabled: typeahead
|
|
805
|
+
});
|
|
806
|
+
break;
|
|
718
807
|
}
|
|
719
808
|
};
|
|
720
809
|
window.addEventListener("keydown", handler);
|
|
721
810
|
return () => window.removeEventListener("keydown", handler);
|
|
722
|
-
}, [open, closeOnEscape, loop, setOpen, triggerRef]);
|
|
811
|
+
}, [open, closeOnEscape, loop, typeahead, setOpen, triggerRef]);
|
|
723
812
|
useEffect(() => {
|
|
724
813
|
if (!open || !isMobileSheet) return;
|
|
725
814
|
document.body.style.overflow = "hidden";
|
|
@@ -843,7 +932,7 @@ var DropdownItem = ({
|
|
|
843
932
|
),
|
|
844
933
|
children: [
|
|
845
934
|
icon && /* @__PURE__ */ jsx("span", { className: "flex size-4 shrink-0 items-center justify-center", children: icon }),
|
|
846
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children }),
|
|
935
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", "data-menu-label": true, children }),
|
|
847
936
|
shortcut ? /* @__PURE__ */ jsx(
|
|
848
937
|
"span",
|
|
849
938
|
{
|