@mlw-packages/react-components 1.10.28 → 1.10.29
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/index.css +0 -3
- package/dist/index.d.mts +3 -9
- package/dist/index.d.ts +3 -9
- package/dist/index.js +185 -69
- package/dist/index.mjs +186 -70
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -6002,9 +6002,6 @@ body {
|
|
|
6002
6002
|
.group:hover .group-hover\:text-destructive {
|
|
6003
6003
|
color: hsl(var(--destructive));
|
|
6004
6004
|
}
|
|
6005
|
-
.group:hover .group-hover\:text-foreground {
|
|
6006
|
-
color: hsl(var(--foreground));
|
|
6007
|
-
}
|
|
6008
6005
|
.group:hover .group-hover\:text-primary {
|
|
6009
6006
|
color: hsl(var(--primary));
|
|
6010
6007
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -28,7 +28,6 @@ import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
|
28
28
|
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
|
|
29
29
|
import { UniqueIdentifier, DraggableAttributes } from '@dnd-kit/core';
|
|
30
30
|
import { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
|
|
31
|
-
import * as _phosphor_icons_react from '@phosphor-icons/react';
|
|
32
31
|
import { IconProps as IconProps$1 } from '@phosphor-icons/react';
|
|
33
32
|
|
|
34
33
|
type ErrorMessageProps = {
|
|
@@ -2649,6 +2648,7 @@ interface CommandPaletteProps {
|
|
|
2649
2648
|
multiSelect?: boolean;
|
|
2650
2649
|
onSelectMultiple?: (items: CommandItem[]) => void;
|
|
2651
2650
|
multiSearch?: boolean;
|
|
2651
|
+
onMultiSearchSubmit?: (terms: string[]) => void;
|
|
2652
2652
|
debounceDelay?: number;
|
|
2653
2653
|
footer?: React$1.ReactNode;
|
|
2654
2654
|
onSelect?: (item: CommandItem) => void;
|
|
@@ -2692,7 +2692,7 @@ declare function CommandItemRow({ item, isActive, isSelected, multiSelect, onSel
|
|
|
2692
2692
|
|
|
2693
2693
|
declare function CommandPalette(props: CommandPaletteProps): react_jsx_runtime.JSX.Element;
|
|
2694
2694
|
|
|
2695
|
-
declare function useCommandPalette({ items, groups, open, onOpenChange, recentItems, onRecentItemsChange, maxRecentItems, multiSearch, multiSelect, onSelectMultiple, }: Partial<CommandPaletteProps>): {
|
|
2695
|
+
declare function useCommandPalette({ items, groups, open, onOpenChange, recentItems, onRecentItemsChange, maxRecentItems, multiSearch, multiSelect, onSelectMultiple, onMultiSearchSubmit, }: Partial<CommandPaletteProps>): {
|
|
2696
2696
|
query: string;
|
|
2697
2697
|
setQuery: React$1.Dispatch<React$1.SetStateAction<string>>;
|
|
2698
2698
|
activeIndex: number;
|
|
@@ -2700,13 +2700,7 @@ declare function useCommandPalette({ items, groups, open, onOpenChange, recentIt
|
|
|
2700
2700
|
page: number;
|
|
2701
2701
|
setPage: React$1.Dispatch<React$1.SetStateAction<number>>;
|
|
2702
2702
|
searchTerms: string[];
|
|
2703
|
-
allMatchedGroups:
|
|
2704
|
-
id: string;
|
|
2705
|
-
label: string;
|
|
2706
|
-
icon: React$1.FunctionComponentElement<_phosphor_icons_react.IconProps>;
|
|
2707
|
-
items: CommandItem[];
|
|
2708
|
-
priority: number;
|
|
2709
|
-
})[];
|
|
2703
|
+
allMatchedGroups: CommandGroup[];
|
|
2710
2704
|
allFlatItems: CommandItem[];
|
|
2711
2705
|
displayedGroups: CommandGroup[];
|
|
2712
2706
|
flatItems: CommandItem[];
|
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,6 @@ import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
|
28
28
|
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
|
|
29
29
|
import { UniqueIdentifier, DraggableAttributes } from '@dnd-kit/core';
|
|
30
30
|
import { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
|
|
31
|
-
import * as _phosphor_icons_react from '@phosphor-icons/react';
|
|
32
31
|
import { IconProps as IconProps$1 } from '@phosphor-icons/react';
|
|
33
32
|
|
|
34
33
|
type ErrorMessageProps = {
|
|
@@ -2649,6 +2648,7 @@ interface CommandPaletteProps {
|
|
|
2649
2648
|
multiSelect?: boolean;
|
|
2650
2649
|
onSelectMultiple?: (items: CommandItem[]) => void;
|
|
2651
2650
|
multiSearch?: boolean;
|
|
2651
|
+
onMultiSearchSubmit?: (terms: string[]) => void;
|
|
2652
2652
|
debounceDelay?: number;
|
|
2653
2653
|
footer?: React$1.ReactNode;
|
|
2654
2654
|
onSelect?: (item: CommandItem) => void;
|
|
@@ -2692,7 +2692,7 @@ declare function CommandItemRow({ item, isActive, isSelected, multiSelect, onSel
|
|
|
2692
2692
|
|
|
2693
2693
|
declare function CommandPalette(props: CommandPaletteProps): react_jsx_runtime.JSX.Element;
|
|
2694
2694
|
|
|
2695
|
-
declare function useCommandPalette({ items, groups, open, onOpenChange, recentItems, onRecentItemsChange, maxRecentItems, multiSearch, multiSelect, onSelectMultiple, }: Partial<CommandPaletteProps>): {
|
|
2695
|
+
declare function useCommandPalette({ items, groups, open, onOpenChange, recentItems, onRecentItemsChange, maxRecentItems, multiSearch, multiSelect, onSelectMultiple, onMultiSearchSubmit, }: Partial<CommandPaletteProps>): {
|
|
2696
2696
|
query: string;
|
|
2697
2697
|
setQuery: React$1.Dispatch<React$1.SetStateAction<string>>;
|
|
2698
2698
|
activeIndex: number;
|
|
@@ -2700,13 +2700,7 @@ declare function useCommandPalette({ items, groups, open, onOpenChange, recentIt
|
|
|
2700
2700
|
page: number;
|
|
2701
2701
|
setPage: React$1.Dispatch<React$1.SetStateAction<number>>;
|
|
2702
2702
|
searchTerms: string[];
|
|
2703
|
-
allMatchedGroups:
|
|
2704
|
-
id: string;
|
|
2705
|
-
label: string;
|
|
2706
|
-
icon: React$1.FunctionComponentElement<_phosphor_icons_react.IconProps>;
|
|
2707
|
-
items: CommandItem[];
|
|
2708
|
-
priority: number;
|
|
2709
|
-
})[];
|
|
2703
|
+
allMatchedGroups: CommandGroup[];
|
|
2710
2704
|
allFlatItems: CommandItem[];
|
|
2711
2705
|
displayedGroups: CommandGroup[];
|
|
2712
2706
|
flatItems: CommandItem[];
|
package/dist/index.js
CHANGED
|
@@ -22284,15 +22284,24 @@ function normaliseGroups(items = [], groups = []) {
|
|
|
22284
22284
|
}
|
|
22285
22285
|
function unionGroups(base, terms) {
|
|
22286
22286
|
if (terms.length === 0) return base;
|
|
22287
|
-
const
|
|
22287
|
+
const bestScore = /* @__PURE__ */ new Map();
|
|
22288
22288
|
terms.forEach((term) => {
|
|
22289
|
-
|
|
22290
|
-
|
|
22289
|
+
base.forEach((group) => {
|
|
22290
|
+
group.items.forEach((item) => {
|
|
22291
|
+
const s = scoreMatch(item, term);
|
|
22292
|
+
if (s >= 0) {
|
|
22293
|
+
const prev = bestScore.get(item.id) ?? -1;
|
|
22294
|
+
if (s > prev) bestScore.set(item.id, s);
|
|
22295
|
+
}
|
|
22296
|
+
});
|
|
22297
|
+
});
|
|
22291
22298
|
});
|
|
22292
22299
|
return base.map((group) => ({
|
|
22293
22300
|
...group,
|
|
22294
|
-
items: group.items.filter((item) =>
|
|
22295
|
-
|
|
22301
|
+
items: group.items.filter((item) => bestScore.has(item.id)).sort(
|
|
22302
|
+
(a, b) => (bestScore.get(b.id) ?? 0) - (bestScore.get(a.id) ?? 0)
|
|
22303
|
+
)
|
|
22304
|
+
})).filter((group) => group.items.length > 0).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
22296
22305
|
}
|
|
22297
22306
|
function createGroup(id, label, items, opts) {
|
|
22298
22307
|
return { id, label, items, ...opts };
|
|
@@ -22413,33 +22422,31 @@ function CommandItemRow({
|
|
|
22413
22422
|
onHover,
|
|
22414
22423
|
searchQuery
|
|
22415
22424
|
}) {
|
|
22425
|
+
const handleCheckboxChange = (checked) => {
|
|
22426
|
+
if (checked !== "indeterminate") {
|
|
22427
|
+
onToggleSelection?.({});
|
|
22428
|
+
}
|
|
22429
|
+
};
|
|
22430
|
+
const handleItemClick = (e) => {
|
|
22431
|
+
if (multiSelect) {
|
|
22432
|
+
onToggleSelection?.(e);
|
|
22433
|
+
return;
|
|
22434
|
+
}
|
|
22435
|
+
onSelect(e);
|
|
22436
|
+
};
|
|
22416
22437
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
22417
22438
|
framerMotion.motion.button,
|
|
22418
22439
|
{
|
|
22419
22440
|
layout: true,
|
|
22420
|
-
onClick:
|
|
22421
|
-
if (multiSelect && onToggleSelection && (e.ctrlKey || e.metaKey || e.shiftKey)) {
|
|
22422
|
-
onToggleSelection(e);
|
|
22423
|
-
} else {
|
|
22424
|
-
onSelect(e);
|
|
22425
|
-
}
|
|
22426
|
-
},
|
|
22441
|
+
onClick: handleItemClick,
|
|
22427
22442
|
onMouseEnter: onHover,
|
|
22428
22443
|
className: `
|
|
22429
|
-
w-full flex items-center gap-
|
|
22430
|
-
transition-colors duration-75 group relative
|
|
22444
|
+
w-full flex items-center gap-2 px-2 py-1 rounded-md text-left cursor-pointer
|
|
22445
|
+
transition-colors duration-75 group relative justify-between
|
|
22431
22446
|
${isActive ? "text-accent-foreground bg-accent" : "hover:bg-accent hover:text-accent-foreground"}
|
|
22432
22447
|
`,
|
|
22433
22448
|
children: [
|
|
22434
|
-
|
|
22435
|
-
"span",
|
|
22436
|
-
{
|
|
22437
|
-
className: `relative flex-shrink-0 w-8 h-8 flex items-center justify-center rounded-md text-base
|
|
22438
|
-
${isSelected ? "bg-primary text-primary-foreground" : isActive ? "bg-primary/20 text-primary" : "bg-muted text-muted-foreground group-hover:text-foreground"}`,
|
|
22439
|
-
children: item.icon
|
|
22440
|
-
}
|
|
22441
|
-
),
|
|
22442
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0 px-1", children: [
|
|
22449
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0", children: [
|
|
22443
22450
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [
|
|
22444
22451
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22445
22452
|
"span",
|
|
@@ -22453,6 +22460,14 @@ function CommandItemRow({
|
|
|
22453
22460
|
item.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground truncate", children: /* @__PURE__ */ jsxRuntime.jsx(HighlightText, { text: item.description, query: searchQuery }) })
|
|
22454
22461
|
] }),
|
|
22455
22462
|
item.shortcut && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative hidden sm:flex items-center gap-1 flex-shrink-0", children: item.shortcut.map((k, i) => /* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: k }, i)) }),
|
|
22463
|
+
multiSelect && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22464
|
+
CheckboxBase,
|
|
22465
|
+
{
|
|
22466
|
+
checked: isSelected,
|
|
22467
|
+
onCheckedChange: handleCheckboxChange,
|
|
22468
|
+
className: "h-4 w-4 pointer-events-none"
|
|
22469
|
+
}
|
|
22470
|
+
) }),
|
|
22456
22471
|
isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22457
22472
|
framerMotion.motion.div,
|
|
22458
22473
|
{
|
|
@@ -22460,7 +22475,8 @@ function CommandItemRow({
|
|
|
22460
22475
|
className: "absolute left-0 top-1/2 -translate-y-1/2 w-1 h-2/3 bg-primary rounded-r-md"
|
|
22461
22476
|
}
|
|
22462
22477
|
),
|
|
22463
|
-
|
|
22478
|
+
!isSelected && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-1/2 -translate-y-1/2 w-1 h-2/3 bg-transparent rounded-r-md" }),
|
|
22479
|
+
isActive && !isSelected && !multiSelect && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22464
22480
|
react.CaretRightIcon,
|
|
22465
22481
|
{
|
|
22466
22482
|
className: "relative w-4 h-4 text-primary flex-shrink-0",
|
|
@@ -22482,12 +22498,15 @@ function useCommandPalette({
|
|
|
22482
22498
|
maxRecentItems = 5,
|
|
22483
22499
|
multiSearch = false,
|
|
22484
22500
|
multiSelect = false,
|
|
22485
|
-
onSelectMultiple
|
|
22501
|
+
onSelectMultiple,
|
|
22502
|
+
onMultiSearchSubmit
|
|
22486
22503
|
}) {
|
|
22487
22504
|
const [query, setQuery] = React32__namespace.useState("");
|
|
22488
22505
|
const [activeIndex, setActiveIndex] = React32__namespace.useState(0);
|
|
22489
22506
|
const [page, setPage] = React32__namespace.useState(0);
|
|
22490
|
-
const [selectedItemIds, setSelectedItemIds] = React32__namespace.useState(
|
|
22507
|
+
const [selectedItemIds, setSelectedItemIds] = React32__namespace.useState(
|
|
22508
|
+
/* @__PURE__ */ new Set()
|
|
22509
|
+
);
|
|
22491
22510
|
const stateRef = React32.useRef({
|
|
22492
22511
|
activeIndex,
|
|
22493
22512
|
page,
|
|
@@ -22504,27 +22523,44 @@ function useCommandPalette({
|
|
|
22504
22523
|
});
|
|
22505
22524
|
}, []);
|
|
22506
22525
|
const clearSelection = React32.useCallback(() => setSelectedItemIds(/* @__PURE__ */ new Set()), []);
|
|
22507
|
-
const baseGroups = React32.useMemo(
|
|
22526
|
+
const baseGroups = React32.useMemo(
|
|
22527
|
+
() => normaliseGroups(items, groups),
|
|
22528
|
+
[items, groups]
|
|
22529
|
+
);
|
|
22508
22530
|
React32.useEffect(() => {
|
|
22509
22531
|
if (open) {
|
|
22510
|
-
|
|
22532
|
+
const savedQuery = localStorage.getItem("commandPaletteQuery") || "";
|
|
22533
|
+
setQuery(savedQuery);
|
|
22511
22534
|
setActiveIndex(0);
|
|
22512
22535
|
setPage(0);
|
|
22513
|
-
|
|
22536
|
+
if (!multiSelect) {
|
|
22537
|
+
clearSelection();
|
|
22538
|
+
}
|
|
22514
22539
|
}
|
|
22515
|
-
}, [open, clearSelection]);
|
|
22540
|
+
}, [open, clearSelection, multiSelect]);
|
|
22541
|
+
React32.useEffect(() => {
|
|
22542
|
+
if (!open) {
|
|
22543
|
+
localStorage.setItem("commandPaletteQuery", query);
|
|
22544
|
+
}
|
|
22545
|
+
}, [open, query]);
|
|
22516
22546
|
const searchTerms = React32.useMemo(() => {
|
|
22517
22547
|
const parts = query.split(",");
|
|
22518
|
-
|
|
22519
|
-
|
|
22548
|
+
const terms = parts.map((t) => t.trim().toLowerCase()).filter(Boolean);
|
|
22549
|
+
if (terms.length > 1) return terms;
|
|
22550
|
+
if (multiSearch && terms.length > 0) return terms;
|
|
22551
|
+
return [];
|
|
22520
22552
|
}, [query, multiSearch]);
|
|
22521
22553
|
const allMatchedGroups = React32.useMemo(() => {
|
|
22522
|
-
if (!query.trim())
|
|
22523
|
-
|
|
22524
|
-
|
|
22525
|
-
|
|
22526
|
-
|
|
22527
|
-
|
|
22554
|
+
if (!query.trim()) return baseGroups;
|
|
22555
|
+
if (searchTerms.length > 0) {
|
|
22556
|
+
return unionGroups(baseGroups, searchTerms);
|
|
22557
|
+
}
|
|
22558
|
+
return filterAndScore(baseGroups, query);
|
|
22559
|
+
}, [query, baseGroups, searchTerms]);
|
|
22560
|
+
const allFlatItems = React32.useMemo(
|
|
22561
|
+
() => allMatchedGroups.flatMap((g) => g.items),
|
|
22562
|
+
[allMatchedGroups]
|
|
22563
|
+
);
|
|
22528
22564
|
const totalItems = allFlatItems.length;
|
|
22529
22565
|
const totalPages = Math.max(1, Math.ceil(totalItems / PAGE_SIZE));
|
|
22530
22566
|
React32.useEffect(() => {
|
|
@@ -22551,8 +22587,14 @@ function useCommandPalette({
|
|
|
22551
22587
|
}
|
|
22552
22588
|
return result;
|
|
22553
22589
|
}, [allMatchedGroups, page]);
|
|
22554
|
-
const flatItems = React32.useMemo(
|
|
22555
|
-
|
|
22590
|
+
const flatItems = React32.useMemo(
|
|
22591
|
+
() => displayedGroups.flatMap((g) => g.items),
|
|
22592
|
+
[displayedGroups]
|
|
22593
|
+
);
|
|
22594
|
+
const selectedItems = React32.useMemo(
|
|
22595
|
+
() => allFlatItems.filter((i) => selectedItemIds.has(i.id)),
|
|
22596
|
+
[allFlatItems, selectedItemIds]
|
|
22597
|
+
);
|
|
22556
22598
|
React32.useEffect(() => {
|
|
22557
22599
|
stateRef.current = { activeIndex, page, flatItems, query, selectedItems };
|
|
22558
22600
|
}, [activeIndex, page, flatItems, query, selectedItems]);
|
|
@@ -22561,47 +22603,92 @@ function useCommandPalette({
|
|
|
22561
22603
|
onSelectMultiple(selectedItems);
|
|
22562
22604
|
onOpenChange?.(false);
|
|
22563
22605
|
}, [onSelectMultiple, selectedItems, onOpenChange]);
|
|
22564
|
-
const handleSelect = React32.useCallback(
|
|
22565
|
-
|
|
22566
|
-
|
|
22567
|
-
|
|
22568
|
-
|
|
22569
|
-
|
|
22570
|
-
|
|
22606
|
+
const handleSelect = React32.useCallback(
|
|
22607
|
+
(item, event) => {
|
|
22608
|
+
if (!item) return;
|
|
22609
|
+
if (multiSelect) {
|
|
22610
|
+
const isCmdKey = event && ("ctrlKey" in event || "metaKey" in event || "shiftKey" in event) && (event.ctrlKey || event.metaKey || event.shiftKey);
|
|
22611
|
+
if (isCmdKey) {
|
|
22612
|
+
toggleSelection(item.id);
|
|
22613
|
+
return;
|
|
22614
|
+
}
|
|
22615
|
+
if (selectedItems.length > 0) {
|
|
22616
|
+
const finalItems = selectedItemIds.has(item.id) ? selectedItems : [...selectedItems, item];
|
|
22617
|
+
onSelectMultiple?.(finalItems);
|
|
22618
|
+
onOpenChange?.(false);
|
|
22619
|
+
return;
|
|
22620
|
+
}
|
|
22571
22621
|
}
|
|
22572
|
-
|
|
22573
|
-
|
|
22574
|
-
|
|
22575
|
-
|
|
22576
|
-
|
|
22622
|
+
item.onSelect();
|
|
22623
|
+
onOpenChange?.(false);
|
|
22624
|
+
if (onRecentItemsChange) {
|
|
22625
|
+
const next = [
|
|
22626
|
+
item,
|
|
22627
|
+
...recentItems.filter((r) => r.id !== item.id)
|
|
22628
|
+
].slice(0, maxRecentItems);
|
|
22629
|
+
onRecentItemsChange(next);
|
|
22577
22630
|
}
|
|
22578
|
-
}
|
|
22579
|
-
|
|
22580
|
-
|
|
22581
|
-
|
|
22582
|
-
|
|
22583
|
-
|
|
22584
|
-
|
|
22585
|
-
|
|
22631
|
+
},
|
|
22632
|
+
[
|
|
22633
|
+
multiSelect,
|
|
22634
|
+
selectedItems,
|
|
22635
|
+
selectedItemIds,
|
|
22636
|
+
onSelectMultiple,
|
|
22637
|
+
onOpenChange,
|
|
22638
|
+
onRecentItemsChange,
|
|
22639
|
+
recentItems,
|
|
22640
|
+
maxRecentItems,
|
|
22641
|
+
toggleSelection
|
|
22642
|
+
]
|
|
22643
|
+
);
|
|
22586
22644
|
React32.useEffect(() => {
|
|
22587
22645
|
if (!open) return;
|
|
22588
22646
|
const handler = (e) => {
|
|
22589
|
-
const { activeIndex: curIdx, flatItems: curItems
|
|
22647
|
+
const { activeIndex: curIdx, flatItems: curItems } = stateRef.current;
|
|
22590
22648
|
if (e.key === "ArrowDown") {
|
|
22591
22649
|
e.preventDefault();
|
|
22592
|
-
if (curIdx === curItems.length - 1 && page < totalPages - 1)
|
|
22650
|
+
if (curIdx === curItems.length - 1 && page < totalPages - 1)
|
|
22651
|
+
setPage((p) => p + 1);
|
|
22593
22652
|
else setActiveIndex((i) => (i + 1) % Math.max(curItems.length, 1));
|
|
22594
22653
|
} else if (e.key === "ArrowUp") {
|
|
22595
22654
|
e.preventDefault();
|
|
22596
22655
|
if (curIdx === 0 && page > 0) {
|
|
22597
22656
|
setPage((p) => p - 1);
|
|
22598
22657
|
setActiveIndex(PAGE_SIZE - 1);
|
|
22599
|
-
} else
|
|
22658
|
+
} else
|
|
22659
|
+
setActiveIndex(
|
|
22660
|
+
(i) => (i - 1 + Math.max(curItems.length, 1)) % Math.max(curItems.length, 1)
|
|
22661
|
+
);
|
|
22600
22662
|
} else if (e.key === "Enter") {
|
|
22601
22663
|
e.preventDefault();
|
|
22602
|
-
|
|
22664
|
+
const currentSelectedItems = allFlatItems.filter(
|
|
22665
|
+
(i) => selectedItemIds.has(i.id)
|
|
22666
|
+
);
|
|
22667
|
+
if (multiSelect && currentSelectedItems.length > 0) {
|
|
22668
|
+
const selectedLabels = currentSelectedItems.map((item) => item.label);
|
|
22669
|
+
onMultiSearchSubmit?.(selectedLabels);
|
|
22603
22670
|
return;
|
|
22604
22671
|
}
|
|
22672
|
+
if (multiSearch && query.trim().length > 0) {
|
|
22673
|
+
const terms = query.split(",").map((t) => t.trim()).filter(Boolean);
|
|
22674
|
+
if (terms.length > 0) {
|
|
22675
|
+
if (multiSelect) {
|
|
22676
|
+
const matchedItems = allFlatItems.filter(
|
|
22677
|
+
(item) => terms.some(
|
|
22678
|
+
(term) => item.label.toLowerCase().includes(term.toLowerCase()) || item.id.toLowerCase().includes(term.toLowerCase())
|
|
22679
|
+
)
|
|
22680
|
+
);
|
|
22681
|
+
const newSelectedIds = new Set(selectedItemIds);
|
|
22682
|
+
matchedItems.forEach((item) => newSelectedIds.add(item.id));
|
|
22683
|
+
setSelectedItemIds(newSelectedIds);
|
|
22684
|
+
const selectedLabels = matchedItems.map((item) => item.label);
|
|
22685
|
+
onMultiSearchSubmit?.(selectedLabels);
|
|
22686
|
+
return;
|
|
22687
|
+
}
|
|
22688
|
+
onMultiSearchSubmit?.(terms);
|
|
22689
|
+
return;
|
|
22690
|
+
}
|
|
22691
|
+
}
|
|
22605
22692
|
if (multiSelect && (e.ctrlKey || e.metaKey)) {
|
|
22606
22693
|
executeBulkAction();
|
|
22607
22694
|
return;
|
|
@@ -22611,7 +22698,20 @@ function useCommandPalette({
|
|
|
22611
22698
|
};
|
|
22612
22699
|
window.addEventListener("keydown", handler);
|
|
22613
22700
|
return () => window.removeEventListener("keydown", handler);
|
|
22614
|
-
}, [
|
|
22701
|
+
}, [
|
|
22702
|
+
open,
|
|
22703
|
+
page,
|
|
22704
|
+
totalPages,
|
|
22705
|
+
multiSearch,
|
|
22706
|
+
multiSelect,
|
|
22707
|
+
handleSelect,
|
|
22708
|
+
executeBulkAction,
|
|
22709
|
+
onMultiSearchSubmit,
|
|
22710
|
+
selectedItems,
|
|
22711
|
+
allFlatItems,
|
|
22712
|
+
selectedItemIds,
|
|
22713
|
+
query
|
|
22714
|
+
]);
|
|
22615
22715
|
return {
|
|
22616
22716
|
query,
|
|
22617
22717
|
setQuery,
|
|
@@ -22632,7 +22732,7 @@ function useCommandPalette({
|
|
|
22632
22732
|
selectedItems,
|
|
22633
22733
|
executeBulkAction,
|
|
22634
22734
|
isEmpty: totalItems === 0 && query.trim().length > 0,
|
|
22635
|
-
showList:
|
|
22735
|
+
showList: true
|
|
22636
22736
|
};
|
|
22637
22737
|
}
|
|
22638
22738
|
function useKeyboardShortcut(key, callback, options = {}) {
|
|
@@ -22932,7 +23032,16 @@ function CommandPalette(props) {
|
|
|
22932
23032
|
className: "flex-1 bg-transparent border-none shadow-none focus-visible:ring-0 p-0 text-base"
|
|
22933
23033
|
}
|
|
22934
23034
|
),
|
|
22935
|
-
query && /* @__PURE__ */ jsxRuntime.jsx(
|
|
23035
|
+
query && /* @__PURE__ */ jsxRuntime.jsx(
|
|
23036
|
+
ButtonBase,
|
|
23037
|
+
{
|
|
23038
|
+
variant: "ghost",
|
|
23039
|
+
size: "icon",
|
|
23040
|
+
onClick: handleClearQuery,
|
|
23041
|
+
className: "h-8 w-8",
|
|
23042
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(react.XIcon, { className: "w-4 h-4" })
|
|
23043
|
+
}
|
|
23044
|
+
)
|
|
22936
23045
|
]
|
|
22937
23046
|
}
|
|
22938
23047
|
),
|
|
@@ -22985,7 +23094,13 @@ function CommandPalette(props) {
|
|
|
22985
23094
|
style: { maxHeight: "min(600px, 80vh)" },
|
|
22986
23095
|
children: [
|
|
22987
23096
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 px-4 py-2 border-b border-border", children: [
|
|
22988
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
23097
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
23098
|
+
react.MagnifyingGlassIcon,
|
|
23099
|
+
{
|
|
23100
|
+
className: "w-4 h-4 text-muted-foreground flex-shrink-0",
|
|
23101
|
+
weight: "bold"
|
|
23102
|
+
}
|
|
23103
|
+
),
|
|
22989
23104
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22990
23105
|
DebouncedInput,
|
|
22991
23106
|
{
|
|
@@ -23016,7 +23131,8 @@ function CommandPalette(props) {
|
|
|
23016
23131
|
footer,
|
|
23017
23132
|
totalItems,
|
|
23018
23133
|
selectedCount: selectedItemIds.size,
|
|
23019
|
-
executeBulkAction
|
|
23134
|
+
executeBulkAction,
|
|
23135
|
+
multiSelect
|
|
23020
23136
|
}
|
|
23021
23137
|
)
|
|
23022
23138
|
]
|
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { Slot } from '@radix-ui/react-slot';
|
|
|
5
5
|
import { cva } from 'class-variance-authority';
|
|
6
6
|
import { clsx } from 'clsx';
|
|
7
7
|
import { twMerge } from 'tailwind-merge';
|
|
8
|
-
import { XIcon, CircleNotchIcon, MagnifyingGlassIcon, CaretUpIcon, CaretDownIcon, CheckIcon, CaretRightIcon, CircleIcon, CloudArrowUpIcon, MinusIcon, CaretUpDownIcon, PencilSimpleIcon, ArrowsLeftRightIcon, FloppyDiskIcon, PlusIcon, TrashIcon, SidebarSimpleIcon, CommandIcon, ArrowElbowDownRightIcon, ArrowBendUpLeftIcon, FilePdfIcon, FileDocIcon, FileXlsIcon, FilePptIcon, FileCsvIcon, FileTextIcon, FileImageIcon, FileVideoIcon, FileAudioIcon, FileZipIcon, FileIcon, DotsSixVerticalIcon, CopyIcon, InfoIcon, WarningIcon, XCircleIcon, CheckCircleIcon, CaretLeftIcon, DownloadSimpleIcon, UploadSimpleIcon, ArrowClockwiseIcon, ArrowLeftIcon, GearIcon, BellIcon, DotsThreeIcon, FunnelIcon, HeartIcon, StarIcon, EyeIcon, EyeSlashIcon, LockIcon, LockOpenIcon, FolderIcon, ArrowRightIcon as ArrowRightIcon$1, ArrowsOutIcon, DownloadIcon, CalendarBlankIcon, CalendarIcon, MapPinIcon, CalendarDotsIcon, SunIcon, ClockIcon, AlignLeftIcon, CaretLeft, CaretRight, ArrowDownIcon, ClockUserIcon, EyeSlash, Eye, ArrowUpRightIcon, ArrowDownRightIcon, FunnelSimpleIcon, PencilIcon,
|
|
8
|
+
import { XIcon, CircleNotchIcon, MagnifyingGlassIcon, CaretUpIcon, CaretDownIcon, CheckIcon, CaretRightIcon, CircleIcon, CloudArrowUpIcon, MinusIcon, CaretUpDownIcon, PencilSimpleIcon, ArrowsLeftRightIcon, FloppyDiskIcon, PlusIcon, TrashIcon, SidebarSimpleIcon, CommandIcon, ArrowElbowDownRightIcon, ArrowBendUpLeftIcon, FilePdfIcon, FileDocIcon, FileXlsIcon, FilePptIcon, FileCsvIcon, FileTextIcon, FileImageIcon, FileVideoIcon, FileAudioIcon, FileZipIcon, FileIcon, DotsSixVerticalIcon, CopyIcon, InfoIcon, WarningIcon, XCircleIcon, CheckCircleIcon, CaretLeftIcon, DownloadSimpleIcon, UploadSimpleIcon, ArrowClockwiseIcon, ArrowLeftIcon, GearIcon, BellIcon, DotsThreeIcon, FunnelIcon, HeartIcon, StarIcon, EyeIcon, EyeSlashIcon, LockIcon, LockOpenIcon, FolderIcon, ArrowRightIcon as ArrowRightIcon$1, ArrowsOutIcon, DownloadIcon, CalendarBlankIcon, CalendarIcon, MapPinIcon, CalendarDotsIcon, SunIcon, ClockIcon, AlignLeftIcon, CaretLeft, CaretRight, ArrowDownIcon, ClockUserIcon, EyeSlash, Eye, ArrowUpRightIcon, ArrowDownRightIcon, FunnelSimpleIcon, PencilIcon, FileArchiveIcon, TerminalIcon, CodeIcon, CalendarDotIcon as CalendarDotIcon$1, MoonIcon, DesktopIcon } from '@phosphor-icons/react';
|
|
9
9
|
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
|
|
10
10
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
11
11
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
@@ -22242,15 +22242,24 @@ function normaliseGroups(items = [], groups = []) {
|
|
|
22242
22242
|
}
|
|
22243
22243
|
function unionGroups(base, terms) {
|
|
22244
22244
|
if (terms.length === 0) return base;
|
|
22245
|
-
const
|
|
22245
|
+
const bestScore = /* @__PURE__ */ new Map();
|
|
22246
22246
|
terms.forEach((term) => {
|
|
22247
|
-
|
|
22248
|
-
|
|
22247
|
+
base.forEach((group) => {
|
|
22248
|
+
group.items.forEach((item) => {
|
|
22249
|
+
const s = scoreMatch(item, term);
|
|
22250
|
+
if (s >= 0) {
|
|
22251
|
+
const prev = bestScore.get(item.id) ?? -1;
|
|
22252
|
+
if (s > prev) bestScore.set(item.id, s);
|
|
22253
|
+
}
|
|
22254
|
+
});
|
|
22255
|
+
});
|
|
22249
22256
|
});
|
|
22250
22257
|
return base.map((group) => ({
|
|
22251
22258
|
...group,
|
|
22252
|
-
items: group.items.filter((item) =>
|
|
22253
|
-
|
|
22259
|
+
items: group.items.filter((item) => bestScore.has(item.id)).sort(
|
|
22260
|
+
(a, b) => (bestScore.get(b.id) ?? 0) - (bestScore.get(a.id) ?? 0)
|
|
22261
|
+
)
|
|
22262
|
+
})).filter((group) => group.items.length > 0).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
22254
22263
|
}
|
|
22255
22264
|
function createGroup(id, label, items, opts) {
|
|
22256
22265
|
return { id, label, items, ...opts };
|
|
@@ -22371,33 +22380,31 @@ function CommandItemRow({
|
|
|
22371
22380
|
onHover,
|
|
22372
22381
|
searchQuery
|
|
22373
22382
|
}) {
|
|
22383
|
+
const handleCheckboxChange = (checked) => {
|
|
22384
|
+
if (checked !== "indeterminate") {
|
|
22385
|
+
onToggleSelection?.({});
|
|
22386
|
+
}
|
|
22387
|
+
};
|
|
22388
|
+
const handleItemClick = (e) => {
|
|
22389
|
+
if (multiSelect) {
|
|
22390
|
+
onToggleSelection?.(e);
|
|
22391
|
+
return;
|
|
22392
|
+
}
|
|
22393
|
+
onSelect(e);
|
|
22394
|
+
};
|
|
22374
22395
|
return /* @__PURE__ */ jsxs(
|
|
22375
22396
|
motion.button,
|
|
22376
22397
|
{
|
|
22377
22398
|
layout: true,
|
|
22378
|
-
onClick:
|
|
22379
|
-
if (multiSelect && onToggleSelection && (e.ctrlKey || e.metaKey || e.shiftKey)) {
|
|
22380
|
-
onToggleSelection(e);
|
|
22381
|
-
} else {
|
|
22382
|
-
onSelect(e);
|
|
22383
|
-
}
|
|
22384
|
-
},
|
|
22399
|
+
onClick: handleItemClick,
|
|
22385
22400
|
onMouseEnter: onHover,
|
|
22386
22401
|
className: `
|
|
22387
|
-
w-full flex items-center gap-
|
|
22388
|
-
transition-colors duration-75 group relative
|
|
22402
|
+
w-full flex items-center gap-2 px-2 py-1 rounded-md text-left cursor-pointer
|
|
22403
|
+
transition-colors duration-75 group relative justify-between
|
|
22389
22404
|
${isActive ? "text-accent-foreground bg-accent" : "hover:bg-accent hover:text-accent-foreground"}
|
|
22390
22405
|
`,
|
|
22391
22406
|
children: [
|
|
22392
|
-
|
|
22393
|
-
"span",
|
|
22394
|
-
{
|
|
22395
|
-
className: `relative flex-shrink-0 w-8 h-8 flex items-center justify-center rounded-md text-base
|
|
22396
|
-
${isSelected ? "bg-primary text-primary-foreground" : isActive ? "bg-primary/20 text-primary" : "bg-muted text-muted-foreground group-hover:text-foreground"}`,
|
|
22397
|
-
children: item.icon
|
|
22398
|
-
}
|
|
22399
|
-
),
|
|
22400
|
-
/* @__PURE__ */ jsxs("div", { className: "relative flex-1 min-w-0 px-1", children: [
|
|
22407
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex-1 min-w-0", children: [
|
|
22401
22408
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [
|
|
22402
22409
|
/* @__PURE__ */ jsx(
|
|
22403
22410
|
"span",
|
|
@@ -22411,6 +22418,14 @@ function CommandItemRow({
|
|
|
22411
22418
|
item.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate", children: /* @__PURE__ */ jsx(HighlightText, { text: item.description, query: searchQuery }) })
|
|
22412
22419
|
] }),
|
|
22413
22420
|
item.shortcut && /* @__PURE__ */ jsx("div", { className: "relative hidden sm:flex items-center gap-1 flex-shrink-0", children: item.shortcut.map((k, i) => /* @__PURE__ */ jsx(Kbd, { children: k }, i)) }),
|
|
22421
|
+
multiSelect && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
22422
|
+
CheckboxBase,
|
|
22423
|
+
{
|
|
22424
|
+
checked: isSelected,
|
|
22425
|
+
onCheckedChange: handleCheckboxChange,
|
|
22426
|
+
className: "h-4 w-4 pointer-events-none"
|
|
22427
|
+
}
|
|
22428
|
+
) }),
|
|
22414
22429
|
isSelected && /* @__PURE__ */ jsx(
|
|
22415
22430
|
motion.div,
|
|
22416
22431
|
{
|
|
@@ -22418,7 +22433,8 @@ function CommandItemRow({
|
|
|
22418
22433
|
className: "absolute left-0 top-1/2 -translate-y-1/2 w-1 h-2/3 bg-primary rounded-r-md"
|
|
22419
22434
|
}
|
|
22420
22435
|
),
|
|
22421
|
-
|
|
22436
|
+
!isSelected && /* @__PURE__ */ jsx("div", { className: "absolute left-0 top-1/2 -translate-y-1/2 w-1 h-2/3 bg-transparent rounded-r-md" }),
|
|
22437
|
+
isActive && !isSelected && !multiSelect && /* @__PURE__ */ jsx(
|
|
22422
22438
|
CaretRightIcon,
|
|
22423
22439
|
{
|
|
22424
22440
|
className: "relative w-4 h-4 text-primary flex-shrink-0",
|
|
@@ -22440,12 +22456,15 @@ function useCommandPalette({
|
|
|
22440
22456
|
maxRecentItems = 5,
|
|
22441
22457
|
multiSearch = false,
|
|
22442
22458
|
multiSelect = false,
|
|
22443
|
-
onSelectMultiple
|
|
22459
|
+
onSelectMultiple,
|
|
22460
|
+
onMultiSearchSubmit
|
|
22444
22461
|
}) {
|
|
22445
22462
|
const [query, setQuery] = React32.useState("");
|
|
22446
22463
|
const [activeIndex, setActiveIndex] = React32.useState(0);
|
|
22447
22464
|
const [page, setPage] = React32.useState(0);
|
|
22448
|
-
const [selectedItemIds, setSelectedItemIds] = React32.useState(
|
|
22465
|
+
const [selectedItemIds, setSelectedItemIds] = React32.useState(
|
|
22466
|
+
/* @__PURE__ */ new Set()
|
|
22467
|
+
);
|
|
22449
22468
|
const stateRef = useRef({
|
|
22450
22469
|
activeIndex,
|
|
22451
22470
|
page,
|
|
@@ -22462,27 +22481,44 @@ function useCommandPalette({
|
|
|
22462
22481
|
});
|
|
22463
22482
|
}, []);
|
|
22464
22483
|
const clearSelection = useCallback(() => setSelectedItemIds(/* @__PURE__ */ new Set()), []);
|
|
22465
|
-
const baseGroups = useMemo(
|
|
22484
|
+
const baseGroups = useMemo(
|
|
22485
|
+
() => normaliseGroups(items, groups),
|
|
22486
|
+
[items, groups]
|
|
22487
|
+
);
|
|
22466
22488
|
useEffect(() => {
|
|
22467
22489
|
if (open) {
|
|
22468
|
-
|
|
22490
|
+
const savedQuery = localStorage.getItem("commandPaletteQuery") || "";
|
|
22491
|
+
setQuery(savedQuery);
|
|
22469
22492
|
setActiveIndex(0);
|
|
22470
22493
|
setPage(0);
|
|
22471
|
-
|
|
22494
|
+
if (!multiSelect) {
|
|
22495
|
+
clearSelection();
|
|
22496
|
+
}
|
|
22472
22497
|
}
|
|
22473
|
-
}, [open, clearSelection]);
|
|
22498
|
+
}, [open, clearSelection, multiSelect]);
|
|
22499
|
+
useEffect(() => {
|
|
22500
|
+
if (!open) {
|
|
22501
|
+
localStorage.setItem("commandPaletteQuery", query);
|
|
22502
|
+
}
|
|
22503
|
+
}, [open, query]);
|
|
22474
22504
|
const searchTerms = useMemo(() => {
|
|
22475
22505
|
const parts = query.split(",");
|
|
22476
|
-
|
|
22477
|
-
|
|
22506
|
+
const terms = parts.map((t) => t.trim().toLowerCase()).filter(Boolean);
|
|
22507
|
+
if (terms.length > 1) return terms;
|
|
22508
|
+
if (multiSearch && terms.length > 0) return terms;
|
|
22509
|
+
return [];
|
|
22478
22510
|
}, [query, multiSearch]);
|
|
22479
22511
|
const allMatchedGroups = useMemo(() => {
|
|
22480
|
-
if (!query.trim())
|
|
22481
|
-
|
|
22482
|
-
|
|
22483
|
-
|
|
22484
|
-
|
|
22485
|
-
|
|
22512
|
+
if (!query.trim()) return baseGroups;
|
|
22513
|
+
if (searchTerms.length > 0) {
|
|
22514
|
+
return unionGroups(baseGroups, searchTerms);
|
|
22515
|
+
}
|
|
22516
|
+
return filterAndScore(baseGroups, query);
|
|
22517
|
+
}, [query, baseGroups, searchTerms]);
|
|
22518
|
+
const allFlatItems = useMemo(
|
|
22519
|
+
() => allMatchedGroups.flatMap((g) => g.items),
|
|
22520
|
+
[allMatchedGroups]
|
|
22521
|
+
);
|
|
22486
22522
|
const totalItems = allFlatItems.length;
|
|
22487
22523
|
const totalPages = Math.max(1, Math.ceil(totalItems / PAGE_SIZE));
|
|
22488
22524
|
useEffect(() => {
|
|
@@ -22509,8 +22545,14 @@ function useCommandPalette({
|
|
|
22509
22545
|
}
|
|
22510
22546
|
return result;
|
|
22511
22547
|
}, [allMatchedGroups, page]);
|
|
22512
|
-
const flatItems = useMemo(
|
|
22513
|
-
|
|
22548
|
+
const flatItems = useMemo(
|
|
22549
|
+
() => displayedGroups.flatMap((g) => g.items),
|
|
22550
|
+
[displayedGroups]
|
|
22551
|
+
);
|
|
22552
|
+
const selectedItems = useMemo(
|
|
22553
|
+
() => allFlatItems.filter((i) => selectedItemIds.has(i.id)),
|
|
22554
|
+
[allFlatItems, selectedItemIds]
|
|
22555
|
+
);
|
|
22514
22556
|
useEffect(() => {
|
|
22515
22557
|
stateRef.current = { activeIndex, page, flatItems, query, selectedItems };
|
|
22516
22558
|
}, [activeIndex, page, flatItems, query, selectedItems]);
|
|
@@ -22519,47 +22561,92 @@ function useCommandPalette({
|
|
|
22519
22561
|
onSelectMultiple(selectedItems);
|
|
22520
22562
|
onOpenChange?.(false);
|
|
22521
22563
|
}, [onSelectMultiple, selectedItems, onOpenChange]);
|
|
22522
|
-
const handleSelect = useCallback(
|
|
22523
|
-
|
|
22524
|
-
|
|
22525
|
-
|
|
22526
|
-
|
|
22527
|
-
|
|
22528
|
-
|
|
22564
|
+
const handleSelect = useCallback(
|
|
22565
|
+
(item, event) => {
|
|
22566
|
+
if (!item) return;
|
|
22567
|
+
if (multiSelect) {
|
|
22568
|
+
const isCmdKey = event && ("ctrlKey" in event || "metaKey" in event || "shiftKey" in event) && (event.ctrlKey || event.metaKey || event.shiftKey);
|
|
22569
|
+
if (isCmdKey) {
|
|
22570
|
+
toggleSelection(item.id);
|
|
22571
|
+
return;
|
|
22572
|
+
}
|
|
22573
|
+
if (selectedItems.length > 0) {
|
|
22574
|
+
const finalItems = selectedItemIds.has(item.id) ? selectedItems : [...selectedItems, item];
|
|
22575
|
+
onSelectMultiple?.(finalItems);
|
|
22576
|
+
onOpenChange?.(false);
|
|
22577
|
+
return;
|
|
22578
|
+
}
|
|
22529
22579
|
}
|
|
22530
|
-
|
|
22531
|
-
|
|
22532
|
-
|
|
22533
|
-
|
|
22534
|
-
|
|
22580
|
+
item.onSelect();
|
|
22581
|
+
onOpenChange?.(false);
|
|
22582
|
+
if (onRecentItemsChange) {
|
|
22583
|
+
const next = [
|
|
22584
|
+
item,
|
|
22585
|
+
...recentItems.filter((r) => r.id !== item.id)
|
|
22586
|
+
].slice(0, maxRecentItems);
|
|
22587
|
+
onRecentItemsChange(next);
|
|
22535
22588
|
}
|
|
22536
|
-
}
|
|
22537
|
-
|
|
22538
|
-
|
|
22539
|
-
|
|
22540
|
-
|
|
22541
|
-
|
|
22542
|
-
|
|
22543
|
-
|
|
22589
|
+
},
|
|
22590
|
+
[
|
|
22591
|
+
multiSelect,
|
|
22592
|
+
selectedItems,
|
|
22593
|
+
selectedItemIds,
|
|
22594
|
+
onSelectMultiple,
|
|
22595
|
+
onOpenChange,
|
|
22596
|
+
onRecentItemsChange,
|
|
22597
|
+
recentItems,
|
|
22598
|
+
maxRecentItems,
|
|
22599
|
+
toggleSelection
|
|
22600
|
+
]
|
|
22601
|
+
);
|
|
22544
22602
|
useEffect(() => {
|
|
22545
22603
|
if (!open) return;
|
|
22546
22604
|
const handler = (e) => {
|
|
22547
|
-
const { activeIndex: curIdx, flatItems: curItems
|
|
22605
|
+
const { activeIndex: curIdx, flatItems: curItems } = stateRef.current;
|
|
22548
22606
|
if (e.key === "ArrowDown") {
|
|
22549
22607
|
e.preventDefault();
|
|
22550
|
-
if (curIdx === curItems.length - 1 && page < totalPages - 1)
|
|
22608
|
+
if (curIdx === curItems.length - 1 && page < totalPages - 1)
|
|
22609
|
+
setPage((p) => p + 1);
|
|
22551
22610
|
else setActiveIndex((i) => (i + 1) % Math.max(curItems.length, 1));
|
|
22552
22611
|
} else if (e.key === "ArrowUp") {
|
|
22553
22612
|
e.preventDefault();
|
|
22554
22613
|
if (curIdx === 0 && page > 0) {
|
|
22555
22614
|
setPage((p) => p - 1);
|
|
22556
22615
|
setActiveIndex(PAGE_SIZE - 1);
|
|
22557
|
-
} else
|
|
22616
|
+
} else
|
|
22617
|
+
setActiveIndex(
|
|
22618
|
+
(i) => (i - 1 + Math.max(curItems.length, 1)) % Math.max(curItems.length, 1)
|
|
22619
|
+
);
|
|
22558
22620
|
} else if (e.key === "Enter") {
|
|
22559
22621
|
e.preventDefault();
|
|
22560
|
-
|
|
22622
|
+
const currentSelectedItems = allFlatItems.filter(
|
|
22623
|
+
(i) => selectedItemIds.has(i.id)
|
|
22624
|
+
);
|
|
22625
|
+
if (multiSelect && currentSelectedItems.length > 0) {
|
|
22626
|
+
const selectedLabels = currentSelectedItems.map((item) => item.label);
|
|
22627
|
+
onMultiSearchSubmit?.(selectedLabels);
|
|
22561
22628
|
return;
|
|
22562
22629
|
}
|
|
22630
|
+
if (multiSearch && query.trim().length > 0) {
|
|
22631
|
+
const terms = query.split(",").map((t) => t.trim()).filter(Boolean);
|
|
22632
|
+
if (terms.length > 0) {
|
|
22633
|
+
if (multiSelect) {
|
|
22634
|
+
const matchedItems = allFlatItems.filter(
|
|
22635
|
+
(item) => terms.some(
|
|
22636
|
+
(term) => item.label.toLowerCase().includes(term.toLowerCase()) || item.id.toLowerCase().includes(term.toLowerCase())
|
|
22637
|
+
)
|
|
22638
|
+
);
|
|
22639
|
+
const newSelectedIds = new Set(selectedItemIds);
|
|
22640
|
+
matchedItems.forEach((item) => newSelectedIds.add(item.id));
|
|
22641
|
+
setSelectedItemIds(newSelectedIds);
|
|
22642
|
+
const selectedLabels = matchedItems.map((item) => item.label);
|
|
22643
|
+
onMultiSearchSubmit?.(selectedLabels);
|
|
22644
|
+
return;
|
|
22645
|
+
}
|
|
22646
|
+
onMultiSearchSubmit?.(terms);
|
|
22647
|
+
return;
|
|
22648
|
+
}
|
|
22649
|
+
}
|
|
22563
22650
|
if (multiSelect && (e.ctrlKey || e.metaKey)) {
|
|
22564
22651
|
executeBulkAction();
|
|
22565
22652
|
return;
|
|
@@ -22569,7 +22656,20 @@ function useCommandPalette({
|
|
|
22569
22656
|
};
|
|
22570
22657
|
window.addEventListener("keydown", handler);
|
|
22571
22658
|
return () => window.removeEventListener("keydown", handler);
|
|
22572
|
-
}, [
|
|
22659
|
+
}, [
|
|
22660
|
+
open,
|
|
22661
|
+
page,
|
|
22662
|
+
totalPages,
|
|
22663
|
+
multiSearch,
|
|
22664
|
+
multiSelect,
|
|
22665
|
+
handleSelect,
|
|
22666
|
+
executeBulkAction,
|
|
22667
|
+
onMultiSearchSubmit,
|
|
22668
|
+
selectedItems,
|
|
22669
|
+
allFlatItems,
|
|
22670
|
+
selectedItemIds,
|
|
22671
|
+
query
|
|
22672
|
+
]);
|
|
22573
22673
|
return {
|
|
22574
22674
|
query,
|
|
22575
22675
|
setQuery,
|
|
@@ -22590,7 +22690,7 @@ function useCommandPalette({
|
|
|
22590
22690
|
selectedItems,
|
|
22591
22691
|
executeBulkAction,
|
|
22592
22692
|
isEmpty: totalItems === 0 && query.trim().length > 0,
|
|
22593
|
-
showList:
|
|
22693
|
+
showList: true
|
|
22594
22694
|
};
|
|
22595
22695
|
}
|
|
22596
22696
|
function useKeyboardShortcut(key, callback, options = {}) {
|
|
@@ -22890,7 +22990,16 @@ function CommandPalette(props) {
|
|
|
22890
22990
|
className: "flex-1 bg-transparent border-none shadow-none focus-visible:ring-0 p-0 text-base"
|
|
22891
22991
|
}
|
|
22892
22992
|
),
|
|
22893
|
-
query && /* @__PURE__ */ jsx(
|
|
22993
|
+
query && /* @__PURE__ */ jsx(
|
|
22994
|
+
ButtonBase,
|
|
22995
|
+
{
|
|
22996
|
+
variant: "ghost",
|
|
22997
|
+
size: "icon",
|
|
22998
|
+
onClick: handleClearQuery,
|
|
22999
|
+
className: "h-8 w-8",
|
|
23000
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "w-4 h-4" })
|
|
23001
|
+
}
|
|
23002
|
+
)
|
|
22894
23003
|
]
|
|
22895
23004
|
}
|
|
22896
23005
|
),
|
|
@@ -22943,7 +23052,13 @@ function CommandPalette(props) {
|
|
|
22943
23052
|
style: { maxHeight: "min(600px, 80vh)" },
|
|
22944
23053
|
children: [
|
|
22945
23054
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 px-4 py-2 border-b border-border", children: [
|
|
22946
|
-
/* @__PURE__ */ jsx(
|
|
23055
|
+
/* @__PURE__ */ jsx(
|
|
23056
|
+
MagnifyingGlassIcon,
|
|
23057
|
+
{
|
|
23058
|
+
className: "w-4 h-4 text-muted-foreground flex-shrink-0",
|
|
23059
|
+
weight: "bold"
|
|
23060
|
+
}
|
|
23061
|
+
),
|
|
22947
23062
|
/* @__PURE__ */ jsx(
|
|
22948
23063
|
DebouncedInput,
|
|
22949
23064
|
{
|
|
@@ -22974,7 +23089,8 @@ function CommandPalette(props) {
|
|
|
22974
23089
|
footer,
|
|
22975
23090
|
totalItems,
|
|
22976
23091
|
selectedCount: selectedItemIds.size,
|
|
22977
|
-
executeBulkAction
|
|
23092
|
+
executeBulkAction,
|
|
23093
|
+
multiSelect
|
|
22978
23094
|
}
|
|
22979
23095
|
)
|
|
22980
23096
|
]
|