@andrilla/mado-ui 1.0.10 → 1.1.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.
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { extendTailwindMerge, twJoin } from "tailwind-merge";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
- import { Button as Button$1, Checkbox as Checkbox$1, Description, Dialog, DialogBackdrop, DialogPanel, DialogTitle, Disclosure, DisclosureButton, DisclosurePanel, Field, Fieldset as Fieldset$1, Input as Input$1, Label, Legend, Listbox, ListboxButton, ListboxOption, ListboxOptions, ListboxSelectedOption, Menu, MenuButton, MenuHeading, MenuItem, MenuItems, MenuSection, MenuSeparator, Textarea as Textarea$1 } from "@headlessui/react";
4
+ import { Button as Button$1, Checkbox as Checkbox$1, Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions, Description, Dialog, DialogBackdrop, DialogPanel, DialogTitle, Disclosure, DisclosureButton, DisclosurePanel, Field, Fieldset as Fieldset$1, Input as Input$1, Label, Legend, Listbox, ListboxButton, ListboxOption, ListboxOptions, ListboxSelectedOption, Menu, MenuButton, MenuHeading, MenuItem, MenuItems, MenuSection, MenuSeparator, Textarea as Textarea$1 } from "@headlessui/react";
5
5
  import * as React from "react";
6
6
  import { Children, cloneElement, createContext, isValidElement, useContext, useEffect, useEffectEvent, useId, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
7
7
  import * as ReactDOM from "react-dom";
@@ -1252,7 +1252,7 @@ if (isBrowser) {
1252
1252
  * @param {String} str
1253
1253
  * @return {String}
1254
1254
  */
1255
- const toLowerCase = (str) => str.replace(lowerCaseRgx, "$1-$2").toLowerCase();
1255
+ const toLowerCase$1 = (str) => str.replace(lowerCaseRgx, "$1-$2").toLowerCase();
1256
1256
  /**
1257
1257
  * Prioritize this method instead of regex when possible
1258
1258
  * @param {String} str
@@ -1890,7 +1890,7 @@ const sanitizePropertyName = (propertyName, target, tweenType) => {
1890
1890
  const cachedPropertyName = propertyNamesCache[propertyName];
1891
1891
  if (cachedPropertyName) return cachedPropertyName;
1892
1892
  else {
1893
- const lowerCaseName = propertyName ? toLowerCase(propertyName) : propertyName;
1893
+ const lowerCaseName = propertyName ? toLowerCase$1(propertyName) : propertyName;
1894
1894
  propertyNamesCache[propertyName] = lowerCaseName;
1895
1895
  return lowerCaseName;
1896
1896
  }
@@ -1923,7 +1923,7 @@ const cleanInlineStyles = (renderable) => {
1923
1923
  for (let key in cachedTransforms) str += transformsFragmentStrings[key] + cachedTransforms[key] + ") ";
1924
1924
  targetStyle.transform = str;
1925
1925
  }
1926
- } else if (tweenHadNoInlineValue) targetStyle.removeProperty(toLowerCase(tweenProperty));
1926
+ } else if (tweenHadNoInlineValue) targetStyle.removeProperty(toLowerCase$1(tweenProperty));
1927
1927
  else targetStyle[tweenProperty] = originalInlinedValue;
1928
1928
  if (animation._tail === tween) animation.targets.forEach((t) => {
1929
1929
  if (t.getAttribute && t.getAttribute("style") === "") t.removeAttribute("style");
@@ -3971,6 +3971,20 @@ function getWeekdayName(weekday = d) {
3971
3971
  return weekdayNamesList[weekday.getDay()];
3972
3972
  }
3973
3973
  //#endregion
3974
+ //#region src/utils/string-manipulation.ts
3975
+ /**
3976
+ * # To Lower Case
3977
+ * Converts a string to lowercase, and offers easy string replacements for creating snake case, kebab case, or your own.
3978
+ * @param str - The string to convert to lowercase.
3979
+ * @param options - Configuration options.
3980
+ * @param options[0] - The delimiter to split the string. Defaults to space.
3981
+ * @param options[1] - The string to join the parts back together. Defaults to space.
3982
+ * @returns The lowercase version of the input string, with the replacements, if provided.
3983
+ */
3984
+ function toLowerCase(str, [delimiter, joiner]) {
3985
+ return str.toLowerCase().replaceAll(delimiter || " ", joiner || " ");
3986
+ }
3987
+ //#endregion
3974
3988
  //#region src/components/chevron-up-down-anime.tsx
3975
3989
  function ChevronUpDownAnime({ className, isUp = false }) {
3976
3990
  const firstLoadRef = useRef(true);
@@ -6347,7 +6361,7 @@ function ModalTitle({ as, ref, ...props }) {
6347
6361
  ref
6348
6362
  });
6349
6363
  }
6350
- function ModalDialog(props) {
6364
+ function ModalDialog({ dialogPanelProps: { className: dialogPanelClassName, style: dialogPanelStyle, ...dialogPanelProps } = {}, modalScrollContainerProps: { className: modalScrollContainerClassName, ...modalScrollContainerProps } = {}, ...props }) {
6351
6365
  const [modalControls, setModalControls] = useModalControls((store) => store), isMobileDevice = useMobileDevice();
6352
6366
  const { className, closeModal, dialogPanelRef, isOpen, place, pseudoContainerRef, readyToClose } = modalControls || {};
6353
6367
  const [dialogPanelEl, setDialogPanelEl] = useState(null);
@@ -6410,7 +6424,6 @@ function ModalDialog(props) {
6410
6424
  pseudoContainer.style.width = `${width}px`;
6411
6425
  pseudoContainer.style.height = `100dvh`;
6412
6426
  pseudoContainer.style.zIndex = "-1";
6413
- pseudoContainer.style.border = "2px solid blue";
6414
6427
  document.body.appendChild(pseudoContainer);
6415
6428
  animate(dialogPanel, {
6416
6429
  ...isMobileDevice ? {
@@ -6478,8 +6491,12 @@ function ModalDialog(props) {
6478
6491
  })
6479
6492
  }), /* @__PURE__ */ jsxs(DialogPanel, {
6480
6493
  ref: setDialogPanelRef,
6481
- className: twMerge("fixed left-1/2 w-screen -translate-x-1/2 bg-neutral-50 px-4 shadow-[0_-15px_50px_-12px] shadow-neutral-950/25 ease-exponential sm:w-[calc(100vw-2rem)] sm:max-w-fit sm:px-6 sm:shadow-2xl lg:px-8 dark:bg-neutral-900", place === "center" ? "top-1/2 -translate-y-1/2 rounded-2xl" : "bottom-0 h-fit max-h-[calc(100dvh-4rem)] translate-y-0 rounded-ss-4xl rounded-se-4xl after:absolute after:inset-x-0 after:-bottom-64 after:h-64 after:bg-inherit sm:top-1/2 sm:bottom-auto sm:-translate-y-1/2 sm:rounded-ee-4xl sm:rounded-es-4xl sm:after:hidden pointer-fine:top-1/2 pointer-fine:bottom-auto pointer-fine:-translate-y-1/2 pointer-fine:rounded-3xl", className),
6482
- style: isMobileDevice ? void 0 : { opacity: 0 },
6494
+ ...dialogPanelProps,
6495
+ className: twMerge("fixed left-1/2 w-screen -translate-x-1/2 bg-neutral-50 shadow-[0_-15px_50px_-12px] shadow-neutral-950/25 ease-exponential sm:w-[calc(100vw-2rem)] sm:max-w-fit sm:shadow-2xl dark:bg-neutral-900", place === "center" ? "top-1/2 -translate-y-1/2 rounded-2xl" : "bottom-0 h-fit max-h-[calc(100dvh-4rem)] translate-y-0 rounded-ss-4xl rounded-se-4xl after:absolute after:inset-x-0 after:-bottom-64 after:h-64 after:bg-inherit sm:top-1/2 sm:bottom-auto sm:-translate-y-1/2 sm:rounded-ee-4xl sm:rounded-es-4xl sm:after:hidden pointer-fine:top-1/2 pointer-fine:bottom-auto pointer-fine:-translate-y-1/2 pointer-fine:rounded-3xl", dialogPanelClassName),
6496
+ style: {
6497
+ ...dialogPanelStyle,
6498
+ ...isMobileDevice ? {} : { opacity: 0 }
6499
+ },
6483
6500
  children: [/* @__PURE__ */ jsx("button", {
6484
6501
  className: "absolute inset-x-0 top-0 z-10 flex h-6 cursor-grab items-center justify-center after:h-1 after:w-8 after:rounded-full after:bg-neutral-500/50 after:transition-[scale,background-color] after:duration-500 after:ease-exponential active:cursor-grabbing active:after:scale-x-150 active:after:scale-y-125 active:after:bg-neutral-500 data-ready:after:scale-x-200 data-ready:after:scale-y-200 data-ready:after:bg-(--base-theme-color) pointer-fine:hover:after:scale-x-125 pointer-fine:hover:after:bg-neutral-500/75 pointer-fine:active:after:scale-x-150 pointer-fine:active:after:bg-neutral-500 data-ready:pointer-fine:hover:after:scale-x-200 data-ready:pointer-fine:hover:after:scale-y-200 data-ready:pointer-fine:hover:after:bg-(--base-theme-color) data-ready:pointer-fine:active:after:scale-x-200 data-ready:pointer-fine:active:after:scale-y-200 data-ready:pointer-fine:active:after:bg-(--base-theme-color)",
6485
6502
  ...readyToClose ? { "data-ready": "" } : {},
@@ -6490,10 +6507,11 @@ function ModalDialog(props) {
6490
6507
  children: "Drag down to close"
6491
6508
  })
6492
6509
  }), /* @__PURE__ */ jsx("div", {
6493
- className: "overflow-y-scroll",
6510
+ ...modalScrollContainerProps,
6511
+ className: twMerge("h-fit max-h-[calc(100dvh-4rem)] overflow-y-scroll px-4 sm:px-6 lg:px-8", modalScrollContainerClassName),
6494
6512
  children: /* @__PURE__ */ jsx("div", {
6495
6513
  ...props,
6496
- className: "py-4 sm:py-6 lg:py-8"
6514
+ className: twMerge("h-full py-3 sm:py-5 lg:py-7", className)
6497
6515
  })
6498
6516
  })]
6499
6517
  })]
@@ -6758,6 +6776,197 @@ function Select({ buttonProps, children, className, description, descriptionProp
6758
6776
  });
6759
6777
  }
6760
6778
  //#endregion
6779
+ //#region src/symbols/plus.tsx
6780
+ function Plus({ weight = "regular", ...props }) {
6781
+ switch (weight) {
6782
+ case "ultralight": return /* @__PURE__ */ jsx("svg", {
6783
+ viewBox: "9.76562 -65.2349 59.96 59.96",
6784
+ ...props,
6785
+ children: /* @__PURE__ */ jsx("path", { d: "M40.8828-6.4126L40.8828-64.0952C40.8828-64.7417 40.3511-65.2349 39.7466-65.2349C39.1421-65.2349 38.6069-64.7417 38.6069-64.0952L38.6069-6.4126C38.6069-5.76611 39.1421-5.27293 39.7466-5.27293C40.3511-5.27293 40.8828-5.76611 40.8828-6.4126ZM10.9053-34.1142L68.5879-34.1142C69.2344-34.1142 69.7242-34.6494 69.7242-35.2539C69.7242-35.8584 69.2344-36.3936 68.5879-36.3936L10.9053-36.3936C10.2554-36.3936 9.76562-35.8584 9.76562-35.2539C9.76562-34.6494 10.2554-34.1142 10.9053-34.1142Z" })
6786
+ });
6787
+ case "thin": return /* @__PURE__ */ jsx("svg", {
6788
+ viewBox: "9.76562 -65.6758 60.83 60.84",
6789
+ ...props,
6790
+ children: /* @__PURE__ */ jsx("path", { d: "M41.9492-6.60743L41.9492-63.9004C41.9492-64.875 41.1406-65.6758 40.1875-65.6758C39.2344-65.6758 38.4121-64.875 38.4121-63.9004L38.4121-6.60743C38.4121-5.63281 39.2344-4.83202 40.1875-4.83202C41.1406-4.83202 41.9492-5.63281 41.9492-6.60743ZM11.541-33.4785L68.834-33.4785C69.8086-33.4785 70.5957-34.3008 70.5957-35.2539C70.5957-36.207 69.8086-37.0293 68.834-37.0293L11.541-37.0293C10.5527-37.0293 9.76562-36.207 9.76562-35.2539C9.76562-34.3008 10.5527-33.4785 11.541-33.4785Z" })
6791
+ });
6792
+ case "light": return /* @__PURE__ */ jsx("svg", {
6793
+ viewBox: "9.76562 -66.5366 62.53 62.57",
6794
+ ...props,
6795
+ children: /* @__PURE__ */ jsx("path", { d: "M44.0313-6.9878L44.0313-63.52C44.0313-65.1353 42.6821-66.5366 41.0483-66.5366C39.4146-66.5366 38.0317-65.1353 38.0317-63.52L38.0317-6.9878C38.0317-5.37256 39.4146-3.97119 41.0483-3.97119C42.6821-3.97119 44.0313-5.37256 44.0313-6.9878ZM12.7822-32.2373L69.3145-32.2373C70.9297-32.2373 72.2974-33.6201 72.2974-35.2539C72.2974-36.8877 70.9297-38.2705 69.3145-38.2705L12.7822-38.2705C11.1333-38.2705 9.76562-36.8877 9.76562-35.2539C9.76562-33.6201 11.1333-32.2373 12.7822-32.2373Z" })
6796
+ });
6797
+ case "regular": return /* @__PURE__ */ jsx("svg", {
6798
+ viewBox: "9.76562 -67.1875 63.82 63.87",
6799
+ ...props,
6800
+ children: /* @__PURE__ */ jsx("path", { d: "M45.6055-7.27539L45.6055-63.2324C45.6055-65.332 43.8477-67.1875 41.6992-67.1875C39.5508-67.1875 37.7441-65.332 37.7441-63.2324L37.7441-7.27539C37.7441-5.17578 39.5508-3.32031 41.6992-3.32031C43.8477-3.32031 45.6055-5.17578 45.6055-7.27539ZM13.7207-31.2988L69.6777-31.2988C71.7773-31.2988 73.584-33.1055 73.584-35.2539C73.584-37.4023 71.7773-39.209 69.6777-39.209L13.7207-39.209C11.5723-39.209 9.76562-37.4023 9.76562-35.2539C9.76562-33.1055 11.5723-31.2988 13.7207-31.2988Z" })
6801
+ });
6802
+ case "medium": return /* @__PURE__ */ jsx("svg", {
6803
+ viewBox: "9.76562 -67.6006 64.67 64.71",
6804
+ ...props,
6805
+ children: /* @__PURE__ */ jsx("path", { d: "M46.8623-7.6709L46.8623-62.8193C46.8623-65.3936 44.7354-67.6006 42.1211-67.6006C39.5068-67.6006 37.3398-65.3936 37.3398-62.8193L37.3398-7.6709C37.3398-5.09668 39.5068-2.88965 42.1211-2.88965C44.7354-2.88965 46.8623-5.09668 46.8623-7.6709ZM14.5469-30.4639L69.6953-30.4639C72.2695-30.4639 74.4365-32.6309 74.4365-35.2451C74.4365-37.8594 72.2695-40.0264 69.6953-40.0264L14.5469-40.0264C11.9326-40.0264 9.76562-37.8594 9.76562-35.2451C9.76562-32.6309 11.9326-30.4639 14.5469-30.4639Z" })
6806
+ });
6807
+ case "semibold": return /* @__PURE__ */ jsx("svg", {
6808
+ viewBox: "9.76562 -67.9173 65.32 65.36",
6809
+ ...props,
6810
+ children: /* @__PURE__ */ jsx("path", { d: "M47.8259-7.97412L47.8259-62.5026C47.8259-65.4407 45.4159-67.9173 42.4445-67.9173C39.4731-67.9173 37.0299-65.4407 37.0299-62.5026L37.0299-7.97412C37.0299-5.03604 39.4731-2.55947 42.4445-2.55947C45.4159-2.55947 47.8259-5.03604 47.8259-7.97412ZM15.1803-29.8237L69.7088-29.8237C72.6469-29.8237 75.0901-32.267 75.0901-35.2384C75.0901-38.2098 72.6469-40.653 69.7088-40.653L15.1803-40.653C12.2089-40.653 9.76562-38.2098 9.76562-35.2384C9.76562-32.267 12.2089-29.8237 15.1803-29.8237Z" })
6811
+ });
6812
+ case "bold": return /* @__PURE__ */ jsx("svg", {
6813
+ viewBox: "9.76562 -68.335 66.19 66.21",
6814
+ ...props,
6815
+ children: /* @__PURE__ */ jsx("path", { d: "M49.0967-8.37402L49.0967-62.085C49.0967-65.5029 46.3135-68.335 42.8711-68.335C39.4287-68.335 36.6211-65.5029 36.6211-62.085L36.6211-8.37402C36.6211-4.95605 39.4287-2.12402 42.8711-2.12402C46.3135-2.12402 49.0967-4.95605 49.0967-8.37402ZM16.0156-28.9795L69.7266-28.9795C73.1445-28.9795 75.9521-31.7871 75.9521-35.2295C75.9521-38.6719 73.1445-41.4795 69.7266-41.4795L16.0156-41.4795C12.5732-41.4795 9.76562-38.6719 9.76562-35.2295C9.76562-31.7871 12.5732-28.9795 16.0156-28.9795Z" })
6816
+ });
6817
+ case "heavy": return /* @__PURE__ */ jsx("svg", {
6818
+ viewBox: "9.76562 -68.9408 67.44 67.45",
6819
+ ...props,
6820
+ children: /* @__PURE__ */ jsx("path", { d: "M50.9399-8.95406L50.9399-61.4791C50.9399-65.5932 47.6153-68.9408 43.4898-68.9408C39.3643-68.9408 36.0282-65.5932 36.0282-61.4791L36.0282-8.95406C36.0282-4.84005 39.3643-1.49243 43.4898-1.49243C47.6153-1.49243 50.9399-4.84005 50.9399-8.95406ZM17.2272-27.755L69.7523-27.755C73.8663-27.755 77.2024-31.0911 77.2024-35.2166C77.2024-39.3421 73.8663-42.6782 69.7523-42.6782L17.2272-42.6782C13.1017-42.6782 9.76562-39.3421 9.76562-35.2166C9.76562-31.0911 13.1017-27.755 17.2272-27.755Z" })
6821
+ });
6822
+ case "black": return /* @__PURE__ */ jsx("svg", {
6823
+ viewBox: "9.76562 -69.4824 68.55 68.55",
6824
+ ...props,
6825
+ children: /* @__PURE__ */ jsx("path", { d: "M52.5879-9.47266L52.5879-60.9375C52.5879-65.6738 48.7793-69.4824 44.043-69.4824C39.3066-69.4824 35.498-65.6738 35.498-60.9375L35.498-9.47266C35.498-4.73633 39.3066-0.927734 44.043-0.927734C48.7793-0.927734 52.5879-4.73633 52.5879-9.47266ZM18.3105-26.6602L69.7754-26.6602C74.5117-26.6602 78.3203-30.4688 78.3203-35.2051C78.3203-39.9414 74.5117-43.75 69.7754-43.75L18.3105-43.75C13.5742-43.75 9.76562-39.9414 9.76562-35.2051C9.76562-30.4688 13.5742-26.6602 18.3105-26.6602Z" })
6826
+ });
6827
+ }
6828
+ }
6829
+ //#endregion
6830
+ //#region src/components/search.tsx
6831
+ /**
6832
+ * ## SearchOption
6833
+ *
6834
+ * @prop children - This is what is displayed in the drop down menu
6835
+ * @prop name - This is used for filtering by default
6836
+ * @prop value - This is used as selected value and for FormData
6837
+ */
6838
+ function SearchOption({ children, className, name, value, ...props }) {
6839
+ return /* @__PURE__ */ jsx(ComboboxOption, {
6840
+ className: "group/option contents",
6841
+ value: {
6842
+ id: value,
6843
+ name
6844
+ },
6845
+ ...props,
6846
+ children: (bag) => /* @__PURE__ */ jsxs("div", {
6847
+ className: twMerge("flex cursor-pointer items-center gap-2 rounded-lg px-2 py-1 transition-[background-color] duration-200 ease-exponential select-none [--theme-color:var(--base-theme-color)] corner-super-1.5 group-disabled/option:opacity-50 group-data-focus/option:bg-(--theme-color)/15 group-data-selected/option:cursor-default group-data-selected/option:text-(--theme-color) group-data-focus/option:group-data-selected/option:bg-transparent dark:group-data-focus/option:bg-(--theme-color)/15", className),
6848
+ children: [/* @__PURE__ */ jsx(Checkmark, { className: "invisible size-3.5 group-data-selected/option:visible" }), typeof children === "function" ? children(bag) : children ?? name]
6849
+ })
6850
+ });
6851
+ }
6852
+ /**
6853
+ * # Search
6854
+ *
6855
+ * A searchable select component built on top of Headless UI's `Combobox`.
6856
+ *
6857
+ * Use the `SearchOption` component to define options.
6858
+ */
6859
+ function Search({ allowCustom, buttonProps, children, className, defaultValue, description, descriptionProps: { className: descriptionClassName, ...descriptionProps } = {}, fieldProps: { className: fieldClassName, ...fieldProps } = {}, inputProps, invalid, label, labelProps: { className: labelClassName, ...labelProps } = {}, multiple, onChange, optionsProps: { anchor, className: optionsClassName, transition, ...optionsProps } = {}, placeholder, required = true, ...props }) {
6860
+ const uniqueId = useId();
6861
+ const options = Children.toArray(children).flatMap((child) => {
6862
+ if (!isValidElement(child)) return [];
6863
+ const candidate = child;
6864
+ if (typeof candidate.props?.name !== "string") return [];
6865
+ if (typeof candidate.props?.value !== "string") return [];
6866
+ return [{
6867
+ name: candidate.props.name,
6868
+ value: candidate.props.value,
6869
+ element: child
6870
+ }];
6871
+ });
6872
+ const [query, setQuery] = useState("");
6873
+ const [isInvalid, setIsInvalid] = useState(invalid);
6874
+ const [selectedOptionSync, setSelectedOptionSync] = useState(() => {
6875
+ if (multiple) return Array.isArray(defaultValue) ? defaultValue : [];
6876
+ return typeof defaultValue === "string" ? defaultValue : null;
6877
+ });
6878
+ const comboboxInputRef = useRef(null);
6879
+ const filteredOptions = query.trim() === "" ? options : options.filter((option) => option.name.toLowerCase().includes(query.toLowerCase()));
6880
+ const handleChange = (selected) => {
6881
+ setIsInvalid(false);
6882
+ setSelectedOptionSync(selected);
6883
+ onChange?.(selected);
6884
+ };
6885
+ const handleInvalid = () => setIsInvalid(true);
6886
+ const refocus = () => comboboxInputRef.current?.focus();
6887
+ return /* @__PURE__ */ jsxs(Field, {
6888
+ ...fieldProps,
6889
+ className: (bag) => twMerge("grid gap-1", typeof fieldClassName === "function" ? fieldClassName(bag) : fieldClassName),
6890
+ children: [
6891
+ label && /* @__PURE__ */ jsx(Label, {
6892
+ ...labelProps,
6893
+ className: (bag) => twMerge("text-sm font-medium", required ? `after:text-red-700 after:content-['_*']` : "", typeof labelClassName === "function" ? labelClassName(bag) : labelClassName),
6894
+ children: label
6895
+ }),
6896
+ /* @__PURE__ */ jsxs(Combobox, {
6897
+ ...props,
6898
+ invalid: isInvalid || invalid,
6899
+ multiple,
6900
+ onChange: handleChange,
6901
+ onClose: () => setQuery(""),
6902
+ value: selectedOptionSync || "",
6903
+ children: [/* @__PURE__ */ jsxs("div", {
6904
+ className: "relative",
6905
+ children: [
6906
+ /* @__PURE__ */ jsx(ComboboxInput, {
6907
+ ...inputProps,
6908
+ "aria-label": typeof label === "string" ? label : props.name,
6909
+ className: (bag) => twMerge("inline-block w-full overflow-clip rounded-xl border border-neutral-500/50 bg-neutral-100 py-1 pr-8 pl-2 text-left text-neutral-950 outline-offset-1 outline-blue-400/95 transition-[background-color] duration-300 ease-exponential corner-super-1.5 dark:bg-neutral-700 dark:text-neutral-50", "focus:outline-3 focus-visible:bg-neutral-50 focus-visible:outline-3 active:bg-neutral-200 dark:focus-visible:bg-neutral-600 dark:active:bg-neutral-800 pointer-fine:hover:bg-neutral-50 pointer-fine:active:bg-neutral-200 dark:pointer-fine:hover:bg-neutral-600 dark:pointer-fine:active:bg-neutral-800", "data-invalid:border-red-500 data-invalid:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-100)_5%)] data-invalid:focus-visible:bg-[color-mix(in_oklch,var(--color-red-500)_1%,var(--color-neutral-100))] data-invalid:active:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-100))] dark:data-invalid:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-800)_5%)] dark:data-invalid:focus-visible:bg-[color-mix(in_oklch,var(--color-red-500)_1%,var(--color-neutral-800))] dark:data-invalid:active:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-800)_5%)] data-invalid:pointer-fine:hover:bg-[color-mix(in_oklch,var(--color-red-500)_10%,var(--color-neutral-500)_5%)] data-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklch,var(--color-red-500)_1%,var(--color-neutral-100))] data-invalid:pointer-fine:active:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-100))] dark:data-invalid:pointer-fine:hover:bg-[color-mix(in_oklch,var(--color-red-500)_10%,var(--color-neutral-800)_5%)] dark:data-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklch,var(--color-red-500)_1%,var(--color-neutral-800))] dark:data-invalid:pointer-fine:active:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-800)_5%)]", typeof className === "function" ? className(bag) : className),
6910
+ displayValue: (value) => Array.isArray(value) ? value.map((v) => v.name).join(", ") : value?.name ?? "",
6911
+ name: props.name,
6912
+ onChange: (event) => setQuery(event.target.value),
6913
+ placeholder: placeholder || (multiple ? "Choose Any" : "Choose One"),
6914
+ ref: comboboxInputRef,
6915
+ required
6916
+ }),
6917
+ /* @__PURE__ */ jsx("input", {
6918
+ "aria-hidden": "true",
6919
+ className: "sr-only top-0 left-1/2",
6920
+ id: props.name + ":input:id" + uniqueId,
6921
+ name: props.name,
6922
+ onChange: () => {},
6923
+ onFocus: refocus,
6924
+ onInvalid: handleInvalid,
6925
+ required,
6926
+ tabIndex: -1,
6927
+ value: Array.isArray(selectedOptionSync) ? selectedOptionSync.join(", ") : selectedOptionSync ?? ""
6928
+ }),
6929
+ /* @__PURE__ */ jsx(ComboboxButton, {
6930
+ ...buttonProps,
6931
+ className: "absolute top-1/2 right-1.5 -translate-y-1/2 rounded p-0.5",
6932
+ children: /* @__PURE__ */ jsx(ChevronUpChevronDown, { className: "size-3 fill-current/50" })
6933
+ })
6934
+ ]
6935
+ }), /* @__PURE__ */ jsxs(ComboboxOptions, {
6936
+ ...optionsProps,
6937
+ anchor: anchor || "bottom start",
6938
+ className: (bag) => twMerge("z-50 w-(--input-width) origin-top rounded-xl border border-neutral-500/50 bg-neutral-50/95 p-1 backdrop-blur-sm backdrop-brightness-110 transition-[opacity,scale,translate] duration-300 ease-exponential [--anchor-gap:--spacing(1)] corner-super-1.5 empty:invisible focus:outline-none data-closed:-translate-y-0.5 data-closed:scale-y-0 data-closed:opacity-0 data-[anchor*=top]:origin-bottom dark:bg-neutral-800/95", typeof optionsClassName === "function" ? optionsClassName(bag) : optionsClassName),
6939
+ transition: transition ?? true,
6940
+ children: [allowCustom && query.length > 0 && /* @__PURE__ */ jsx(ComboboxOption, {
6941
+ value: {
6942
+ id: props.customOptionParams?.formatID?.(query) ?? toLowerCase(query, [" ", "_"]),
6943
+ name: query
6944
+ },
6945
+ className: "group/option contents",
6946
+ children: ({ selected }) => /* @__PURE__ */ jsx("div", {
6947
+ className: "flex cursor-pointer items-center gap-2 rounded-lg px-2 py-1 transition-[background-color] duration-200 ease-exponential select-none [--theme-color:var(--base-theme-color)] corner-super-1.5 group-disabled/option:opacity-50 group-data-focus/option:bg-(--theme-color)/15 group-data-selected/option:cursor-default group-data-selected/option:text-(--theme-color) group-data-focus/option:group-data-selected/option:bg-transparent dark:group-data-focus/option:bg-(--theme-color)/15",
6948
+ children: selected ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Checkmark, { className: "size-3.5" }), query] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
6949
+ /* @__PURE__ */ jsx(Plus, { className: "size-3.5" }),
6950
+ "Use ",
6951
+ /* @__PURE__ */ jsxs("b", { children: [
6952
+ "\"",
6953
+ query,
6954
+ "\""
6955
+ ] })
6956
+ ] })
6957
+ })
6958
+ }), filteredOptions.map((option) => option.element)]
6959
+ })]
6960
+ }),
6961
+ description && /* @__PURE__ */ jsx(Description, {
6962
+ ...descriptionProps,
6963
+ className: (bag) => twMerge("text-xs text-current/60", typeof descriptionClassName === "function" ? descriptionClassName(bag) : descriptionClassName),
6964
+ children: description
6965
+ })
6966
+ ]
6967
+ });
6968
+ }
6969
+ //#endregion
6761
6970
  //#region src/symbols/circle.fill.tsx
6762
6971
  function CircleFill({ weight = "regular", ...props }) {
6763
6972
  switch (weight) {
@@ -8838,4 +9047,4 @@ function ArrowSvg({ className, ...props }) {
8838
9047
  });
8839
9048
  }
8840
9049
  //#endregion
8841
- export { Anchor, Button, Checkbox, Details, DetailsBody, DetailsSummary, DropDown, DropDownButton, DropDownItem, DropDownItems, DropDownSection, DropDownSeparator, Fieldset, Form, Ghost, Heading, HumanVerification, IFrame, Input, Link, Modal, ModalClose, ModalDialog, ModalTitle, ModalTrigger, Select, SelectOption, SelectSectionTitle, SubmitButton, Textarea, Time, Tooltip, TooltipPanel, TooltipTrigger, generateHumanValidationToken, getLinkClasses, validateHuman };
9050
+ export { Anchor, Button, Checkbox, Details, DetailsBody, DetailsSummary, DropDown, DropDownButton, DropDownItem, DropDownItems, DropDownSection, DropDownSeparator, Fieldset, Form, Ghost, Heading, HumanVerification, IFrame, Input, Link, Modal, ModalClose, ModalDialog, ModalTitle, ModalTrigger, Search, SearchOption, Select, SelectOption, SelectSectionTitle, SubmitButton, Textarea, Time, Tooltip, TooltipPanel, TooltipTrigger, generateHumanValidationToken, getLinkClasses, validateHuman };
package/dist/client.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { extendTailwindMerge, twJoin } from "tailwind-merge";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
- import { Button as Button$1, Checkbox as Checkbox$1, Description, Dialog, DialogBackdrop, DialogPanel, DialogTitle, Disclosure, DisclosureButton, DisclosurePanel, Field, Fieldset as Fieldset$1, Input as Input$1, Label, Legend, Listbox, ListboxButton, ListboxOption, ListboxOptions, ListboxSelectedOption, Menu, MenuButton, MenuHeading, MenuItem, MenuItems, MenuSection, MenuSeparator, Textarea as Textarea$1 } from "@headlessui/react";
4
+ import { Button as Button$1, Checkbox as Checkbox$1, Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions, Description, Dialog, DialogBackdrop, DialogPanel, DialogTitle, Disclosure, DisclosureButton, DisclosurePanel, Field, Fieldset as Fieldset$1, Input as Input$1, Label, Legend, Listbox, ListboxButton, ListboxOption, ListboxOptions, ListboxSelectedOption, Menu, MenuButton, MenuHeading, MenuItem, MenuItems, MenuSection, MenuSeparator, Textarea as Textarea$1 } from "@headlessui/react";
5
5
  import * as React from "react";
6
6
  import { Children, Suspense, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useEffectEvent, useId, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
7
7
  import * as ReactDOM from "react-dom";
@@ -6995,7 +6995,7 @@ function ModalTitle({ as, ref, ...props }) {
6995
6995
  ref
6996
6996
  });
6997
6997
  }
6998
- function ModalDialog(props) {
6998
+ function ModalDialog({ dialogPanelProps: { className: dialogPanelClassName, style: dialogPanelStyle, ...dialogPanelProps } = {}, modalScrollContainerProps: { className: modalScrollContainerClassName, ...modalScrollContainerProps } = {}, ...props }) {
6999
6999
  const [modalControls, setModalControls] = useModalControls((store) => store), isMobileDevice = useMobileDevice();
7000
7000
  const { className, closeModal, dialogPanelRef, isOpen, place, pseudoContainerRef, readyToClose } = modalControls || {};
7001
7001
  const [dialogPanelEl, setDialogPanelEl] = useState(null);
@@ -7058,7 +7058,6 @@ function ModalDialog(props) {
7058
7058
  pseudoContainer.style.width = `${width}px`;
7059
7059
  pseudoContainer.style.height = `100dvh`;
7060
7060
  pseudoContainer.style.zIndex = "-1";
7061
- pseudoContainer.style.border = "2px solid blue";
7062
7061
  document.body.appendChild(pseudoContainer);
7063
7062
  animate(dialogPanel, {
7064
7063
  ...isMobileDevice ? {
@@ -7126,8 +7125,12 @@ function ModalDialog(props) {
7126
7125
  })
7127
7126
  }), /* @__PURE__ */ jsxs(DialogPanel, {
7128
7127
  ref: setDialogPanelRef,
7129
- className: twMerge("fixed left-1/2 w-screen -translate-x-1/2 bg-neutral-50 px-4 shadow-[0_-15px_50px_-12px] shadow-neutral-950/25 ease-exponential sm:w-[calc(100vw-2rem)] sm:max-w-fit sm:px-6 sm:shadow-2xl lg:px-8 dark:bg-neutral-900", place === "center" ? "top-1/2 -translate-y-1/2 rounded-2xl" : "bottom-0 h-fit max-h-[calc(100dvh-4rem)] translate-y-0 rounded-ss-4xl rounded-se-4xl after:absolute after:inset-x-0 after:-bottom-64 after:h-64 after:bg-inherit sm:top-1/2 sm:bottom-auto sm:-translate-y-1/2 sm:rounded-ee-4xl sm:rounded-es-4xl sm:after:hidden pointer-fine:top-1/2 pointer-fine:bottom-auto pointer-fine:-translate-y-1/2 pointer-fine:rounded-3xl", className),
7130
- style: isMobileDevice ? void 0 : { opacity: 0 },
7128
+ ...dialogPanelProps,
7129
+ className: twMerge("fixed left-1/2 w-screen -translate-x-1/2 bg-neutral-50 shadow-[0_-15px_50px_-12px] shadow-neutral-950/25 ease-exponential sm:w-[calc(100vw-2rem)] sm:max-w-fit sm:shadow-2xl dark:bg-neutral-900", place === "center" ? "top-1/2 -translate-y-1/2 rounded-2xl" : "bottom-0 h-fit max-h-[calc(100dvh-4rem)] translate-y-0 rounded-ss-4xl rounded-se-4xl after:absolute after:inset-x-0 after:-bottom-64 after:h-64 after:bg-inherit sm:top-1/2 sm:bottom-auto sm:-translate-y-1/2 sm:rounded-ee-4xl sm:rounded-es-4xl sm:after:hidden pointer-fine:top-1/2 pointer-fine:bottom-auto pointer-fine:-translate-y-1/2 pointer-fine:rounded-3xl", dialogPanelClassName),
7130
+ style: {
7131
+ ...dialogPanelStyle,
7132
+ ...isMobileDevice ? {} : { opacity: 0 }
7133
+ },
7131
7134
  children: [/* @__PURE__ */ jsx("button", {
7132
7135
  className: "absolute inset-x-0 top-0 z-10 flex h-6 cursor-grab items-center justify-center after:h-1 after:w-8 after:rounded-full after:bg-neutral-500/50 after:transition-[scale,background-color] after:duration-500 after:ease-exponential active:cursor-grabbing active:after:scale-x-150 active:after:scale-y-125 active:after:bg-neutral-500 data-ready:after:scale-x-200 data-ready:after:scale-y-200 data-ready:after:bg-(--base-theme-color) pointer-fine:hover:after:scale-x-125 pointer-fine:hover:after:bg-neutral-500/75 pointer-fine:active:after:scale-x-150 pointer-fine:active:after:bg-neutral-500 data-ready:pointer-fine:hover:after:scale-x-200 data-ready:pointer-fine:hover:after:scale-y-200 data-ready:pointer-fine:hover:after:bg-(--base-theme-color) data-ready:pointer-fine:active:after:scale-x-200 data-ready:pointer-fine:active:after:scale-y-200 data-ready:pointer-fine:active:after:bg-(--base-theme-color)",
7133
7136
  ...readyToClose ? { "data-ready": "" } : {},
@@ -7138,10 +7141,11 @@ function ModalDialog(props) {
7138
7141
  children: "Drag down to close"
7139
7142
  })
7140
7143
  }), /* @__PURE__ */ jsx("div", {
7141
- className: "overflow-y-scroll",
7144
+ ...modalScrollContainerProps,
7145
+ className: twMerge("h-fit max-h-[calc(100dvh-4rem)] overflow-y-scroll px-4 sm:px-6 lg:px-8", modalScrollContainerClassName),
7142
7146
  children: /* @__PURE__ */ jsx("div", {
7143
7147
  ...props,
7144
- className: "py-4 sm:py-6 lg:py-8"
7148
+ className: twMerge("h-full py-3 sm:py-5 lg:py-7", className)
7145
7149
  })
7146
7150
  })]
7147
7151
  })]
@@ -7406,6 +7410,197 @@ function Select({ buttonProps, children, className, description, descriptionProp
7406
7410
  });
7407
7411
  }
7408
7412
  //#endregion
7413
+ //#region src/symbols/plus.tsx
7414
+ function Plus({ weight = "regular", ...props }) {
7415
+ switch (weight) {
7416
+ case "ultralight": return /* @__PURE__ */ jsx("svg", {
7417
+ viewBox: "9.76562 -65.2349 59.96 59.96",
7418
+ ...props,
7419
+ children: /* @__PURE__ */ jsx("path", { d: "M40.8828-6.4126L40.8828-64.0952C40.8828-64.7417 40.3511-65.2349 39.7466-65.2349C39.1421-65.2349 38.6069-64.7417 38.6069-64.0952L38.6069-6.4126C38.6069-5.76611 39.1421-5.27293 39.7466-5.27293C40.3511-5.27293 40.8828-5.76611 40.8828-6.4126ZM10.9053-34.1142L68.5879-34.1142C69.2344-34.1142 69.7242-34.6494 69.7242-35.2539C69.7242-35.8584 69.2344-36.3936 68.5879-36.3936L10.9053-36.3936C10.2554-36.3936 9.76562-35.8584 9.76562-35.2539C9.76562-34.6494 10.2554-34.1142 10.9053-34.1142Z" })
7420
+ });
7421
+ case "thin": return /* @__PURE__ */ jsx("svg", {
7422
+ viewBox: "9.76562 -65.6758 60.83 60.84",
7423
+ ...props,
7424
+ children: /* @__PURE__ */ jsx("path", { d: "M41.9492-6.60743L41.9492-63.9004C41.9492-64.875 41.1406-65.6758 40.1875-65.6758C39.2344-65.6758 38.4121-64.875 38.4121-63.9004L38.4121-6.60743C38.4121-5.63281 39.2344-4.83202 40.1875-4.83202C41.1406-4.83202 41.9492-5.63281 41.9492-6.60743ZM11.541-33.4785L68.834-33.4785C69.8086-33.4785 70.5957-34.3008 70.5957-35.2539C70.5957-36.207 69.8086-37.0293 68.834-37.0293L11.541-37.0293C10.5527-37.0293 9.76562-36.207 9.76562-35.2539C9.76562-34.3008 10.5527-33.4785 11.541-33.4785Z" })
7425
+ });
7426
+ case "light": return /* @__PURE__ */ jsx("svg", {
7427
+ viewBox: "9.76562 -66.5366 62.53 62.57",
7428
+ ...props,
7429
+ children: /* @__PURE__ */ jsx("path", { d: "M44.0313-6.9878L44.0313-63.52C44.0313-65.1353 42.6821-66.5366 41.0483-66.5366C39.4146-66.5366 38.0317-65.1353 38.0317-63.52L38.0317-6.9878C38.0317-5.37256 39.4146-3.97119 41.0483-3.97119C42.6821-3.97119 44.0313-5.37256 44.0313-6.9878ZM12.7822-32.2373L69.3145-32.2373C70.9297-32.2373 72.2974-33.6201 72.2974-35.2539C72.2974-36.8877 70.9297-38.2705 69.3145-38.2705L12.7822-38.2705C11.1333-38.2705 9.76562-36.8877 9.76562-35.2539C9.76562-33.6201 11.1333-32.2373 12.7822-32.2373Z" })
7430
+ });
7431
+ case "regular": return /* @__PURE__ */ jsx("svg", {
7432
+ viewBox: "9.76562 -67.1875 63.82 63.87",
7433
+ ...props,
7434
+ children: /* @__PURE__ */ jsx("path", { d: "M45.6055-7.27539L45.6055-63.2324C45.6055-65.332 43.8477-67.1875 41.6992-67.1875C39.5508-67.1875 37.7441-65.332 37.7441-63.2324L37.7441-7.27539C37.7441-5.17578 39.5508-3.32031 41.6992-3.32031C43.8477-3.32031 45.6055-5.17578 45.6055-7.27539ZM13.7207-31.2988L69.6777-31.2988C71.7773-31.2988 73.584-33.1055 73.584-35.2539C73.584-37.4023 71.7773-39.209 69.6777-39.209L13.7207-39.209C11.5723-39.209 9.76562-37.4023 9.76562-35.2539C9.76562-33.1055 11.5723-31.2988 13.7207-31.2988Z" })
7435
+ });
7436
+ case "medium": return /* @__PURE__ */ jsx("svg", {
7437
+ viewBox: "9.76562 -67.6006 64.67 64.71",
7438
+ ...props,
7439
+ children: /* @__PURE__ */ jsx("path", { d: "M46.8623-7.6709L46.8623-62.8193C46.8623-65.3936 44.7354-67.6006 42.1211-67.6006C39.5068-67.6006 37.3398-65.3936 37.3398-62.8193L37.3398-7.6709C37.3398-5.09668 39.5068-2.88965 42.1211-2.88965C44.7354-2.88965 46.8623-5.09668 46.8623-7.6709ZM14.5469-30.4639L69.6953-30.4639C72.2695-30.4639 74.4365-32.6309 74.4365-35.2451C74.4365-37.8594 72.2695-40.0264 69.6953-40.0264L14.5469-40.0264C11.9326-40.0264 9.76562-37.8594 9.76562-35.2451C9.76562-32.6309 11.9326-30.4639 14.5469-30.4639Z" })
7440
+ });
7441
+ case "semibold": return /* @__PURE__ */ jsx("svg", {
7442
+ viewBox: "9.76562 -67.9173 65.32 65.36",
7443
+ ...props,
7444
+ children: /* @__PURE__ */ jsx("path", { d: "M47.8259-7.97412L47.8259-62.5026C47.8259-65.4407 45.4159-67.9173 42.4445-67.9173C39.4731-67.9173 37.0299-65.4407 37.0299-62.5026L37.0299-7.97412C37.0299-5.03604 39.4731-2.55947 42.4445-2.55947C45.4159-2.55947 47.8259-5.03604 47.8259-7.97412ZM15.1803-29.8237L69.7088-29.8237C72.6469-29.8237 75.0901-32.267 75.0901-35.2384C75.0901-38.2098 72.6469-40.653 69.7088-40.653L15.1803-40.653C12.2089-40.653 9.76562-38.2098 9.76562-35.2384C9.76562-32.267 12.2089-29.8237 15.1803-29.8237Z" })
7445
+ });
7446
+ case "bold": return /* @__PURE__ */ jsx("svg", {
7447
+ viewBox: "9.76562 -68.335 66.19 66.21",
7448
+ ...props,
7449
+ children: /* @__PURE__ */ jsx("path", { d: "M49.0967-8.37402L49.0967-62.085C49.0967-65.5029 46.3135-68.335 42.8711-68.335C39.4287-68.335 36.6211-65.5029 36.6211-62.085L36.6211-8.37402C36.6211-4.95605 39.4287-2.12402 42.8711-2.12402C46.3135-2.12402 49.0967-4.95605 49.0967-8.37402ZM16.0156-28.9795L69.7266-28.9795C73.1445-28.9795 75.9521-31.7871 75.9521-35.2295C75.9521-38.6719 73.1445-41.4795 69.7266-41.4795L16.0156-41.4795C12.5732-41.4795 9.76562-38.6719 9.76562-35.2295C9.76562-31.7871 12.5732-28.9795 16.0156-28.9795Z" })
7450
+ });
7451
+ case "heavy": return /* @__PURE__ */ jsx("svg", {
7452
+ viewBox: "9.76562 -68.9408 67.44 67.45",
7453
+ ...props,
7454
+ children: /* @__PURE__ */ jsx("path", { d: "M50.9399-8.95406L50.9399-61.4791C50.9399-65.5932 47.6153-68.9408 43.4898-68.9408C39.3643-68.9408 36.0282-65.5932 36.0282-61.4791L36.0282-8.95406C36.0282-4.84005 39.3643-1.49243 43.4898-1.49243C47.6153-1.49243 50.9399-4.84005 50.9399-8.95406ZM17.2272-27.755L69.7523-27.755C73.8663-27.755 77.2024-31.0911 77.2024-35.2166C77.2024-39.3421 73.8663-42.6782 69.7523-42.6782L17.2272-42.6782C13.1017-42.6782 9.76562-39.3421 9.76562-35.2166C9.76562-31.0911 13.1017-27.755 17.2272-27.755Z" })
7455
+ });
7456
+ case "black": return /* @__PURE__ */ jsx("svg", {
7457
+ viewBox: "9.76562 -69.4824 68.55 68.55",
7458
+ ...props,
7459
+ children: /* @__PURE__ */ jsx("path", { d: "M52.5879-9.47266L52.5879-60.9375C52.5879-65.6738 48.7793-69.4824 44.043-69.4824C39.3066-69.4824 35.498-65.6738 35.498-60.9375L35.498-9.47266C35.498-4.73633 39.3066-0.927734 44.043-0.927734C48.7793-0.927734 52.5879-4.73633 52.5879-9.47266ZM18.3105-26.6602L69.7754-26.6602C74.5117-26.6602 78.3203-30.4688 78.3203-35.2051C78.3203-39.9414 74.5117-43.75 69.7754-43.75L18.3105-43.75C13.5742-43.75 9.76562-39.9414 9.76562-35.2051C9.76562-30.4688 13.5742-26.6602 18.3105-26.6602Z" })
7460
+ });
7461
+ }
7462
+ }
7463
+ //#endregion
7464
+ //#region src/components/search.tsx
7465
+ /**
7466
+ * ## SearchOption
7467
+ *
7468
+ * @prop children - This is what is displayed in the drop down menu
7469
+ * @prop name - This is used for filtering by default
7470
+ * @prop value - This is used as selected value and for FormData
7471
+ */
7472
+ function SearchOption({ children, className, name, value, ...props }) {
7473
+ return /* @__PURE__ */ jsx(ComboboxOption, {
7474
+ className: "group/option contents",
7475
+ value: {
7476
+ id: value,
7477
+ name
7478
+ },
7479
+ ...props,
7480
+ children: (bag) => /* @__PURE__ */ jsxs("div", {
7481
+ className: twMerge("flex cursor-pointer items-center gap-2 rounded-lg px-2 py-1 transition-[background-color] duration-200 ease-exponential select-none [--theme-color:var(--base-theme-color)] corner-super-1.5 group-disabled/option:opacity-50 group-data-focus/option:bg-(--theme-color)/15 group-data-selected/option:cursor-default group-data-selected/option:text-(--theme-color) group-data-focus/option:group-data-selected/option:bg-transparent dark:group-data-focus/option:bg-(--theme-color)/15", className),
7482
+ children: [/* @__PURE__ */ jsx(Checkmark, { className: "invisible size-3.5 group-data-selected/option:visible" }), typeof children === "function" ? children(bag) : children ?? name]
7483
+ })
7484
+ });
7485
+ }
7486
+ /**
7487
+ * # Search
7488
+ *
7489
+ * A searchable select component built on top of Headless UI's `Combobox`.
7490
+ *
7491
+ * Use the `SearchOption` component to define options.
7492
+ */
7493
+ function Search({ allowCustom, buttonProps, children, className, defaultValue, description, descriptionProps: { className: descriptionClassName, ...descriptionProps } = {}, fieldProps: { className: fieldClassName, ...fieldProps } = {}, inputProps, invalid, label, labelProps: { className: labelClassName, ...labelProps } = {}, multiple, onChange, optionsProps: { anchor, className: optionsClassName, transition, ...optionsProps } = {}, placeholder, required = true, ...props }) {
7494
+ const uniqueId = useId();
7495
+ const options = Children.toArray(children).flatMap((child) => {
7496
+ if (!isValidElement(child)) return [];
7497
+ const candidate = child;
7498
+ if (typeof candidate.props?.name !== "string") return [];
7499
+ if (typeof candidate.props?.value !== "string") return [];
7500
+ return [{
7501
+ name: candidate.props.name,
7502
+ value: candidate.props.value,
7503
+ element: child
7504
+ }];
7505
+ });
7506
+ const [query, setQuery] = useState("");
7507
+ const [isInvalid, setIsInvalid] = useState(invalid);
7508
+ const [selectedOptionSync, setSelectedOptionSync] = useState(() => {
7509
+ if (multiple) return Array.isArray(defaultValue) ? defaultValue : [];
7510
+ return typeof defaultValue === "string" ? defaultValue : null;
7511
+ });
7512
+ const comboboxInputRef = useRef(null);
7513
+ const filteredOptions = query.trim() === "" ? options : options.filter((option) => option.name.toLowerCase().includes(query.toLowerCase()));
7514
+ const handleChange = (selected) => {
7515
+ setIsInvalid(false);
7516
+ setSelectedOptionSync(selected);
7517
+ onChange?.(selected);
7518
+ };
7519
+ const handleInvalid = () => setIsInvalid(true);
7520
+ const refocus = () => comboboxInputRef.current?.focus();
7521
+ return /* @__PURE__ */ jsxs(Field, {
7522
+ ...fieldProps,
7523
+ className: (bag) => twMerge("grid gap-1", typeof fieldClassName === "function" ? fieldClassName(bag) : fieldClassName),
7524
+ children: [
7525
+ label && /* @__PURE__ */ jsx(Label, {
7526
+ ...labelProps,
7527
+ className: (bag) => twMerge("text-sm font-medium", required ? `after:text-red-700 after:content-['_*']` : "", typeof labelClassName === "function" ? labelClassName(bag) : labelClassName),
7528
+ children: label
7529
+ }),
7530
+ /* @__PURE__ */ jsxs(Combobox, {
7531
+ ...props,
7532
+ invalid: isInvalid || invalid,
7533
+ multiple,
7534
+ onChange: handleChange,
7535
+ onClose: () => setQuery(""),
7536
+ value: selectedOptionSync || "",
7537
+ children: [/* @__PURE__ */ jsxs("div", {
7538
+ className: "relative",
7539
+ children: [
7540
+ /* @__PURE__ */ jsx(ComboboxInput, {
7541
+ ...inputProps,
7542
+ "aria-label": typeof label === "string" ? label : props.name,
7543
+ className: (bag) => twMerge("inline-block w-full overflow-clip rounded-xl border border-neutral-500/50 bg-neutral-100 py-1 pr-8 pl-2 text-left text-neutral-950 outline-offset-1 outline-blue-400/95 transition-[background-color] duration-300 ease-exponential corner-super-1.5 dark:bg-neutral-700 dark:text-neutral-50", "focus:outline-3 focus-visible:bg-neutral-50 focus-visible:outline-3 active:bg-neutral-200 dark:focus-visible:bg-neutral-600 dark:active:bg-neutral-800 pointer-fine:hover:bg-neutral-50 pointer-fine:active:bg-neutral-200 dark:pointer-fine:hover:bg-neutral-600 dark:pointer-fine:active:bg-neutral-800", "data-invalid:border-red-500 data-invalid:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-100)_5%)] data-invalid:focus-visible:bg-[color-mix(in_oklch,var(--color-red-500)_1%,var(--color-neutral-100))] data-invalid:active:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-100))] dark:data-invalid:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-800)_5%)] dark:data-invalid:focus-visible:bg-[color-mix(in_oklch,var(--color-red-500)_1%,var(--color-neutral-800))] dark:data-invalid:active:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-800)_5%)] data-invalid:pointer-fine:hover:bg-[color-mix(in_oklch,var(--color-red-500)_10%,var(--color-neutral-500)_5%)] data-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklch,var(--color-red-500)_1%,var(--color-neutral-100))] data-invalid:pointer-fine:active:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-100))] dark:data-invalid:pointer-fine:hover:bg-[color-mix(in_oklch,var(--color-red-500)_10%,var(--color-neutral-800)_5%)] dark:data-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklch,var(--color-red-500)_1%,var(--color-neutral-800))] dark:data-invalid:pointer-fine:active:bg-[color-mix(in_oklch,var(--color-red-500)_5%,var(--color-neutral-800)_5%)]", typeof className === "function" ? className(bag) : className),
7544
+ displayValue: (value) => Array.isArray(value) ? value.map((v) => v.name).join(", ") : value?.name ?? "",
7545
+ name: props.name,
7546
+ onChange: (event) => setQuery(event.target.value),
7547
+ placeholder: placeholder || (multiple ? "Choose Any" : "Choose One"),
7548
+ ref: comboboxInputRef,
7549
+ required
7550
+ }),
7551
+ /* @__PURE__ */ jsx("input", {
7552
+ "aria-hidden": "true",
7553
+ className: "sr-only top-0 left-1/2",
7554
+ id: props.name + ":input:id" + uniqueId,
7555
+ name: props.name,
7556
+ onChange: () => {},
7557
+ onFocus: refocus,
7558
+ onInvalid: handleInvalid,
7559
+ required,
7560
+ tabIndex: -1,
7561
+ value: Array.isArray(selectedOptionSync) ? selectedOptionSync.join(", ") : selectedOptionSync ?? ""
7562
+ }),
7563
+ /* @__PURE__ */ jsx(ComboboxButton, {
7564
+ ...buttonProps,
7565
+ className: "absolute top-1/2 right-1.5 -translate-y-1/2 rounded p-0.5",
7566
+ children: /* @__PURE__ */ jsx(ChevronUpChevronDown, { className: "size-3 fill-current/50" })
7567
+ })
7568
+ ]
7569
+ }), /* @__PURE__ */ jsxs(ComboboxOptions, {
7570
+ ...optionsProps,
7571
+ anchor: anchor || "bottom start",
7572
+ className: (bag) => twMerge("z-50 w-(--input-width) origin-top rounded-xl border border-neutral-500/50 bg-neutral-50/95 p-1 backdrop-blur-sm backdrop-brightness-110 transition-[opacity,scale,translate] duration-300 ease-exponential [--anchor-gap:--spacing(1)] corner-super-1.5 empty:invisible focus:outline-none data-closed:-translate-y-0.5 data-closed:scale-y-0 data-closed:opacity-0 data-[anchor*=top]:origin-bottom dark:bg-neutral-800/95", typeof optionsClassName === "function" ? optionsClassName(bag) : optionsClassName),
7573
+ transition: transition ?? true,
7574
+ children: [allowCustom && query.length > 0 && /* @__PURE__ */ jsx(ComboboxOption, {
7575
+ value: {
7576
+ id: props.customOptionParams?.formatID?.(query) ?? toLowerCase(query, [" ", "_"]),
7577
+ name: query
7578
+ },
7579
+ className: "group/option contents",
7580
+ children: ({ selected }) => /* @__PURE__ */ jsx("div", {
7581
+ className: "flex cursor-pointer items-center gap-2 rounded-lg px-2 py-1 transition-[background-color] duration-200 ease-exponential select-none [--theme-color:var(--base-theme-color)] corner-super-1.5 group-disabled/option:opacity-50 group-data-focus/option:bg-(--theme-color)/15 group-data-selected/option:cursor-default group-data-selected/option:text-(--theme-color) group-data-focus/option:group-data-selected/option:bg-transparent dark:group-data-focus/option:bg-(--theme-color)/15",
7582
+ children: selected ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Checkmark, { className: "size-3.5" }), query] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7583
+ /* @__PURE__ */ jsx(Plus, { className: "size-3.5" }),
7584
+ "Use ",
7585
+ /* @__PURE__ */ jsxs("b", { children: [
7586
+ "\"",
7587
+ query,
7588
+ "\""
7589
+ ] })
7590
+ ] })
7591
+ })
7592
+ }), filteredOptions.map((option) => option.element)]
7593
+ })]
7594
+ }),
7595
+ description && /* @__PURE__ */ jsx(Description, {
7596
+ ...descriptionProps,
7597
+ className: (bag) => twMerge("text-xs text-current/60", typeof descriptionClassName === "function" ? descriptionClassName(bag) : descriptionClassName),
7598
+ children: description
7599
+ })
7600
+ ]
7601
+ });
7602
+ }
7603
+ //#endregion
7409
7604
  //#region src/symbols/circle.fill.tsx
7410
7605
  function CircleFill({ weight = "regular", ...props }) {
7411
7606
  switch (weight) {
@@ -9900,4 +10095,4 @@ function YouTubeLogo({ className, cutout = false, targets, ...props }) {
9900
10095
  });
9901
10096
  }
9902
10097
  //#endregion
9903
- export { Anchor, Button, Checkbox, Details, DetailsBody, DetailsSummary, DropDown, DropDownButton, DropDownItem, DropDownItems, DropDownSection, DropDownSeparator, FacebookLogo, Fieldset, Form, FormStatusProvider, Ghost, GoogleLogo, Heading, HumanVerification, IFrame, Input, InstagramLogo, Link, LinkedInLogo, Modal, ModalClose, ModalDialog, ModalTitle, ModalTrigger, Select, SelectOption, SelectSectionTitle, SubmitButton, Textarea, TikTokLogo, Time, Tooltip, TooltipPanel, TooltipTrigger, XLogo, YouTubeLogo, addClass, createFastContext, currentMonthName, currentWeekdayName, daysInMonth, easeOutExpo, emailRegex, extendMadoTailwindMerge, firstOfMonth, formatPhoneNumber, generateHumanValidationToken, getDate, getHours, getHoursIn12, getLinkClasses, getLocalTime, getMeridianFromHour, getMilliseconds, getMinutes, getMonth, getMonthIndexFromName, getMonthName, getNextMonth, getPreviousMonth, getSeconds, getTimezone, getUserReadableDate, getUserReadableDateFromTimestampz, getWeekdayName, getYearsInRange, hasClass, isEmail, isPhoneNumber, monthNamesList, removeClass, splitCamelCase, telRegex, toCamelCase, toFullDateString, toLowerCase, toTitleCase, toggleClass, twMerge, useFormStatus, useMobileDevice, usePointerMovement, validateHuman, weekdayNamesList };
10098
+ export { Anchor, Button, Checkbox, Details, DetailsBody, DetailsSummary, DropDown, DropDownButton, DropDownItem, DropDownItems, DropDownSection, DropDownSeparator, FacebookLogo, Fieldset, Form, FormStatusProvider, Ghost, GoogleLogo, Heading, HumanVerification, IFrame, Input, InstagramLogo, Link, LinkedInLogo, Modal, ModalClose, ModalDialog, ModalTitle, ModalTrigger, Search, SearchOption, Select, SelectOption, SelectSectionTitle, SubmitButton, Textarea, TikTokLogo, Time, Tooltip, TooltipPanel, TooltipTrigger, XLogo, YouTubeLogo, addClass, createFastContext, currentMonthName, currentWeekdayName, daysInMonth, easeOutExpo, emailRegex, extendMadoTailwindMerge, firstOfMonth, formatPhoneNumber, generateHumanValidationToken, getDate, getHours, getHoursIn12, getLinkClasses, getLocalTime, getMeridianFromHour, getMilliseconds, getMinutes, getMonth, getMonthIndexFromName, getMonthName, getNextMonth, getPreviousMonth, getSeconds, getTimezone, getUserReadableDate, getUserReadableDateFromTimestampz, getWeekdayName, getYearsInRange, hasClass, isEmail, isPhoneNumber, monthNamesList, removeClass, splitCamelCase, telRegex, toCamelCase, toFullDateString, toLowerCase, toTitleCase, toggleClass, twMerge, useFormStatus, useMobileDevice, usePointerMovement, validateHuman, weekdayNamesList };
@@ -12,6 +12,7 @@ export * from './input';
12
12
  export * from './link';
13
13
  export * from './modal';
14
14
  export * from './select';
15
+ export * from './search';
15
16
  export * from './submit-button';
16
17
  export * from './textarea';
17
18
  export * from './time';