@chekinapp/ui 0.0.4 → 0.0.5

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
@@ -3312,7 +3312,7 @@ GridItems.displayName = "GridItems";
3312
3312
 
3313
3313
  // src/help-tooltip/HelpTooltip.tsx
3314
3314
  import { CircleQuestionMark } from "lucide-react";
3315
- import { jsx as jsx55, jsxs as jsxs34 } from "react/jsx-runtime";
3315
+ import { Fragment as Fragment5, jsx as jsx55, jsxs as jsxs34 } from "react/jsx-runtime";
3316
3316
  function HelpTooltip({
3317
3317
  content,
3318
3318
  side,
@@ -3321,27 +3321,31 @@ function HelpTooltip({
3321
3321
  className,
3322
3322
  contentClassName,
3323
3323
  size = 16,
3324
- label = "More info"
3324
+ label = "More info",
3325
+ triggerAs = "button"
3325
3326
  }) {
3327
+ const triggerClassName = cn(
3328
+ "relative flex shrink-0 cursor-help items-center justify-center rounded-full",
3329
+ "text-chekin-gray-2 outline-none transition-colors hover:text-chekin-blue",
3330
+ triggerAs === "button" && "focus-visible:shadow-chekin-focus",
3331
+ className
3332
+ );
3333
+ const triggerStyle = { width: size, height: size };
3334
+ const triggerContent = /* @__PURE__ */ jsxs34(Fragment5, { children: [
3335
+ /* @__PURE__ */ jsx55(CircleQuestionMark, { "aria-hidden": "true", style: { width: size, height: size } }),
3336
+ /* @__PURE__ */ jsx55("span", { className: "absolute -left-0.5 -top-0.5 h-5 w-5" })
3337
+ ] });
3326
3338
  return /* @__PURE__ */ jsx55(TooltipProvider, { children: /* @__PURE__ */ jsxs34(TooltipRoot, { children: [
3327
- /* @__PURE__ */ jsx55(TooltipTrigger, { asChild: true, onClick, children: /* @__PURE__ */ jsxs34(
3339
+ /* @__PURE__ */ jsx55(TooltipTrigger, { asChild: true, onClick, children: triggerAs === "button" ? /* @__PURE__ */ jsx55(
3328
3340
  "button",
3329
3341
  {
3330
3342
  type: "button",
3331
3343
  "aria-label": label,
3332
- className: cn(
3333
- "relative flex shrink-0 cursor-help items-center justify-center rounded-full",
3334
- "text-chekin-gray-2 outline-none transition-colors hover:text-chekin-blue",
3335
- "focus-visible:shadow-chekin-focus",
3336
- className
3337
- ),
3338
- style: { width: size, height: size },
3339
- children: [
3340
- /* @__PURE__ */ jsx55(CircleQuestionMark, { "aria-hidden": "true", style: { width: size, height: size } }),
3341
- /* @__PURE__ */ jsx55("span", { className: "absolute -left-0.5 -top-0.5 h-5 w-5" })
3342
- ]
3344
+ className: triggerClassName,
3345
+ style: triggerStyle,
3346
+ children: triggerContent
3343
3347
  }
3344
- ) }),
3348
+ ) : /* @__PURE__ */ jsx55("span", { "aria-label": label, className: triggerClassName, style: triggerStyle, children: triggerContent }) }),
3345
3349
  /* @__PURE__ */ jsx55(
3346
3350
  TooltipContent,
3347
3351
  {
@@ -3356,11 +3360,11 @@ function HelpTooltip({
3356
3360
 
3357
3361
  // src/icon/Icon.tsx
3358
3362
  import { forwardRef as forwardRef23, memo as memo2 } from "react";
3359
- import { Fragment as Fragment5, jsx as jsx56, jsxs as jsxs35 } from "react/jsx-runtime";
3363
+ import { Fragment as Fragment6, jsx as jsx56, jsxs as jsxs35 } from "react/jsx-runtime";
3360
3364
  var MissingIcon = forwardRef23(
3361
3365
  ({ size = 24, className = "", fallback = null, color, ...props }, ref) => {
3362
3366
  if (fallback) {
3363
- return /* @__PURE__ */ jsx56(Fragment5, { children: fallback });
3367
+ return /* @__PURE__ */ jsx56(Fragment6, { children: fallback });
3364
3368
  }
3365
3369
  return /* @__PURE__ */ jsxs35(
3366
3370
  "svg",
@@ -5285,7 +5289,7 @@ function useRadioOptions({ options, defaultValue, onChange }) {
5285
5289
  var styles_default5 = {};
5286
5290
 
5287
5291
  // src/radio/Radio.tsx
5288
- import { Fragment as Fragment6, jsx as jsx78, jsxs as jsxs48 } from "react/jsx-runtime";
5292
+ import { Fragment as Fragment7, jsx as jsx78, jsxs as jsxs48 } from "react/jsx-runtime";
5289
5293
  var Radio = forwardRef32(
5290
5294
  ({ options, value, onChange, error, className = "", disabled = false, renderOption }, ref) => {
5291
5295
  const { selectedValue, handleValueChange } = useRadioOptions({
@@ -5299,7 +5303,7 @@ var Radio = forwardRef32(
5299
5303
  }
5300
5304
  return option.value === selectedValue;
5301
5305
  };
5302
- return /* @__PURE__ */ jsxs48(Fragment6, { children: [
5306
+ return /* @__PURE__ */ jsxs48(Fragment7, { children: [
5303
5307
  /* @__PURE__ */ jsx78(
5304
5308
  RadioGroup,
5305
5309
  {
@@ -5316,7 +5320,7 @@ var Radio = forwardRef32(
5316
5320
  styles_default5.radio__wrapper,
5317
5321
  (disabled || option.disabled) && styles_default5.radio__wrapper_disabled
5318
5322
  ),
5319
- children: renderOption ? renderOption({ option, isSelected: getIsSelected(option) }) : /* @__PURE__ */ jsxs48(Fragment6, { children: [
5323
+ children: renderOption ? renderOption({ option, isSelected: getIsSelected(option) }) : /* @__PURE__ */ jsxs48(Fragment7, { children: [
5320
5324
  /* @__PURE__ */ jsx78(
5321
5325
  RadioGroupItem,
5322
5326
  {
@@ -5574,42 +5578,74 @@ function SearchButton({ onClick, className, icon, ariaLabel }) {
5574
5578
  }
5575
5579
 
5576
5580
  // src/search-input/SearchInput.tsx
5577
- import { Search as Search2, X as X6 } from "lucide-react";
5581
+ import { Loader2 as Loader23, Search as Search2, X as X6 } from "lucide-react";
5578
5582
  import { useTranslation as useTranslation18 } from "react-i18next";
5579
5583
  import { jsx as jsx85, jsxs as jsxs53 } from "react/jsx-runtime";
5580
5584
  function SearchInput({
5585
+ disabled,
5586
+ invalid,
5587
+ label,
5588
+ loading,
5581
5589
  onReset,
5590
+ optional,
5582
5591
  placeholder,
5592
+ tooltip,
5583
5593
  wrapperClassName,
5584
5594
  className,
5585
5595
  ...props
5586
5596
  }) {
5587
5597
  const { t } = useTranslation18();
5588
5598
  const placeholderText = placeholder || `${t("search_property")}...`;
5589
- return /* @__PURE__ */ jsxs53("div", { className: cn("input-wrapper relative", wrapperClassName), children: [
5590
- /* @__PURE__ */ jsx85(Search2, { className: "absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 text-chekin-gray-2" }),
5591
- /* @__PURE__ */ jsx85(
5592
- Input,
5593
- {
5594
- ...props,
5595
- type: "text",
5596
- placeholder: placeholderText,
5597
- className: cn(
5598
- "w-full py-3 pl-12 pr-10 text-base text-chekin-navy focus:border-chekin-gray-3",
5599
- className
5599
+ const isBlocked = Boolean(disabled) || Boolean(loading);
5600
+ const optionalLabel = optional ? typeof optional === "string" ? optional : t("optional") : void 0;
5601
+ const hasLabelMeta = Boolean(optionalLabel) || Boolean(tooltip);
5602
+ return /* @__PURE__ */ jsxs53("div", { className: cn("input-wrapper", wrapperClassName), children: [
5603
+ (label || hasLabelMeta) && /* @__PURE__ */ jsxs53("div", { className: "mb-2 inline-flex max-w-full items-center gap-1.5 text-sm font-medium text-chekin-navy", children: [
5604
+ label && /* @__PURE__ */ jsx85("span", { className: "min-w-0 truncate", children: label }),
5605
+ optionalLabel && /* @__PURE__ */ jsx85("span", { className: "shrink-0 text-xs font-normal text-chekin-gray-2", children: optionalLabel }),
5606
+ tooltip && /* @__PURE__ */ jsx85(HelpTooltip, { content: tooltip, side: "top", size: 16 })
5607
+ ] }),
5608
+ /* @__PURE__ */ jsxs53("div", { className: "relative", children: [
5609
+ /* @__PURE__ */ jsx85(Search2, { className: "absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 text-chekin-gray-2" }),
5610
+ /* @__PURE__ */ jsx85(
5611
+ Input,
5612
+ {
5613
+ ...props,
5614
+ type: "text",
5615
+ disabled: isBlocked,
5616
+ placeholder: placeholderText,
5617
+ "aria-busy": loading,
5618
+ "aria-invalid": invalid,
5619
+ className: cn(
5620
+ "w-full py-3 pl-12 pr-10 text-base text-chekin-navy focus:border-chekin-gray-3",
5621
+ (loading || onReset) && "pr-20",
5622
+ invalid && "border-[var(--status-danger)] text-[var(--status-danger)] placeholder:text-[var(--status-danger)]",
5623
+ loading && "cursor-progress",
5624
+ className
5625
+ )
5626
+ }
5627
+ ),
5628
+ (loading || onReset) && /* @__PURE__ */ jsxs53("div", { className: "absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1", children: [
5629
+ loading && /* @__PURE__ */ jsx85(
5630
+ Loader23,
5631
+ {
5632
+ "aria-hidden": "true",
5633
+ className: "h-5 w-5 animate-spin text-chekin-gray-2"
5634
+ }
5635
+ ),
5636
+ onReset && /* @__PURE__ */ jsx85(
5637
+ Button,
5638
+ {
5639
+ variant: "ghost",
5640
+ onClick: onReset,
5641
+ disabled: isBlocked,
5642
+ className: "h-7 w-7 p-0 text-chekin-gray-2",
5643
+ "aria-label": t("reset_search"),
5644
+ children: /* @__PURE__ */ jsx85(X6, { className: "h-5 w-5" })
5645
+ }
5600
5646
  )
5601
- }
5602
- ),
5603
- onReset && /* @__PURE__ */ jsx85(
5604
- Button,
5605
- {
5606
- variant: "ghost",
5607
- onClick: onReset,
5608
- className: "absolute right-2 top-1/2 h-7 w-7 -translate-y-1/2 p-0 text-chekin-gray-2",
5609
- "aria-label": t("reset_search"),
5610
- children: /* @__PURE__ */ jsx85(X6, { className: "h-5 w-5" })
5611
- }
5612
- )
5647
+ ] })
5648
+ ] })
5613
5649
  ] });
5614
5650
  }
5615
5651
 
@@ -5802,7 +5838,7 @@ SelectorButton.displayName = "SelectorButton";
5802
5838
  var styles_default8 = {};
5803
5839
 
5804
5840
  // src/selectors/Selectors.tsx
5805
- import { Fragment as Fragment7, jsx as jsx89, jsxs as jsxs56 } from "react/jsx-runtime";
5841
+ import { Fragment as Fragment8, jsx as jsx89, jsxs as jsxs56 } from "react/jsx-runtime";
5806
5842
  var getValueArray = (value) => {
5807
5843
  if (value) {
5808
5844
  return Array.isArray(value) ? value : [value];
@@ -5859,7 +5895,7 @@ function SelectorsInternal({
5859
5895
  useEffect9(() => {
5860
5896
  onAnySelectorActive?.(isAnyActive);
5861
5897
  }, [isAnyActive, onAnySelectorActive]);
5862
- return /* @__PURE__ */ jsxs56(Fragment7, { children: [
5898
+ return /* @__PURE__ */ jsxs56(Fragment8, { children: [
5863
5899
  label && /* @__PURE__ */ jsx89("div", { className: styles_default8.labelWrapper, children: /* @__PURE__ */ jsx89("div", { className: cn(styles_default8.name, "label"), children: label }) }),
5864
5900
  /* @__PURE__ */ jsx89(
5865
5901
  "div",
@@ -6836,7 +6872,7 @@ function SortingAction({
6836
6872
  // src/status-button/StatusButton.tsx
6837
6873
  import { useMemo as useMemo3 } from "react";
6838
6874
  import { useTranslation as useTranslation20 } from "react-i18next";
6839
- import { AlertCircle as AlertCircle2, CheckCircle, Loader2 as Loader23 } from "lucide-react";
6875
+ import { AlertCircle as AlertCircle2, CheckCircle, Loader2 as Loader24 } from "lucide-react";
6840
6876
  import { jsx as jsx97, jsxs as jsxs61 } from "react/jsx-runtime";
6841
6877
  function StatusButton({
6842
6878
  hidden,
@@ -6855,7 +6891,7 @@ function StatusButton({
6855
6891
  const configMap = useMemo3(() => {
6856
6892
  const defaultLoadingConfig = {
6857
6893
  text: loadingText ?? `${t("saving")}...`,
6858
- icon: /* @__PURE__ */ jsx97(Loader23, { className: "h-4 w-4 animate-spin" }),
6894
+ icon: /* @__PURE__ */ jsx97(Loader24, { className: "h-4 w-4 animate-spin" }),
6859
6895
  variant,
6860
6896
  isLoading: true
6861
6897
  };
@@ -7742,7 +7778,7 @@ var LABEL_PLACEMENT = /* @__PURE__ */ ((LABEL_PLACEMENT2) => {
7742
7778
  var styles_default10 = {};
7743
7779
 
7744
7780
  // src/three-dots-loader/ThreeDotsLoader.tsx
7745
- import { Fragment as Fragment8, jsx as jsx113, jsxs as jsxs71 } from "react/jsx-runtime";
7781
+ import { Fragment as Fragment9, jsx as jsx113, jsxs as jsxs71 } from "react/jsx-runtime";
7746
7782
  function Dots({
7747
7783
  height,
7748
7784
  width,
@@ -7764,10 +7800,10 @@ function ThreeDotsLoader({
7764
7800
  }) {
7765
7801
  const dots = /* @__PURE__ */ jsx113(Dots, { color, height, width });
7766
7802
  if (label) {
7767
- return /* @__PURE__ */ jsx113("div", { className: cn(styles_default10.Loader, className), children: labelPlacement === 0 /* right */ ? /* @__PURE__ */ jsxs71(Fragment8, { children: [
7803
+ return /* @__PURE__ */ jsx113("div", { className: cn(styles_default10.Loader, className), children: labelPlacement === 0 /* right */ ? /* @__PURE__ */ jsxs71(Fragment9, { children: [
7768
7804
  dots,
7769
7805
  /* @__PURE__ */ jsx113("div", { children: label })
7770
- ] }) : /* @__PURE__ */ jsxs71(Fragment8, { children: [
7806
+ ] }) : /* @__PURE__ */ jsxs71(Fragment9, { children: [
7771
7807
  /* @__PURE__ */ jsx113("div", { children: label }),
7772
7808
  dots
7773
7809
  ] }) });
@@ -8012,6 +8048,13 @@ function stripTime(date) {
8012
8048
  function isValidDate(value) {
8013
8049
  return value instanceof Date && !Number.isNaN(value.getTime());
8014
8050
  }
8051
+ function normalizeDateValue(value) {
8052
+ if (value === "" || value === null || value === void 0) {
8053
+ return null;
8054
+ }
8055
+ const date = value instanceof Date ? value : new Date(value);
8056
+ return isValidDate(date) ? date : null;
8057
+ }
8015
8058
  function clampDate(date, minDate, maxDate) {
8016
8059
  const normalizedDate = stripTime(date);
8017
8060
  const normalizedMinDate = isValidDate(minDate) ? stripTime(minDate) : null;
@@ -8676,6 +8719,8 @@ var DEVICE = {
8676
8719
 
8677
8720
  // src/field-trigger/FieldTrigger.tsx
8678
8721
  import * as React29 from "react";
8722
+ import { Loader2 as Loader25 } from "lucide-react";
8723
+ import { useTranslation as useTranslation22 } from "react-i18next";
8679
8724
 
8680
8725
  // src/field-error-message/FieldErrorMessage.tsx
8681
8726
  import { AlertCircle as AlertCircle3 } from "lucide-react";
@@ -8716,7 +8761,7 @@ function FieldErrorMessage({
8716
8761
  }
8717
8762
 
8718
8763
  // src/field-trigger/FieldTrigger.tsx
8719
- import { Fragment as Fragment9, jsx as jsx120, jsxs as jsxs77 } from "react/jsx-runtime";
8764
+ import { Fragment as Fragment10, jsx as jsx120, jsxs as jsxs77 } from "react/jsx-runtime";
8720
8765
  var FieldTrigger = React29.forwardRef(
8721
8766
  ({
8722
8767
  as = "button",
@@ -8733,30 +8778,63 @@ var FieldTrigger = React29.forwardRef(
8733
8778
  placeholder,
8734
8779
  disabled,
8735
8780
  error,
8781
+ loading,
8782
+ optional,
8783
+ tooltip,
8736
8784
  describedBy,
8737
8785
  className,
8738
8786
  contentClassName,
8739
8787
  trailingAdornment,
8740
8788
  forceFloatingLabel = false,
8789
+ forceLabelText = false,
8741
8790
  hideErrorMessage = false,
8742
8791
  children,
8743
8792
  onClick,
8744
8793
  onKeyDown,
8745
8794
  ...props
8746
8795
  }, ref) => {
8796
+ const { t } = useTranslation22();
8747
8797
  const hasValue = Boolean(valueText);
8748
8798
  const isRaised = hasValue || forceFloatingLabel;
8749
- const animatedLabel = isRaised ? labelText ?? label : label ?? placeholder;
8799
+ const optionalLabel = optional ? typeof optional === "string" ? optional : t("optional") : void 0;
8800
+ const visibleLabelText = labelText ?? label;
8801
+ const hasLabelMeta = Boolean(optionalLabel) || Boolean(tooltip);
8802
+ const resolvedLabelText = visibleLabelText && hasLabelMeta ? /* @__PURE__ */ jsxs77("span", { className: "inline-flex max-w-full items-center gap-1.5 align-middle", children: [
8803
+ /* @__PURE__ */ jsx120("span", { className: "min-w-0 truncate", children: visibleLabelText }),
8804
+ optionalLabel && /* @__PURE__ */ jsxs77("span", { className: "shrink-0 text-[12px] relative top-[1px] font-normal leading-4 text-current opacity-70", children: [
8805
+ "(",
8806
+ optionalLabel,
8807
+ ")"
8808
+ ] }),
8809
+ tooltip && /* @__PURE__ */ jsx120(
8810
+ HelpTooltip,
8811
+ {
8812
+ content: tooltip,
8813
+ side: "top",
8814
+ size: 16,
8815
+ triggerAs: as === "button" ? "span" : "button",
8816
+ className: "pointer-events-auto text-current opacity-70 hover:text-current hover:opacity-100"
8817
+ }
8818
+ )
8819
+ ] }) : visibleLabelText;
8820
+ const animatedLabel = forceLabelText ? resolvedLabelText ?? placeholder : isRaised ? resolvedLabelText : label ?? placeholder;
8750
8821
  const isAirbnbVariant = variant === "airbnb";
8822
+ const hasInvalidState = Boolean(error);
8823
+ const errorMessage = typeof error === "string" ? error : void 0;
8824
+ const isBlocked = Boolean(disabled) || Boolean(loading);
8825
+ const resolvedTrailingAdornment = loading || trailingAdornment ? /* @__PURE__ */ jsxs77("span", { className: "flex items-center gap-2", children: [
8826
+ trailingAdornment,
8827
+ loading && /* @__PURE__ */ jsx120(Loader25, { "aria-hidden": "true", className: "h-5 w-5 animate-spin text-[#7A8399]" })
8828
+ ] }) : void 0;
8751
8829
  const sharedClasses = cn(
8752
8830
  "relative flex border w-full items-center bg-[var(--form-background-color,#fff)] text-left transition-colors focus-visible:outline-none",
8753
8831
  isAirbnbVariant ? "rounded-[var(--form-input-border-radius,12px)] border-[var(--form-border-color,#8c8c8c)] pl-4 pr-4 focus-visible:ring-2 focus-visible:ring-[var(--form-title-color,#222222)] focus-visible:ring-offset-2" : "rounded-[10px] px-3.5 focus-visible:border-[#315EFB]",
8754
8832
  isAirbnbVariant ? isRaised ? "min-h-[60px]" : "h-[60px]" : "min-h-[48px]",
8755
- error ? isAirbnbVariant ? "border-[var(--status-danger)] bg-[var(--form-error-background,#FFF5F3)]" : "border-[var(--status-danger)] bg-white" : isAirbnbVariant ? "border-[var(--form-border-color,#8c8c8c)]" : "border-[#A8A8A4] bg-white",
8756
- disabled ? "cursor-not-allowed opacity-50" : isAirbnbVariant ? "cursor-pointer" : "cursor-text",
8833
+ hasInvalidState ? isAirbnbVariant ? "border-[var(--status-danger)] bg-[var(--form-error-background,#FFF5F3)]" : "border-[var(--status-danger)] bg-white" : isAirbnbVariant ? "border-[var(--form-border-color,#8c8c8c)]" : "border-[#A8A8A4] bg-white",
8834
+ disabled ? "cursor-not-allowed opacity-50" : loading ? "cursor-progress" : isAirbnbVariant ? "cursor-pointer" : "cursor-text",
8757
8835
  className
8758
8836
  );
8759
- const sharedContent = /* @__PURE__ */ jsxs77(Fragment9, { children: [
8837
+ const sharedContent = /* @__PURE__ */ jsxs77(Fragment10, { children: [
8760
8838
  /* @__PURE__ */ jsxs77(
8761
8839
  "span",
8762
8840
  {
@@ -8771,9 +8849,10 @@ var FieldTrigger = React29.forwardRef(
8771
8849
  {
8772
8850
  id: labelId,
8773
8851
  className: cn(
8774
- "pointer-events-none absolute left-0 origin-left truncate transition-all duration-200 ease-out",
8852
+ "absolute left-0 origin-left truncate transition-all duration-200 ease-out",
8853
+ hasLabelMeta ? "" : "pointer-events-none",
8775
8854
  isAirbnbVariant ? isRaised ? "top-0 translate-y-0 text-xs leading-5" : "top-1/2 -translate-y-1/2 text-[16px] leading-7" : isRaised ? "-top-2 translate-y-0 bg-[var(--form-background-color,#fff)] px-1 text-[12px] font-medium leading-4" : "top-1/2 -translate-y-1/2 text-[16px] leading-6",
8776
- error ? "text-[var(--status-danger)]" : isAirbnbVariant ? "text-[var(--form-placeholder-color,#6c6c6c)]" : "text-[#7A8399]"
8855
+ hasInvalidState ? "text-[var(--status-danger)]" : isAirbnbVariant ? "text-[var(--form-placeholder-color,#6c6c6c)]" : "text-[#7A8399]"
8777
8856
  ),
8778
8857
  children: animatedLabel
8779
8858
  }
@@ -8785,7 +8864,7 @@ var FieldTrigger = React29.forwardRef(
8785
8864
  className: cn(
8786
8865
  "absolute left-0 block truncate transition-all duration-200 ease-out",
8787
8866
  isAirbnbVariant ? "bottom-0 translate-y-0 text-[16px] leading-6 opacity-100" : "bottom-[11px] text-[16px] leading-6",
8788
- error ? "text-[var(--status-danger)]" : "text-[var(--form-field-text-color,#222222)]"
8867
+ hasInvalidState ? "text-[var(--status-danger)]" : "text-[var(--form-field-text-color,#222222)]"
8789
8868
  ),
8790
8869
  children: valueText
8791
8870
  }
@@ -8793,7 +8872,7 @@ var FieldTrigger = React29.forwardRef(
8793
8872
  ]
8794
8873
  }
8795
8874
  ),
8796
- trailingAdornment && /* @__PURE__ */ jsx120(
8875
+ resolvedTrailingAdornment && /* @__PURE__ */ jsx120(
8797
8876
  "span",
8798
8877
  {
8799
8878
  "aria-hidden": "true",
@@ -8801,7 +8880,7 @@ var FieldTrigger = React29.forwardRef(
8801
8880
  "pointer-events-none absolute top-1/2 -translate-y-1/2",
8802
8881
  isAirbnbVariant ? "right-5" : "right-4"
8803
8882
  ),
8804
- children: trailingAdornment
8883
+ children: resolvedTrailingAdornment
8805
8884
  }
8806
8885
  )
8807
8886
  ] });
@@ -8815,10 +8894,11 @@ var FieldTrigger = React29.forwardRef(
8815
8894
  type: "button",
8816
8895
  "aria-labelledby": hasValue && valueId ? `${labelId} ${valueId}` : labelId,
8817
8896
  "aria-describedby": describedBy,
8818
- "aria-invalid": Boolean(error),
8819
- disabled,
8820
- onClick,
8821
- onKeyDown,
8897
+ "aria-invalid": hasInvalidState,
8898
+ "aria-busy": loading,
8899
+ disabled: isBlocked,
8900
+ onClick: isBlocked ? void 0 : onClick,
8901
+ onKeyDown: isBlocked ? void 0 : onKeyDown,
8822
8902
  className: sharedClasses,
8823
8903
  ...props,
8824
8904
  children: sharedContent
@@ -8830,16 +8910,17 @@ var FieldTrigger = React29.forwardRef(
8830
8910
  ref,
8831
8911
  "aria-labelledby": hasValue && valueId ? `${labelId} ${valueId}` : labelId,
8832
8912
  "aria-describedby": describedBy,
8833
- "aria-invalid": Boolean(error),
8834
- "aria-disabled": disabled,
8835
- onClick,
8836
- onKeyDown,
8913
+ "aria-invalid": hasInvalidState,
8914
+ "aria-busy": loading,
8915
+ "aria-disabled": isBlocked,
8916
+ onClick: isBlocked ? void 0 : onClick,
8917
+ onKeyDown: isBlocked ? void 0 : onKeyDown,
8837
8918
  className: sharedClasses,
8838
8919
  ...props,
8839
8920
  children: sharedContent
8840
8921
  }
8841
8922
  ),
8842
- error && !hideErrorMessage && /* @__PURE__ */ jsx120(FieldErrorMessage, { id: errorId, message: error })
8923
+ errorMessage && !hideErrorMessage && /* @__PURE__ */ jsx120(FieldErrorMessage, { id: errorId, message: errorMessage })
8843
8924
  ] });
8844
8925
  }
8845
8926
  );
@@ -8859,6 +8940,10 @@ var DatePicker = React30.forwardRef(
8859
8940
  placeholder = "Select a date",
8860
8941
  disabled,
8861
8942
  error,
8943
+ invalid,
8944
+ loading,
8945
+ optional,
8946
+ tooltip,
8862
8947
  className,
8863
8948
  name,
8864
8949
  minDate,
@@ -8881,11 +8966,18 @@ var DatePicker = React30.forwardRef(
8881
8966
  const monthLabels = React30.useMemo(() => getMonthLabels(locale), [locale]);
8882
8967
  const resolvedMinDate = React30.useMemo(() => minDate ?? DEFAULT_MIN_DATE, [minDate]);
8883
8968
  const resolvedMaxDate = React30.useMemo(() => maxDate ?? /* @__PURE__ */ new Date(), [maxDate]);
8969
+ const normalizedValue = React30.useMemo(() => normalizeDateValue(value), [value]);
8970
+ const normalizedDefaultValue = React30.useMemo(
8971
+ () => normalizeDateValue(defaultValue),
8972
+ [defaultValue]
8973
+ );
8884
8974
  const resolvedValue = React30.useMemo(
8885
- () => value ? clampDate(value, resolvedMinDate, resolvedMaxDate) : null,
8886
- [resolvedMaxDate, resolvedMinDate, value]
8975
+ () => normalizedValue ? clampDate(normalizedValue, resolvedMinDate, resolvedMaxDate) : null,
8976
+ [normalizedValue, resolvedMaxDate, resolvedMinDate]
8887
8977
  );
8888
8978
  const hasValue = Boolean(resolvedValue);
8979
+ const isBlocked = Boolean(disabled) || Boolean(loading);
8980
+ const triggerError = error ?? invalid;
8889
8981
  const {
8890
8982
  dayIndex,
8891
8983
  dayListRef,
@@ -8906,34 +8998,51 @@ var DatePicker = React30.forwardRef(
8906
8998
  } = useDatePickerWheel({
8907
8999
  isOpen,
8908
9000
  value: resolvedValue,
8909
- defaultValue,
9001
+ defaultValue: normalizedDefaultValue,
8910
9002
  minDate: resolvedMinDate,
8911
9003
  maxDate: resolvedMaxDate
8912
9004
  });
8913
- const handleOpenChange = React30.useCallback((nextOpen) => {
8914
- setIsOpen(nextOpen);
8915
- if (!nextOpen) {
8916
- internalRef.current?.focus();
8917
- }
8918
- }, []);
9005
+ const handleOpenChange = React30.useCallback(
9006
+ (nextOpen) => {
9007
+ if (isBlocked && nextOpen) return;
9008
+ setIsOpen(nextOpen);
9009
+ if (!nextOpen) {
9010
+ internalRef.current?.focus();
9011
+ }
9012
+ },
9013
+ [isBlocked]
9014
+ );
8919
9015
  const handleDone = React30.useCallback(() => {
9016
+ if (isBlocked) return;
8920
9017
  onChange(clampDate(draftDate, resolvedMinDate, resolvedMaxDate));
8921
9018
  handleOpenChange(false);
8922
- }, [draftDate, handleOpenChange, onChange, resolvedMaxDate, resolvedMinDate]);
9019
+ }, [
9020
+ draftDate,
9021
+ handleOpenChange,
9022
+ isBlocked,
9023
+ onChange,
9024
+ resolvedMaxDate,
9025
+ resolvedMinDate
9026
+ ]);
8923
9027
  const handleTriggerClick = React30.useCallback(() => {
8924
- if (disabled) return;
9028
+ if (isBlocked) return;
8925
9029
  setIsOpen(true);
8926
- }, [disabled]);
9030
+ }, [isBlocked]);
8927
9031
  const handleTriggerKeyDown = React30.useCallback(
8928
9032
  (event) => {
8929
- if (disabled) return;
9033
+ if (isBlocked) return;
8930
9034
  if (event.key === "ArrowDown" || event.key === "ArrowUp" || event.key === "Enter" || event.key === " ") {
8931
9035
  event.preventDefault();
8932
9036
  setIsOpen(true);
8933
9037
  }
8934
9038
  },
8935
- [disabled]
9039
+ [isBlocked]
8936
9040
  );
9041
+ React30.useEffect(() => {
9042
+ if (isBlocked) {
9043
+ setIsOpen(false);
9044
+ }
9045
+ }, [isBlocked]);
8937
9046
  return /* @__PURE__ */ jsxs78("div", { className: cn("relative w-full max-w-[425px]", className), children: [
8938
9047
  name && /* @__PURE__ */ jsx121(
8939
9048
  "input",
@@ -8960,7 +9069,11 @@ var DatePicker = React30.forwardRef(
8960
9069
  valueText: resolvedValue ? formatValue(resolvedValue) : void 0,
8961
9070
  placeholder,
8962
9071
  disabled,
8963
- error,
9072
+ error: triggerError,
9073
+ loading,
9074
+ optional,
9075
+ tooltip,
9076
+ forceLabelText: Boolean(optional) || Boolean(tooltip),
8964
9077
  "aria-haspopup": "dialog",
8965
9078
  "aria-expanded": isOpen,
8966
9079
  onClick: handleTriggerClick,
@@ -9120,6 +9233,10 @@ var AirbnbInput = React31.forwardRef(
9120
9233
  topLabel,
9121
9234
  helperText,
9122
9235
  error,
9236
+ invalid,
9237
+ loading,
9238
+ optional,
9239
+ tooltip,
9123
9240
  wrapperClassName,
9124
9241
  fieldClassName,
9125
9242
  contentClassName,
@@ -9144,7 +9261,7 @@ var AirbnbInput = React31.forwardRef(
9144
9261
  const fieldId = `${inputId}-field`;
9145
9262
  const labelId = `${inputId}-label`;
9146
9263
  const errorId = `${inputId}-error`;
9147
- const accessibleLabel = label ?? placeholder;
9264
+ const accessibleLabel = placeholder ?? label;
9148
9265
  const [isFocused, setIsFocused] = React31.useState(false);
9149
9266
  const [currentValue, setCurrentValue] = React31.useState(
9150
9267
  () => value != null ? getInputValue(value) : getInputValue(defaultValue)
@@ -9152,6 +9269,10 @@ var AirbnbInput = React31.forwardRef(
9152
9269
  const resolvedValue = value != null ? getInputValue(value) : currentValue;
9153
9270
  const hasValue = resolvedValue.length > 0;
9154
9271
  const shouldShowLabel = hasValue || isFocused;
9272
+ const hasInvalidState = Boolean(error) || Boolean(invalid);
9273
+ const triggerError = error ?? invalid;
9274
+ const hasLabelMeta = Boolean(optional) || Boolean(tooltip);
9275
+ const isBlocked = Boolean(disabled) || Boolean(loading);
9155
9276
  React31.useLayoutEffect(() => {
9156
9277
  const nextValue = value != null ? getInputValue(value) : getInputValue(inputRef.current?.value);
9157
9278
  setCurrentValue((prevValue) => prevValue === nextValue ? prevValue : nextValue);
@@ -9200,7 +9321,10 @@ var AirbnbInput = React31.forwardRef(
9200
9321
  labelText: helperText ?? label,
9201
9322
  placeholder: placeholder ?? label,
9202
9323
  disabled,
9203
- error,
9324
+ error: triggerError,
9325
+ loading,
9326
+ optional,
9327
+ tooltip,
9204
9328
  describedBy: error && renderErrorMessage ? errorId : void 0,
9205
9329
  className: cn(
9206
9330
  variant === "airbnb" ? "px-4 focus-within:ring-2 focus-within:ring-[#1F1F1B] focus-within:ring-offset-2" : "px-3.5 focus-within:border-[#315EFB]",
@@ -9213,6 +9337,7 @@ var AirbnbInput = React31.forwardRef(
9213
9337
  ),
9214
9338
  trailingAdornment,
9215
9339
  forceFloatingLabel: shouldShowLabel,
9340
+ forceLabelText: hasLabelMeta,
9216
9341
  hideErrorMessage: !renderErrorMessage,
9217
9342
  children: /* @__PURE__ */ jsx123(
9218
9343
  "input",
@@ -9221,21 +9346,23 @@ var AirbnbInput = React31.forwardRef(
9221
9346
  id: inputId,
9222
9347
  ref: setRefs,
9223
9348
  type,
9224
- disabled,
9349
+ disabled: isBlocked,
9225
9350
  value,
9226
9351
  defaultValue,
9227
9352
  onChange: handleChange,
9228
9353
  onFocus: handleFocus,
9229
9354
  onBlur: handleBlur,
9230
9355
  placeholder: "",
9231
- "aria-invalid": Boolean(error),
9356
+ "aria-invalid": hasInvalidState,
9357
+ "aria-busy": loading,
9232
9358
  "aria-describedby": error && renderErrorMessage ? errorId : void 0,
9233
- "aria-labelledby": accessibleLabel ? labelId : void 0,
9359
+ "aria-label": accessibleLabel && hasLabelMeta ? accessibleLabel : void 0,
9360
+ "aria-labelledby": accessibleLabel && !hasLabelMeta ? labelId : void 0,
9234
9361
  className: cn(
9235
9362
  "absolute left-0 h-6 w-full border-0 bg-transparent p-0 text-[16px] leading-6 text-[#1F1F1B] outline-none placeholder:text-[#7A8399]",
9236
9363
  variant === "airbnb" ? "bottom-0" : "bottom-[12px]",
9237
- error ? "text-[var(--status-danger)] placeholder:text-[var(--status-danger)]" : "",
9238
- disabled ? "cursor-not-allowed" : "",
9364
+ hasInvalidState ? "text-[var(--status-danger)] placeholder:text-[var(--status-danger)]" : "",
9365
+ disabled ? "cursor-not-allowed" : loading ? "cursor-progress" : "",
9239
9366
  inputClassName,
9240
9367
  className
9241
9368
  )
@@ -9610,6 +9737,9 @@ var SelectTrigger2 = React32.forwardRef(
9610
9737
  helperText,
9611
9738
  valueLabel,
9612
9739
  disabled,
9740
+ loading,
9741
+ optional,
9742
+ tooltip,
9613
9743
  error,
9614
9744
  hideErrorMessage,
9615
9745
  labelId,
@@ -9641,6 +9771,10 @@ var SelectTrigger2 = React32.forwardRef(
9641
9771
  placeholder: helperText,
9642
9772
  describedBy,
9643
9773
  error,
9774
+ loading,
9775
+ optional,
9776
+ tooltip,
9777
+ forceLabelText: Boolean(optional) || Boolean(tooltip),
9644
9778
  hideErrorMessage,
9645
9779
  disabled,
9646
9780
  onClick,
@@ -10007,7 +10141,7 @@ function useSelectIds({ name, hasValue, error, hideErrorMessage }) {
10007
10141
  }
10008
10142
 
10009
10143
  // src/lib/use-outside-click.ts
10010
- import { useCallback as useCallback18, useEffect as useEffect16, useRef as useRef16 } from "react";
10144
+ import { useCallback as useCallback18, useEffect as useEffect17, useRef as useRef16 } from "react";
10011
10145
  function useOutsideClick(elementRef, onOutsideClick, nested) {
10012
10146
  const handleOutsideClick = useRef16(onOutsideClick);
10013
10147
  handleOutsideClick.current = onOutsideClick;
@@ -10042,7 +10176,7 @@ function useOutsideClick(elementRef, onOutsideClick, nested) {
10042
10176
  },
10043
10177
  [nested]
10044
10178
  );
10045
- useEffect16(() => {
10179
+ useEffect17(() => {
10046
10180
  function handleClickOutside(event) {
10047
10181
  const isNestedElement = checkNestedElements(event);
10048
10182
  if (elementRef?.current && !elementRef.current.contains(event.target) && !isNestedElement) {
@@ -10071,7 +10205,11 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10071
10205
  getValueLabel,
10072
10206
  renderTrigger,
10073
10207
  disabled,
10208
+ loading,
10209
+ optional,
10210
+ tooltip,
10074
10211
  error,
10212
+ invalid,
10075
10213
  hideErrorMessage,
10076
10214
  className,
10077
10215
  menuClassName,
@@ -10086,6 +10224,8 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10086
10224
  const containerRef = React36.useRef(null);
10087
10225
  const hasValue = Boolean(value);
10088
10226
  const helperText = placeholder ?? label;
10227
+ const isBlocked = Boolean(disabled) || Boolean(loading);
10228
+ const triggerError = error ?? invalid;
10089
10229
  const {
10090
10230
  triggerId,
10091
10231
  labelId,
@@ -10111,7 +10251,7 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10111
10251
  isOpen,
10112
10252
  options,
10113
10253
  value,
10114
- disabled
10254
+ disabled: isBlocked
10115
10255
  });
10116
10256
  const {
10117
10257
  highlightedIndex,
@@ -10128,13 +10268,18 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10128
10268
  isOpen,
10129
10269
  options,
10130
10270
  value,
10131
- disabled,
10271
+ disabled: isBlocked,
10132
10272
  onChange
10133
10273
  });
10134
10274
  const combinedRef = useCombinedRef(ref, desktopTriggerRef);
10135
10275
  const activeMobileIndex = getOptionIndex(options, pendingValue);
10136
10276
  const valueLabel = value ? getValueLabel?.(value) ?? String(value.label) : void 0;
10137
10277
  useOutsideClick(containerRef, isOpen && !isMobile ? () => setIsOpen(false) : null);
10278
+ React36.useEffect(() => {
10279
+ if (isBlocked) {
10280
+ setIsOpen(false);
10281
+ }
10282
+ }, [isBlocked]);
10138
10283
  React36.useEffect(
10139
10284
  function setCorrectOptionIfThereIsOnlyValue() {
10140
10285
  if (value?.value === void 0 || value.value === null || value.label !== "") {
@@ -10149,24 +10294,26 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10149
10294
  );
10150
10295
  const handleMobileOpenChange = React36.useCallback(
10151
10296
  (nextOpen) => {
10297
+ if (isBlocked && nextOpen) return;
10152
10298
  setIsOpen(nextOpen);
10153
10299
  syncPendingValue(value ?? null);
10154
10300
  if (!nextOpen) {
10155
10301
  focusTrigger();
10156
10302
  }
10157
10303
  },
10158
- [focusTrigger, syncPendingValue, value]
10304
+ [focusTrigger, isBlocked, syncPendingValue, value]
10159
10305
  );
10160
10306
  const handleMobileDone = React36.useCallback(() => {
10307
+ if (isBlocked) return;
10161
10308
  const finalOption = pendingValue;
10162
10309
  if (finalOption && finalOption.value !== value?.value) {
10163
10310
  onChange(finalOption);
10164
10311
  }
10165
10312
  setIsOpen(false);
10166
10313
  focusTrigger();
10167
- }, [focusTrigger, onChange, pendingValue, value]);
10314
+ }, [focusTrigger, isBlocked, onChange, pendingValue, value]);
10168
10315
  const handleTriggerClick = React36.useCallback(() => {
10169
- if (disabled) return;
10316
+ if (isBlocked) return;
10170
10317
  setIsOpen((prev) => {
10171
10318
  const nextOpen = !prev;
10172
10319
  if (isMobile) {
@@ -10174,10 +10321,10 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10174
10321
  }
10175
10322
  return nextOpen;
10176
10323
  });
10177
- }, [disabled, isMobile, syncPendingValue, value]);
10324
+ }, [isBlocked, isMobile, syncPendingValue, value]);
10178
10325
  const handleRootTriggerKeyDown = (event) => {
10179
10326
  if (isMobile) {
10180
- if (disabled) return;
10327
+ if (isBlocked) return;
10181
10328
  if (event.key === "ArrowDown" || event.key === "ArrowUp" || event.key === "Enter" || event.key === " ") {
10182
10329
  event.preventDefault();
10183
10330
  syncPendingValue(value ?? null);
@@ -10229,8 +10376,12 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10229
10376
  helperText,
10230
10377
  value,
10231
10378
  valueLabel,
10232
- disabled,
10379
+ disabled: isBlocked,
10380
+ loading,
10381
+ optional,
10382
+ tooltip,
10233
10383
  error,
10384
+ invalid,
10234
10385
  listboxId,
10235
10386
  describedBy,
10236
10387
  triggerRef: combinedRef,
@@ -10248,7 +10399,10 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10248
10399
  helperText,
10249
10400
  valueLabel,
10250
10401
  disabled,
10251
- error,
10402
+ loading,
10403
+ optional,
10404
+ tooltip,
10405
+ error: triggerError,
10252
10406
  hideErrorMessage,
10253
10407
  labelId,
10254
10408
  valueId,
@@ -10273,7 +10427,7 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10273
10427
  doneLabel,
10274
10428
  errorId: describedErrorId,
10275
10429
  options,
10276
- disabled,
10430
+ disabled: isBlocked,
10277
10431
  menuClassName,
10278
10432
  scrollTop: mobileScrollTop,
10279
10433
  activeIndex: activeMobileIndex,
@@ -10304,7 +10458,7 @@ var AirbnbSelect = React36.forwardRef(function AirbnbSelect2({
10304
10458
  onKeyDown: (event) => {
10305
10459
  handleMenuKeyDown(event, () => setIsOpen(false));
10306
10460
  },
10307
- disabled,
10461
+ disabled: isBlocked,
10308
10462
  menuClassName,
10309
10463
  dropdownClassName,
10310
10464
  listRef: desktopListRef,
@@ -10328,7 +10482,12 @@ var PhoneField = React37.forwardRef(
10328
10482
  options,
10329
10483
  placeholder = "Phone number",
10330
10484
  disabled,
10485
+ codeReadOnly,
10331
10486
  error,
10487
+ invalid,
10488
+ loading,
10489
+ optional,
10490
+ tooltip,
10332
10491
  className,
10333
10492
  name,
10334
10493
  codeName,
@@ -10350,6 +10509,9 @@ var PhoneField = React37.forwardRef(
10350
10509
  [codeOptions, value?.code]
10351
10510
  );
10352
10511
  const combinedValue = value?.code || value?.number ? `${value?.code ?? ""}${value?.number ?? ""}` : "";
10512
+ const hasInvalidState = Boolean(error) || Boolean(invalid);
10513
+ const isBlocked = Boolean(disabled) || Boolean(loading);
10514
+ const isCodeBlocked = isBlocked || Boolean(codeReadOnly);
10353
10515
  return /* @__PURE__ */ jsxs84("div", { className: cn("w-full max-w-[425px]", className), children: [
10354
10516
  name && /* @__PURE__ */ jsx130("input", { type: "hidden", name, value: combinedValue, disabled }),
10355
10517
  codeName && /* @__PURE__ */ jsx130(
@@ -10392,7 +10554,9 @@ var PhoneField = React37.forwardRef(
10392
10554
  }),
10393
10555
  label: `${label} country code`,
10394
10556
  placeholder: codePlaceholder,
10395
- disabled,
10557
+ disabled: isCodeBlocked,
10558
+ loading,
10559
+ invalid,
10396
10560
  className: "max-w-none shrink-0 basis-[96px]",
10397
10561
  mobileTitle: mobileTitle ?? "Select country code",
10398
10562
  dropdownClassName: "right-auto w-[280px]",
@@ -10402,6 +10566,7 @@ var PhoneField = React37.forwardRef(
10402
10566
  open,
10403
10567
  variant: selectVariant,
10404
10568
  disabled: triggerDisabled,
10569
+ loading: triggerLoading,
10405
10570
  listboxId,
10406
10571
  triggerRef,
10407
10572
  onClick,
@@ -10417,14 +10582,16 @@ var PhoneField = React37.forwardRef(
10417
10582
  "aria-haspopup": "listbox",
10418
10583
  "aria-expanded": open,
10419
10584
  "aria-controls": listboxId,
10585
+ "aria-busy": triggerLoading,
10586
+ "aria-invalid": hasInvalidState,
10420
10587
  disabled: triggerDisabled,
10421
10588
  onClick,
10422
10589
  onKeyDown,
10423
10590
  className: cn(
10424
10591
  "flex w-full items-center justify-center gap-2 border border-r-0 text-[16px] font-medium leading-6 transition-colors focus-visible:outline-none",
10425
10592
  selectVariant === "airbnb" ? "h-full min-h-[60px] rounded-l-[16px] rounded-r-none px-4 focus-visible:ring-2 focus-visible:ring-[#1F1F1B] focus-visible:ring-offset-2" : "min-h-[48px] rounded-l-[10px] rounded-r-none px-3.5 focus-visible:border-[#315EFB]",
10426
- error ? "border-[var(--status-danger)] bg-[#F2F2F2] text-[var(--status-danger)]" : selectVariant === "airbnb" ? "border-[#8C8C8C] bg-[#F4F4F2] text-[#1F1F1B]" : "border-[#A8A8A4] bg-white text-[#1F1F1B]",
10427
- triggerDisabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
10593
+ hasInvalidState ? "border-[var(--status-danger)] bg-[#F2F2F2] text-[var(--status-danger)]" : selectVariant === "airbnb" ? "border-[#8C8C8C] bg-[#F4F4F2] text-[#1F1F1B]" : "border-[#A8A8A4] bg-white text-[#1F1F1B]",
10594
+ triggerDisabled ? "cursor-not-allowed opacity-50" : triggerLoading ? "cursor-progress" : "cursor-pointer"
10428
10595
  ),
10429
10596
  children: [
10430
10597
  /* @__PURE__ */ jsx130("span", { children: valueLabel ?? codePlaceholder }),
@@ -10453,6 +10620,10 @@ var PhoneField = React37.forwardRef(
10453
10620
  placeholder,
10454
10621
  disabled,
10455
10622
  error,
10623
+ invalid,
10624
+ loading,
10625
+ optional,
10626
+ tooltip,
10456
10627
  renderErrorMessage: false,
10457
10628
  wrapperClassName: "min-w-0 flex-1",
10458
10629
  fieldClassName: cn(
@@ -10475,11 +10646,11 @@ PhoneField.displayName = "PhoneField";
10475
10646
 
10476
10647
  // src/airbnb/search-input/SearchInput.tsx
10477
10648
  import * as React38 from "react";
10478
- import { useTranslation as useTranslation22 } from "react-i18next";
10649
+ import { useTranslation as useTranslation23 } from "react-i18next";
10479
10650
  import { Search as Search3, X as X8 } from "lucide-react";
10480
10651
  import { jsx as jsx131, jsxs as jsxs85 } from "react/jsx-runtime";
10481
10652
  var AirbnbSearchInput = React38.forwardRef(({ onReset, placeholder, wrapperClassName, ...props }, ref) => {
10482
- const { t } = useTranslation22();
10653
+ const { t } = useTranslation23();
10483
10654
  const placeholderText = placeholder || t("search_property") + "...";
10484
10655
  return /* @__PURE__ */ jsxs85("div", { className: cn("input-wrapper relative", wrapperClassName), children: [
10485
10656
  /* @__PURE__ */ jsx131(Search3, { className: "absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 transform text-[#9696B9]" }),
@@ -10547,6 +10718,9 @@ var SearchableSelectInternal = ({
10547
10718
  getValueLabel,
10548
10719
  disabled,
10549
10720
  error,
10721
+ invalid,
10722
+ optional,
10723
+ tooltip,
10550
10724
  hideErrorMessage,
10551
10725
  name,
10552
10726
  className,
@@ -10583,10 +10757,16 @@ var SearchableSelectInternal = ({
10583
10757
  );
10584
10758
  const helperText = placeholder ?? label;
10585
10759
  const valueLabel = value ? getValueLabel?.(value) ?? String(value.label) : void 0;
10760
+ const isBlocked = Boolean(disabled) || Boolean(loading);
10761
+ const triggerError = error ?? invalid;
10586
10762
  const describedBy = error && !hideErrorMessage ? errorId : void 0;
10587
10763
  const activeOptionId = highlightedIndex >= 0 ? getOptionId(reactId, highlightedIndex) : void 0;
10588
10764
  useOutsideClick(containerRef, open && !isMobile ? () => closeSelect() : null);
10589
10765
  React39.useEffect(() => {
10766
+ if (isBlocked) {
10767
+ setSelectOpen(false);
10768
+ return;
10769
+ }
10590
10770
  if (!open) return;
10591
10771
  const frameId = window.requestAnimationFrame(() => {
10592
10772
  inputRef.current?.focus();
@@ -10594,7 +10774,7 @@ var SearchableSelectInternal = ({
10594
10774
  return () => {
10595
10775
  window.cancelAnimationFrame(frameId);
10596
10776
  };
10597
- }, [open]);
10777
+ }, [isBlocked, open]);
10598
10778
  React39.useEffect(() => {
10599
10779
  if (!open) {
10600
10780
  setHighlightedIndex(-1);
@@ -10615,7 +10795,7 @@ var SearchableSelectInternal = ({
10615
10795
  }
10616
10796
  }
10617
10797
  function openSelect() {
10618
- if (disabled) return;
10798
+ if (isBlocked) return;
10619
10799
  setSelectOpen(true);
10620
10800
  }
10621
10801
  function closeSelect() {
@@ -10628,7 +10808,7 @@ var SearchableSelectInternal = ({
10628
10808
  onSearchChange?.(nextValue);
10629
10809
  }
10630
10810
  function handleSelect(option) {
10631
- if (disabled || option.isDisabled) return;
10811
+ if (isBlocked || option.isDisabled) return;
10632
10812
  onChange(option);
10633
10813
  setSelectOpen(false, { restoreFocus: true });
10634
10814
  }
@@ -10640,7 +10820,7 @@ var SearchableSelectInternal = ({
10640
10820
  }
10641
10821
  }
10642
10822
  function handleTriggerKeyDown(event) {
10643
- if (disabled) return;
10823
+ if (isBlocked) return;
10644
10824
  if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown" || event.key === "ArrowUp") {
10645
10825
  event.preventDefault();
10646
10826
  openSelect();
@@ -10719,7 +10899,11 @@ var SearchableSelectInternal = ({
10719
10899
  valueText: valueLabel,
10720
10900
  placeholder: helperText,
10721
10901
  describedBy,
10722
- error,
10902
+ error: triggerError,
10903
+ loading,
10904
+ optional,
10905
+ tooltip,
10906
+ forceLabelText: Boolean(optional) || Boolean(tooltip),
10723
10907
  hideErrorMessage,
10724
10908
  disabled,
10725
10909
  onClick: () => {
@@ -10746,6 +10930,7 @@ var SearchableSelectInternal = ({
10746
10930
  {
10747
10931
  open,
10748
10932
  onOpenChange: (nextOpen) => {
10933
+ if (isBlocked && nextOpen) return;
10749
10934
  if (nextOpen) {
10750
10935
  setSelectOpen(true);
10751
10936
  return;