@motor-hero/ui-kit 0.24.0 → 0.25.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/index.js CHANGED
@@ -615,7 +615,7 @@ PasswordInput.displayName = "PasswordInput";
615
615
  // src/components/combobox.tsx
616
616
  import * as PopoverPrimitive from "@radix-ui/react-popover";
617
617
  import { Command as CommandPrimitive } from "cmdk";
618
- import { Check, ChevronsUpDown, Loader2, Search } from "lucide-react";
618
+ import { Check, ChevronsUpDown, Loader2, Plus, Search } from "lucide-react";
619
619
  import * as React6 from "react";
620
620
  import { Drawer as DrawerPrimitive } from "vaul";
621
621
 
@@ -688,12 +688,31 @@ function Combobox({
688
688
  onLoadMore,
689
689
  loading,
690
690
  hasMore,
691
- selectedOption
691
+ selectedOption,
692
+ creatable,
693
+ formatCreateLabel
692
694
  }) {
693
695
  const [open, setOpen] = React6.useState(false);
696
+ const [search, setSearch] = React6.useState("");
694
697
  const isDesktop = useIsDesktop();
695
698
  const isServer = onSearchChange !== void 0;
696
- const selected = selectedOption?.value === value ? selectedOption : options.find((option) => option.value === value);
699
+ const selected = selectedOption?.value === value ? selectedOption : options.find((option) => option.value === value) ?? (creatable && value ? { value, label: value } : void 0);
700
+ const handleOpenChange = (next) => {
701
+ setOpen(next);
702
+ if (!next) setSearch("");
703
+ };
704
+ const handleSelect = (next) => {
705
+ onChange(next);
706
+ handleOpenChange(false);
707
+ };
708
+ const handleSearchChange = (next) => {
709
+ setSearch(next);
710
+ onSearchChange?.(next);
711
+ };
712
+ const trimmedSearch = search.trim();
713
+ const showCreate = !!creatable && trimmedSearch.length > 0 && !options.some(
714
+ (option) => option.value.toLowerCase() === trimmedSearch.toLowerCase()
715
+ );
697
716
  const { listRef, sentinelRef } = useInfiniteScrollSentinel({
698
717
  enabled: isServer && !!hasMore,
699
718
  loading,
@@ -731,7 +750,7 @@ function Combobox({
731
750
  CommandPrimitive.Input,
732
751
  {
733
752
  placeholder: searchPlaceholder,
734
- onValueChange: isServer ? onSearchChange : void 0,
753
+ onValueChange: isServer || creatable ? handleSearchChange : void 0,
735
754
  className: "flex h-11 w-full bg-transparent py-2 text-base outline-none placeholder:text-muted-foreground sm:h-9 sm:text-sm"
736
755
  }
737
756
  )
@@ -742,16 +761,27 @@ function Combobox({
742
761
  ref: listRef,
743
762
  className: "max-h-[50vh] overflow-y-auto overflow-x-hidden p-1 sm:max-h-60",
744
763
  children: [
745
- !isServer && /* @__PURE__ */ jsx16(CommandPrimitive.Empty, { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }),
764
+ !isServer && !showCreate && /* @__PURE__ */ jsx16(CommandPrimitive.Empty, { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }),
765
+ showCreate && /* @__PURE__ */ jsxs14(
766
+ CommandPrimitive.Item,
767
+ {
768
+ value: trimmedSearch,
769
+ onSelect: () => handleSelect(trimmedSearch),
770
+ className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2.5 text-sm outline-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground sm:py-1.5",
771
+ children: [
772
+ /* @__PURE__ */ jsx16(Plus, { className: "h-4 w-4 shrink-0" }),
773
+ /* @__PURE__ */ jsx16("span", { className: "truncate", children: (formatCreateLabel ?? ((text) => `Usar "${text}"`))(
774
+ trimmedSearch
775
+ ) })
776
+ ]
777
+ }
778
+ ),
746
779
  options.map((option) => /* @__PURE__ */ jsxs14(
747
780
  CommandPrimitive.Item,
748
781
  {
749
782
  value: isServer ? option.value : option.label,
750
783
  disabled: option.disabled,
751
- onSelect: () => {
752
- onChange(option.value);
753
- setOpen(false);
754
- },
784
+ onSelect: () => handleSelect(option.value),
755
785
  className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2.5 text-sm outline-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 sm:py-1.5",
756
786
  children: [
757
787
  /* @__PURE__ */ jsx16(
@@ -778,7 +808,7 @@ function Combobox({
778
808
  }
779
809
  );
780
810
  if (isDesktop) {
781
- return /* @__PURE__ */ jsxs14(PopoverPrimitive.Root, { open, onOpenChange: setOpen, children: [
811
+ return /* @__PURE__ */ jsxs14(PopoverPrimitive.Root, { open, onOpenChange: handleOpenChange, children: [
782
812
  /* @__PURE__ */ jsx16(PopoverPrimitive.Trigger, { asChild: true, children: trigger }),
783
813
  /* @__PURE__ */ jsx16(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx16(
784
814
  PopoverPrimitive.Content,
@@ -792,7 +822,7 @@ function Combobox({
792
822
  ) })
793
823
  ] });
794
824
  }
795
- return /* @__PURE__ */ jsxs14(DrawerPrimitive.Root, { open, onOpenChange: setOpen, children: [
825
+ return /* @__PURE__ */ jsxs14(DrawerPrimitive.Root, { open, onOpenChange: handleOpenChange, children: [
796
826
  /* @__PURE__ */ jsx16(DrawerPrimitive.Trigger, { asChild: true, children: trigger }),
797
827
  /* @__PURE__ */ jsxs14(DrawerPrimitive.Portal, { children: [
798
828
  /* @__PURE__ */ jsx16(DrawerPrimitive.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),