@facter/ds-core 1.33.0 → 1.33.2

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.mjs CHANGED
@@ -17,6 +17,7 @@ import { toast as toast$1, Toaster as Toaster$1 } from 'sonner';
17
17
  import * as SwitchPrimitives from '@radix-ui/react-switch';
18
18
  import { FormProvider, useFormContext, Controller } from 'react-hook-form';
19
19
  export { FormProvider, useFormContext } from 'react-hook-form';
20
+ import { createPortal } from 'react-dom';
20
21
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
21
22
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
22
23
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
@@ -2500,7 +2501,7 @@ var DataTable = Object.assign(DataTableRoot, {
2500
2501
  ColumnHeader: DataTableColumnHeader
2501
2502
  });
2502
2503
  function DialogMeshEffect() {
2503
- return /* @__PURE__ */ jsxs("div", { className: "absolute top-0 left-0 right-0 h-[180px] overflow-hidden rounded-t-lg pointer-events-none z-[1]", children: [
2504
+ return /* @__PURE__ */ jsxs("div", { className: "absolute top-0 left-0 right-0 h-[48px] overflow-hidden rounded-t-lg pointer-events-none z-[1]", children: [
2504
2505
  /* @__PURE__ */ jsx(
2505
2506
  "div",
2506
2507
  {
@@ -3487,8 +3488,10 @@ function CardSelect({
3487
3488
  const [search, setSearch] = React10.useState("");
3488
3489
  const selected = options.find((o) => o.value === value);
3489
3490
  const containerRef = React10.useRef(null);
3491
+ const dropdownRef = React10.useRef(null);
3490
3492
  const listRef = React10.useRef(null);
3491
3493
  const searchRef = React10.useRef(null);
3494
+ const [dropdownPos, setDropdownPos] = React10.useState({});
3492
3495
  const filteredOptions = React10.useMemo(() => {
3493
3496
  if (!searchable || onSearch || !search) return options;
3494
3497
  const q = search.toLowerCase();
@@ -3503,10 +3506,34 @@ function CardSelect({
3503
3506
  },
3504
3507
  [onSearch]
3505
3508
  );
3509
+ React10.useEffect(() => {
3510
+ if (!open || !containerRef.current) return;
3511
+ const updatePosition = () => {
3512
+ const rect = containerRef.current.getBoundingClientRect();
3513
+ const spaceBelow = window.innerHeight - rect.bottom;
3514
+ const estimatedHeight = 340;
3515
+ const showAbove = spaceBelow < estimatedHeight && rect.top > spaceBelow;
3516
+ setDropdownPos({
3517
+ position: "fixed",
3518
+ left: rect.left,
3519
+ width: rect.width,
3520
+ zIndex: 9999,
3521
+ ...showAbove ? { bottom: window.innerHeight - rect.top + 4 } : { top: rect.bottom + 4 }
3522
+ });
3523
+ };
3524
+ updatePosition();
3525
+ window.addEventListener("scroll", updatePosition, true);
3526
+ window.addEventListener("resize", updatePosition);
3527
+ return () => {
3528
+ window.removeEventListener("scroll", updatePosition, true);
3529
+ window.removeEventListener("resize", updatePosition);
3530
+ };
3531
+ }, [open]);
3506
3532
  React10.useEffect(() => {
3507
3533
  if (!open) return;
3508
3534
  const handleClickOutside = (e) => {
3509
- if (containerRef.current && !containerRef.current.contains(e.target)) {
3535
+ const target = e.target;
3536
+ if (containerRef.current && !containerRef.current.contains(target) && (!dropdownRef.current || !dropdownRef.current.contains(target))) {
3510
3537
  setOpen(false);
3511
3538
  }
3512
3539
  };
@@ -3595,63 +3622,74 @@ function CardSelect({
3595
3622
  ]
3596
3623
  }
3597
3624
  ),
3598
- open && /* @__PURE__ */ jsxs("div", { className: "absolute left-0 top-full z-50 mt-1 w-full rounded-md border border-border bg-popover shadow-md overflow-hidden animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-150", children: [
3599
- searchable && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border", children: [
3600
- /* @__PURE__ */ jsx(Search, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
3601
- /* @__PURE__ */ jsx(
3602
- "input",
3603
- {
3604
- ref: searchRef,
3605
- type: "text",
3606
- value: search,
3607
- onChange: (e) => handleSearch(e.target.value),
3608
- placeholder: searchPlaceholder,
3609
- className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
3610
- }
3611
- )
3612
- ] }),
3613
- /* @__PURE__ */ jsx(
3625
+ open && createPortal(
3626
+ /* @__PURE__ */ jsxs(
3614
3627
  "div",
3615
3628
  {
3616
- ref: listRef,
3617
- className: "overflow-y-auto overscroll-contain max-h-[300px]",
3618
- onScroll: handleScroll,
3619
- children: /* @__PURE__ */ jsxs("div", { className: "divide-y divide-border/50 p-2", children: [
3620
- filteredOptions.length === 0 && !loading ? /* @__PURE__ */ jsx("p", { className: "py-4 text-center text-sm text-muted-foreground", children: emptyText }) : filteredOptions.map((option) => {
3621
- const isSelected = value === option.value;
3622
- const isDisabled = option.disabled || disabled;
3623
- return /* @__PURE__ */ jsxs(
3624
- "button",
3629
+ ref: dropdownRef,
3630
+ style: dropdownPos,
3631
+ className: "rounded-md border border-border bg-popover shadow-md overflow-hidden animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-150",
3632
+ children: [
3633
+ searchable && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border", children: [
3634
+ /* @__PURE__ */ jsx(Search, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
3635
+ /* @__PURE__ */ jsx(
3636
+ "input",
3625
3637
  {
3626
- type: "button",
3627
- disabled: isDisabled,
3628
- onClick: () => {
3629
- onChange(option.value);
3630
- setOpen(false);
3631
- },
3632
- className: cn(
3633
- "flex w-full items-center gap-3 p-3 text-left transition-all",
3634
- "cursor-pointer hover:bg-accent",
3635
- isSelected && "bg-primary/5",
3636
- isDisabled && "cursor-not-allowed opacity-50 hover:bg-transparent"
3637
- ),
3638
- children: [
3639
- option.icon && /* @__PURE__ */ jsx("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx(option.icon, { className: "h-3.5 w-3.5 text-primary" }) }),
3640
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
3641
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium leading-tight", children: option.label }),
3642
- option.description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs leading-tight text-muted-foreground", children: option.description })
3643
- ] }),
3644
- isSelected && /* @__PURE__ */ jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) })
3645
- ]
3646
- },
3647
- option.value
3648
- );
3649
- }),
3650
- loading && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-3", children: /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) })
3651
- ] })
3638
+ ref: searchRef,
3639
+ type: "text",
3640
+ value: search,
3641
+ onChange: (e) => handleSearch(e.target.value),
3642
+ placeholder: searchPlaceholder,
3643
+ className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
3644
+ }
3645
+ )
3646
+ ] }),
3647
+ /* @__PURE__ */ jsx(
3648
+ "div",
3649
+ {
3650
+ ref: listRef,
3651
+ className: "overflow-y-auto overscroll-contain max-h-[300px]",
3652
+ onScroll: handleScroll,
3653
+ children: /* @__PURE__ */ jsxs("div", { className: "divide-y divide-border/50 p-2", children: [
3654
+ filteredOptions.length === 0 && !loading ? /* @__PURE__ */ jsx("p", { className: "py-4 text-center text-sm text-muted-foreground", children: emptyText }) : filteredOptions.map((option) => {
3655
+ const isSelected = value === option.value;
3656
+ const isDisabled = option.disabled || disabled;
3657
+ return /* @__PURE__ */ jsxs(
3658
+ "button",
3659
+ {
3660
+ type: "button",
3661
+ disabled: isDisabled,
3662
+ onClick: () => {
3663
+ onChange(option.value);
3664
+ setOpen(false);
3665
+ },
3666
+ className: cn(
3667
+ "flex w-full items-center gap-3 p-3 text-left transition-all",
3668
+ "cursor-pointer hover:bg-accent",
3669
+ isSelected && "bg-primary/5",
3670
+ isDisabled && "cursor-not-allowed opacity-50 hover:bg-transparent"
3671
+ ),
3672
+ children: [
3673
+ option.icon && /* @__PURE__ */ jsx("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx(option.icon, { className: "h-3.5 w-3.5 text-primary" }) }),
3674
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
3675
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium leading-tight", children: option.label }),
3676
+ option.description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs leading-tight text-muted-foreground", children: option.description })
3677
+ ] }),
3678
+ isSelected && /* @__PURE__ */ jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) })
3679
+ ]
3680
+ },
3681
+ option.value
3682
+ );
3683
+ }),
3684
+ loading && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-3", children: /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) })
3685
+ ] })
3686
+ }
3687
+ )
3688
+ ]
3652
3689
  }
3653
- )
3654
- ] })
3690
+ ),
3691
+ document.body
3692
+ )
3655
3693
  ] });
3656
3694
  }
3657
3695
  function FormTextarea({