@inf-monkeys-tech/monkeys-design 1.0.97 → 1.0.99

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.
@@ -6,6 +6,8 @@ import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, close
6
6
  import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, useSortable, defaultAnimateLayoutChanges } from '@dnd-kit/sortable';
7
7
  import { CSS } from '@dnd-kit/utilities';
8
8
  import { createPortal } from 'react-dom';
9
+ import * as Popover from '@radix-ui/react-popover';
10
+ import { ChevronDown, Search, Loader2, Check, X } from 'lucide-react';
9
11
 
10
12
  // src/components/data-explorer/DataExplorerToolbarActions.tsx
11
13
 
@@ -6421,6 +6423,185 @@ function DataExplorerRecordCard({
6421
6423
  }
6422
6424
  );
6423
6425
  }
6426
+ var normalizeValues = (value, multiple) => {
6427
+ const values = multiple ? Array.isArray(value) ? value : value ? [value] : [] : typeof value === "string" ? [value] : [];
6428
+ return Array.from(new Set(values.filter((item) => typeof item === "string" && item.length > 0)));
6429
+ };
6430
+ var getOptionText = (option) => option.textValue ?? (typeof option.label === "string" ? option.label : option.value);
6431
+ function DataExplorerRecordPicker({
6432
+ value,
6433
+ activeValue,
6434
+ options = [],
6435
+ createOption,
6436
+ multiple = false,
6437
+ placeholder = "Select a record",
6438
+ triggerLabel,
6439
+ triggerIcon,
6440
+ searchPlaceholder = "Search records",
6441
+ emptyState = "No records found",
6442
+ loadingState,
6443
+ errorState,
6444
+ loading = false,
6445
+ disabled = false,
6446
+ open,
6447
+ defaultOpen = false,
6448
+ searchValue,
6449
+ defaultSearchValue = "",
6450
+ appearance,
6451
+ className,
6452
+ classNames,
6453
+ triggerProps,
6454
+ dataAttributes,
6455
+ onOpenChange,
6456
+ onListScroll,
6457
+ onSearchValueChange,
6458
+ onValueChange
6459
+ }) {
6460
+ const theme = resolveDataExplorerAppearance(appearance);
6461
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
6462
+ const [uncontrolledSearch, setUncontrolledSearch] = useState(defaultSearchValue);
6463
+ const isControlledOpen = open !== void 0;
6464
+ const isOpen = isControlledOpen ? open : uncontrolledOpen;
6465
+ const isControlledSearch = searchValue !== void 0;
6466
+ const query = isControlledSearch ? searchValue : uncontrolledSearch;
6467
+ const selectedValues = useMemo(() => normalizeValues(value, multiple), [multiple, value]);
6468
+ const selectedSet = useMemo(() => new Set(selectedValues), [selectedValues]);
6469
+ const selectedOptions = selectedValues.map((selectedValue) => options.find((option) => option.value === selectedValue)).filter((option) => Boolean(option));
6470
+ const visibleOptions = createOption ? [createOption, ...options] : options;
6471
+ const triggerValue = selectedOptions.length ? multiple && selectedOptions.length > 1 ? `${selectedOptions.slice(0, 2).map((option) => getOptionText(option)).join(", ")} +${selectedOptions.length - 2}` : getOptionText(selectedOptions[0]) : placeholder;
6472
+ useEffect(() => {
6473
+ if (!isOpen) return;
6474
+ const handleKeyDown = (event) => {
6475
+ if (event.key === "Escape") onOpenChange?.(false);
6476
+ };
6477
+ window.addEventListener("keydown", handleKeyDown);
6478
+ return () => window.removeEventListener("keydown", handleKeyDown);
6479
+ }, [isOpen, onOpenChange]);
6480
+ const setOpen = (nextOpen) => {
6481
+ if (disabled) return;
6482
+ if (!isControlledOpen) setUncontrolledOpen(nextOpen);
6483
+ onOpenChange?.(nextOpen);
6484
+ };
6485
+ const setQuery = (nextQuery) => {
6486
+ if (!isControlledSearch) setUncontrolledSearch(nextQuery);
6487
+ onSearchValueChange?.(nextQuery);
6488
+ };
6489
+ const handleOptionClick = (option) => {
6490
+ if (disabled || option.disabled) return;
6491
+ if (multiple) {
6492
+ const nextValues = selectedSet.has(option.value) ? selectedValues.filter((selectedValue) => selectedValue !== option.value) : [...selectedValues, option.value];
6493
+ onValueChange?.(nextValues);
6494
+ return;
6495
+ }
6496
+ onValueChange?.(option.value);
6497
+ setOpen(false);
6498
+ };
6499
+ const removeValue = (selectedValue) => {
6500
+ if (disabled) return;
6501
+ onValueChange?.(selectedValues.filter((valueItem) => valueItem !== selectedValue));
6502
+ };
6503
+ return /* @__PURE__ */ jsxs("div", { ...dataAttributes?.root, className: cn("relative min-w-0 w-full", classNames?.root, className), children: [
6504
+ /* @__PURE__ */ jsxs(Popover.Root, { open: isOpen, onOpenChange: setOpen, children: [
6505
+ /* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
6506
+ "button",
6507
+ {
6508
+ ...triggerProps,
6509
+ ...dataAttributes?.trigger,
6510
+ type: "button",
6511
+ disabled,
6512
+ "aria-label": triggerLabel,
6513
+ "aria-expanded": isOpen,
6514
+ className: cn(theme.slots.controlSelectTrigger, classNames?.trigger),
6515
+ children: [
6516
+ triggerIcon,
6517
+ /* @__PURE__ */ jsx("span", { ...dataAttributes?.triggerValue, className: cn(theme.slots.controlSelectValue, !selectedOptions.length && "text-muted-foreground", classNames?.triggerValue), children: triggerValue }),
6518
+ /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" })
6519
+ ]
6520
+ }
6521
+ ) }),
6522
+ /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(
6523
+ Popover.Content,
6524
+ {
6525
+ ...dataAttributes?.content,
6526
+ align: "start",
6527
+ sideOffset: 6,
6528
+ className: cn("z-50 w-[min(30rem,calc(100vw-2rem))] rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-md", classNames?.content),
6529
+ onOpenAutoFocus: (event) => event.preventDefault(),
6530
+ children: [
6531
+ /* @__PURE__ */ jsxs("label", { className: cn("flex h-9 items-center gap-2 rounded-md border border-border bg-background px-2 text-sm", classNames?.search), children: [
6532
+ /* @__PURE__ */ jsx(Search, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
6533
+ /* @__PURE__ */ jsx(
6534
+ "input",
6535
+ {
6536
+ autoFocus: true,
6537
+ value: query,
6538
+ onChange: (event) => setQuery(event.target.value),
6539
+ placeholder: searchPlaceholder,
6540
+ "aria-label": searchPlaceholder,
6541
+ className: "min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground"
6542
+ }
6543
+ )
6544
+ ] }),
6545
+ /* @__PURE__ */ jsx(
6546
+ "div",
6547
+ {
6548
+ className: cn("mt-2 max-h-72 overflow-y-auto", classNames?.list),
6549
+ ...dataAttributes?.list,
6550
+ role: "listbox",
6551
+ "aria-multiselectable": multiple || void 0,
6552
+ onScroll: onListScroll,
6553
+ children: loading ? /* @__PURE__ */ jsxs("div", { ...dataAttributes?.loading, className: cn("flex min-h-16 items-center justify-center gap-2 px-3 py-4 text-sm text-muted-foreground", classNames?.status), children: [
6554
+ /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" }),
6555
+ loadingState ?? "Loading records..."
6556
+ ] }) : errorState ? /* @__PURE__ */ jsx("div", { ...dataAttributes?.error, className: cn("px-3 py-4 text-sm text-destructive-text", classNames?.status), children: errorState }) : visibleOptions.length === 0 ? /* @__PURE__ */ jsx("div", { ...dataAttributes?.empty, className: cn("px-3 py-4 text-sm text-muted-foreground", classNames?.status), children: emptyState }) : visibleOptions.map((option) => {
6557
+ const selected = selectedSet.has(option.value);
6558
+ return /* @__PURE__ */ jsxs(
6559
+ "button",
6560
+ {
6561
+ ...dataAttributes?.option,
6562
+ type: "button",
6563
+ role: "option",
6564
+ "aria-selected": selected,
6565
+ "aria-current": activeValue !== void 0 && option.value === activeValue ? "true" : void 0,
6566
+ disabled: option.disabled,
6567
+ onClick: () => handleOptionClick(option),
6568
+ className: cn(
6569
+ "flex w-full items-start gap-2 rounded-sm px-2.5 py-2 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",
6570
+ selected && "bg-accent/60",
6571
+ classNames?.option
6572
+ ),
6573
+ children: [
6574
+ /* @__PURE__ */ jsx("span", { className: cn("mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center", classNames?.optionIndicator), children: selected ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4", "aria-hidden": "true" }) : null }),
6575
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
6576
+ /* @__PURE__ */ jsx("span", { className: cn("block truncate", classNames?.optionLabel), children: option.label }),
6577
+ option.description ? /* @__PURE__ */ jsx("span", { className: cn("mt-0.5 block truncate text-xs text-muted-foreground", classNames?.optionDescription), children: option.description }) : null
6578
+ ] })
6579
+ ]
6580
+ },
6581
+ option.value
6582
+ );
6583
+ })
6584
+ }
6585
+ )
6586
+ ]
6587
+ }
6588
+ ) })
6589
+ ] }),
6590
+ multiple && selectedOptions.length > 0 ? /* @__PURE__ */ jsx("div", { className: cn("mt-2 flex flex-wrap gap-1.5", classNames?.selectedList), children: selectedOptions.map((option) => /* @__PURE__ */ jsxs("span", { className: cn("inline-flex max-w-full items-center gap-1 rounded-full border border-border bg-muted px-2 py-1 text-xs", classNames?.selectedItem), children: [
6591
+ /* @__PURE__ */ jsx("span", { className: cn("min-w-0 truncate", classNames?.selectedItemLabel), children: option.label }),
6592
+ /* @__PURE__ */ jsx(
6593
+ "button",
6594
+ {
6595
+ type: "button",
6596
+ "aria-label": `Remove ${getOptionText(option)}`,
6597
+ onClick: () => removeValue(option.value),
6598
+ className: cn("inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:bg-accent hover:text-foreground", classNames?.selectedItemRemove),
6599
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3", "aria-hidden": "true" })
6600
+ }
6601
+ )
6602
+ ] }, option.value)) }) : null
6603
+ ] });
6604
+ }
6424
6605
  function DefaultSearchIcon() {
6425
6606
  return /* @__PURE__ */ jsxs(
6426
6607
  "svg",
@@ -7503,6 +7684,6 @@ function DataExplorerViewShell({
7503
7684
  );
7504
7685
  }
7505
7686
 
7506
- export { DataExplorerActionBar, DataExplorerButton, DataExplorerCheckbox, DataExplorerCollectionFooter, DataExplorerDetailField, DataExplorerDetailSection, DataExplorerDetailShell, DataExplorerDisplayActionMenu, DataExplorerDisplayCard, DataExplorerDisplayCollectionView, DataExplorerDisplayListItem, DataExplorerDisplayMedia, DataExplorerDraggableTree, DataExplorerFilterBar, DataExplorerImagePreview, DataExplorerPage, DataExplorerRecordCard, DataExplorerSelect, DataExplorerSplitButton, DataExplorerToolbarActions, DataExplorerToolbarShell, DataExplorerTree, DataExplorerTreeShell, DataExplorerView, DataExplorerViewCollection, DataExplorerViewItem, DataExplorerViewItemShell, DataExplorerViewShell, DataExplorerViewTree, getDataExplorerActionToneClassName, getDataExplorerMenuItemToneClassName, resolveDataExplorerAppearance };
7687
+ export { DataExplorerActionBar, DataExplorerButton, DataExplorerCheckbox, DataExplorerCollectionFooter, DataExplorerDetailField, DataExplorerDetailSection, DataExplorerDetailShell, DataExplorerDisplayActionMenu, DataExplorerDisplayCard, DataExplorerDisplayCollectionView, DataExplorerDisplayListItem, DataExplorerDisplayMedia, DataExplorerDraggableTree, DataExplorerFilterBar, DataExplorerImagePreview, DataExplorerPage, DataExplorerRecordCard, DataExplorerRecordPicker, DataExplorerSelect, DataExplorerSplitButton, DataExplorerToolbarActions, DataExplorerToolbarShell, DataExplorerTree, DataExplorerTreeShell, DataExplorerView, DataExplorerViewCollection, DataExplorerViewItem, DataExplorerViewItemShell, DataExplorerViewShell, DataExplorerViewTree, getDataExplorerActionToneClassName, getDataExplorerMenuItemToneClassName, resolveDataExplorerAppearance };
7507
7688
  //# sourceMappingURL=index.mjs.map
7508
7689
  //# sourceMappingURL=index.mjs.map