@chekinapp/ui 0.0.115 → 0.0.117

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.cjs CHANGED
@@ -42,6 +42,7 @@ __export(index_exports, {
42
42
  AirbnbSearchInput: () => AirbnbSearchInput,
43
43
  AirbnbSearchableSelect: () => AirbnbSearchableSelect,
44
44
  AirbnbSelect: () => AirbnbSelect,
45
+ AirbnbSwitch: () => AirbnbSwitch,
45
46
  Alert: () => Alert,
46
47
  AlertBox: () => AlertBox,
47
48
  AlertDescription: () => AlertDescription,
@@ -5147,7 +5148,7 @@ function Header2({ children, className, ...props }) {
5147
5148
  "h2",
5148
5149
  {
5149
5150
  className: cn(
5150
- "m-0 flex items-center gap-2 self-stretch p-0 text-2xl font-semibold leading-normal text-[var(--chekin-color-brand-navy)]",
5151
+ "m-0 flex items-center gap-2 self-stretch p-0 text-2xl font-semibold leading-normal text-[var(--form-box-title-color)]",
5151
5152
  className
5152
5153
  ),
5153
5154
  ...props,
@@ -5163,7 +5164,7 @@ function Root11({ children, nested, className, ...props }) {
5163
5164
  "div",
5164
5165
  {
5165
5166
  className: cn(
5166
- "flex max-w-[1400px] flex-col items-start gap-6 self-stretch rounded-[10px] border border-[var(--chekin-color-gray-separator)] p-6 [container-type:inline-size]",
5167
+ "flex max-w-[1400px] flex-col items-start gap-6 self-stretch rounded-[var(--form-box-radius)] border border-[var(--form-box-border)] p-6 [container-type:inline-size]",
5167
5168
  nested && "border-0 p-0",
5168
5169
  className
5169
5170
  ),
@@ -5180,7 +5181,7 @@ function SubHeader({ children, className, ...props }) {
5180
5181
  "h4",
5181
5182
  {
5182
5183
  className: cn(
5183
- "m-0 flex items-center gap-2 self-stretch border-b border-[var(--chekin-color-gray-separator)] px-0 py-2 text-base font-semibold leading-normal text-[var(--chekin-color-brand-navy)]",
5184
+ "m-0 flex items-center gap-2 self-stretch border-b border-[var(--form-box-subtitle-border)] px-0 py-2 text-base font-semibold leading-normal text-[var(--form-box-subtitle-color)]",
5184
5185
  className
5185
5186
  ),
5186
5187
  ...props,
@@ -12871,6 +12872,23 @@ var React45 = __toESM(require("react"), 1);
12871
12872
  var import_react_i18next28 = require("react-i18next");
12872
12873
 
12873
12874
  // src/dashboard/_select-internals/utils.ts
12875
+ function isOptionGroup(item) {
12876
+ if (!item || typeof item !== "object") return false;
12877
+ if ("value" in item) return false;
12878
+ return Array.isArray(item.options);
12879
+ }
12880
+ function flattenGroupedOptions(items) {
12881
+ if (!items) return [];
12882
+ const result = [];
12883
+ for (const item of items) {
12884
+ if (isOptionGroup(item)) {
12885
+ for (const option of item.options) result.push(option);
12886
+ } else {
12887
+ result.push(item);
12888
+ }
12889
+ }
12890
+ return result;
12891
+ }
12874
12892
  function isOptionEnabled(option, isOptionDisabled) {
12875
12893
  if (!option) return false;
12876
12894
  if (option.isDisabled) return false;
@@ -12968,6 +12986,52 @@ function DefaultOption(props) {
12968
12986
 
12969
12987
  // src/dashboard/_select-internals/SelectMenu.tsx
12970
12988
  var import_jsx_runtime148 = require("react/jsx-runtime");
12989
+ function buildMenuEntries(groupedOptions, options, formatGroupLabel, listboxId) {
12990
+ if (!groupedOptions || !groupedOptions.some((item) => isOptionGroup(item))) {
12991
+ return options.map((option, index) => ({
12992
+ kind: "option",
12993
+ key: `${String(option.value)}-${index}`,
12994
+ option,
12995
+ flatIndex: index
12996
+ }));
12997
+ }
12998
+ const visibleValues = new Set(options.map((option) => option.value));
12999
+ const entries = [];
13000
+ let flatIndex = 0;
13001
+ let groupCount = 0;
13002
+ for (const item of groupedOptions) {
13003
+ if (isOptionGroup(item)) {
13004
+ const visible = [];
13005
+ for (const option of item.options) {
13006
+ if (!visibleValues.has(option.value)) continue;
13007
+ visible.push({
13008
+ key: `${String(option.value)}-${flatIndex}`,
13009
+ option,
13010
+ flatIndex
13011
+ });
13012
+ flatIndex += 1;
13013
+ }
13014
+ if (visible.length === 0) continue;
13015
+ entries.push({
13016
+ kind: "group",
13017
+ key: `__group-${groupCount}`,
13018
+ labelId: `${listboxId}-group-${groupCount}`,
13019
+ label: formatGroupLabel ? formatGroupLabel(item) : item.label,
13020
+ options: visible
13021
+ });
13022
+ groupCount += 1;
13023
+ } else if (visibleValues.has(item.value)) {
13024
+ entries.push({
13025
+ kind: "option",
13026
+ key: `${String(item.value)}-${flatIndex}`,
13027
+ option: item,
13028
+ flatIndex
13029
+ });
13030
+ flatIndex += 1;
13031
+ }
13032
+ }
13033
+ return entries;
13034
+ }
12971
13035
  function SelectMenu({
12972
13036
  id,
12973
13037
  options,
@@ -12993,7 +13057,9 @@ function SelectMenu({
12993
13057
  inputValue = "",
12994
13058
  formatOptionLabel,
12995
13059
  isOptionSelected: isOptionSelected2,
12996
- onMenuScrollToBottom
13060
+ onMenuScrollToBottom,
13061
+ groupedOptions,
13062
+ formatGroupLabel
12997
13063
  }) {
12998
13064
  const { t } = (0, import_react_i18next28.useTranslation)();
12999
13065
  const emptyMessage = noOptionsMessage?.() ?? t("no_options");
@@ -13004,6 +13070,38 @@ function SelectMenu({
13004
13070
  () => selectedValues ?? (selectedValue ? [selectedValue] : []),
13005
13071
  [selectedValues, selectedValue]
13006
13072
  );
13073
+ const entries = React45.useMemo(
13074
+ () => buildMenuEntries(groupedOptions, options, formatGroupLabel, id),
13075
+ [groupedOptions, options, formatGroupLabel, id]
13076
+ );
13077
+ const renderOption = (entry) => {
13078
+ const { option, flatIndex, key } = entry;
13079
+ const isSelected = isOptionSelected2 ? isOptionSelected2(option, selectedList) : isOptionSelected(option, selectedValue, selectedValues);
13080
+ const isHighlighted = flatIndex === highlightedIndex;
13081
+ const optionDisabled = Boolean(
13082
+ disabled || option.isDisabled || isOptionDisabled?.(option)
13083
+ );
13084
+ return /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
13085
+ Option,
13086
+ {
13087
+ id: getOptionId2(flatIndex),
13088
+ option,
13089
+ index: flatIndex,
13090
+ isSelected,
13091
+ isHighlighted,
13092
+ isDisabled: optionDisabled,
13093
+ isLast: flatIndex === lastIndex,
13094
+ isMulti: Boolean(isMulti),
13095
+ onClick: onOptionClick,
13096
+ onHover: onOptionHover ?? (() => void 0),
13097
+ innerRef: (node) => selectedOptionRef?.(flatIndex, node),
13098
+ inputValue,
13099
+ selectedOptions: selectedList,
13100
+ formatOptionLabel
13101
+ },
13102
+ key
13103
+ );
13104
+ };
13007
13105
  const wasAtBottomRef = React45.useRef(false);
13008
13106
  const handleScroll = React45.useCallback(
13009
13107
  (event) => {
@@ -13037,32 +13135,21 @@ function SelectMenu({
13037
13135
  ),
13038
13136
  children: [
13039
13137
  !hasOptions && (emptyContent ?? /* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { className: "px-3 py-3 text-left text-[14px] font-medium text-[var(--chekin-color-gray-1)]", children: emptyMessage })),
13040
- options.map((option, index) => {
13041
- const isSelected = isOptionSelected2 ? isOptionSelected2(option, selectedList) : isOptionSelected(option, selectedValue, selectedValues);
13042
- const isHighlighted = index === highlightedIndex;
13043
- const optionDisabled = Boolean(
13044
- disabled || option.isDisabled || isOptionDisabled?.(option)
13045
- );
13046
- return /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
13047
- Option,
13048
- {
13049
- id: getOptionId2(index),
13050
- option,
13051
- index,
13052
- isSelected,
13053
- isHighlighted,
13054
- isDisabled: optionDisabled,
13055
- isLast: index === lastIndex,
13056
- isMulti: Boolean(isMulti),
13057
- onClick: onOptionClick,
13058
- onHover: onOptionHover ?? (() => void 0),
13059
- innerRef: (node) => selectedOptionRef?.(index, node),
13060
- inputValue,
13061
- selectedOptions: selectedList,
13062
- formatOptionLabel
13063
- },
13064
- `${String(option.value)}-${index}`
13065
- );
13138
+ entries.map((entry) => {
13139
+ if (entry.kind === "group") {
13140
+ return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { role: "group", "aria-labelledby": entry.labelId, children: [
13141
+ /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
13142
+ "div",
13143
+ {
13144
+ id: entry.labelId,
13145
+ className: "px-3 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-[var(--chekin-color-gray-1)]",
13146
+ children: entry.label
13147
+ }
13148
+ ),
13149
+ entry.options.map(renderOption)
13150
+ ] }, entry.key);
13151
+ }
13152
+ return renderOption(entry);
13066
13153
  }),
13067
13154
  footer
13068
13155
  ]
@@ -13991,7 +14078,9 @@ function DefaultMenuList(props) {
13991
14078
  inputValue,
13992
14079
  formatOptionLabel,
13993
14080
  isOptionSelected: isOptionSelected2,
13994
- onMenuScrollToBottom
14081
+ onMenuScrollToBottom,
14082
+ groupedOptions,
14083
+ formatGroupLabel
13995
14084
  } = props;
13996
14085
  return /* @__PURE__ */ (0, import_jsx_runtime156.jsx)(
13997
14086
  SelectMenu,
@@ -14019,7 +14108,9 @@ function DefaultMenuList(props) {
14019
14108
  inputValue,
14020
14109
  formatOptionLabel,
14021
14110
  isOptionSelected: isOptionSelected2,
14022
- onMenuScrollToBottom
14111
+ onMenuScrollToBottom,
14112
+ groupedOptions,
14113
+ formatGroupLabel
14023
14114
  }
14024
14115
  );
14025
14116
  }
@@ -14111,7 +14202,8 @@ function SelectInternal(props, ref) {
14111
14202
  searchPosition = "trigger",
14112
14203
  menuHeader,
14113
14204
  onMenuScrollToBottom,
14114
- leftIcon
14205
+ leftIcon,
14206
+ formatGroupLabel
14115
14207
  } = props;
14116
14208
  const isSearchInDropdown = searchPosition === "dropdown";
14117
14209
  const isMulti = props.isMulti === true;
@@ -14132,9 +14224,10 @@ function SelectInternal(props, ref) {
14132
14224
  },
14133
14225
  [isMulti, props.onChange]
14134
14226
  );
14227
+ const flatOptions = React49.useMemo(() => flattenGroupedOptions(options), [options]);
14135
14228
  const state = useSelectState({
14136
14229
  isMulti,
14137
- options,
14230
+ options: flatOptions,
14138
14231
  selectedOptions,
14139
14232
  onSelectionChange,
14140
14233
  filterOption,
@@ -14305,7 +14398,9 @@ function SelectInternal(props, ref) {
14305
14398
  inputValue: state.inputValue,
14306
14399
  formatOptionLabel,
14307
14400
  isOptionSelected: isOptionSelected2,
14308
- onMenuScrollToBottom
14401
+ onMenuScrollToBottom,
14402
+ groupedOptions: options,
14403
+ formatGroupLabel
14309
14404
  }
14310
14405
  ),
14311
14406
  state.canCreateNewOption && /* @__PURE__ */ (0, import_jsx_runtime158.jsx)(
@@ -15059,13 +15154,7 @@ function createCountTrigger(opts) {
15059
15154
 
15060
15155
  // src/dashboard/select-checkboxes/SelectAllRow.tsx
15061
15156
  var import_jsx_runtime169 = require("react/jsx-runtime");
15062
- function SelectAllRow({
15063
- label,
15064
- checked,
15065
- indeterminate,
15066
- disabled,
15067
- onToggle
15068
- }) {
15157
+ function SelectAllRow({ label, checked, disabled, onToggle }) {
15069
15158
  return /* @__PURE__ */ (0, import_jsx_runtime169.jsxs)(
15070
15159
  "button",
15071
15160
  {
@@ -15080,7 +15169,7 @@ function SelectAllRow({
15080
15169
  /* @__PURE__ */ (0, import_jsx_runtime169.jsx)(
15081
15170
  BaseCheckbox,
15082
15171
  {
15083
- checked: indeterminate ? "indeterminate" : checked,
15172
+ checked,
15084
15173
  disabled,
15085
15174
  size: "s",
15086
15175
  tabIndex: -1,
@@ -15116,7 +15205,6 @@ function SelectCheckboxesInternal(props, ref) {
15116
15205
  allowSelectAll = false,
15117
15206
  selectAllLabel,
15118
15207
  searchable = true,
15119
- searchPlaceholder,
15120
15208
  filterOption = defaultFilterOption,
15121
15209
  closeMenuOnSelect = false,
15122
15210
  onSearchChange,
@@ -15128,19 +15216,32 @@ function SelectCheckboxesInternal(props, ref) {
15128
15216
  );
15129
15217
  const [inputValue, setInputValue] = React59.useState("");
15130
15218
  const selected = value ?? [];
15131
- const filteredOptions = React59.useMemo(() => {
15219
+ const flatRawOptions = React59.useMemo(
15220
+ () => flattenGroupedOptions(rawOptions),
15221
+ [rawOptions]
15222
+ );
15223
+ const filteredGrouped = React59.useMemo(() => {
15132
15224
  const trimmed = inputValue.trim();
15133
15225
  if (!trimmed) return rawOptions;
15134
- return rawOptions.filter((option) => filterOption(option, trimmed));
15226
+ return rawOptions.map((item) => {
15227
+ if (isOptionGroup(item)) {
15228
+ const opts = item.options.filter((o) => filterOption(o, trimmed));
15229
+ return opts.length > 0 ? { ...item, options: opts } : null;
15230
+ }
15231
+ return filterOption(item, trimmed) ? item : null;
15232
+ }).filter((item) => item !== null);
15135
15233
  }, [rawOptions, inputValue, filterOption]);
15136
- const visibleSelectedCount = filteredOptions.reduce((acc, option) => {
15234
+ const filteredFlat = React59.useMemo(
15235
+ () => flattenGroupedOptions(filteredGrouped),
15236
+ [filteredGrouped]
15237
+ );
15238
+ const visibleSelectedCount = filteredFlat.reduce((acc, option) => {
15137
15239
  return acc + (selected.some((s) => s.value === option.value) ? 1 : 0);
15138
15240
  }, 0);
15139
- const allVisibleSelected = filteredOptions.length > 0 && visibleSelectedCount === filteredOptions.length;
15140
- const someVisibleSelected = visibleSelectedCount > 0 && visibleSelectedCount < filteredOptions.length;
15241
+ const allVisibleSelected = filteredFlat.length > 0 && visibleSelectedCount === filteredFlat.length;
15141
15242
  const handleToggleAll = React59.useCallback(() => {
15142
15243
  if (allVisibleSelected) {
15143
- const visibleValues = new Set(filteredOptions.map((option) => option.value));
15244
+ const visibleValues = new Set(filteredFlat.map((option) => option.value));
15144
15245
  onChange(
15145
15246
  selected.filter((s) => !visibleValues.has(s.value)),
15146
15247
  { action: "deselect" }
@@ -15148,18 +15249,18 @@ function SelectCheckboxesInternal(props, ref) {
15148
15249
  return;
15149
15250
  }
15150
15251
  const merged = [...selected];
15151
- for (const option of filteredOptions) {
15252
+ for (const option of filteredFlat) {
15152
15253
  if (!merged.some((s) => s.value === option.value)) merged.push(option);
15153
15254
  }
15154
15255
  onChange(merged, { action: "select" });
15155
- }, [allVisibleSelected, filteredOptions, onChange, selected]);
15256
+ }, [allVisibleSelected, filteredFlat, onChange, selected]);
15156
15257
  const Control = React59.useMemo(() => {
15157
15258
  if (trigger) return makeTriggerSlot2(trigger);
15158
15259
  return createCountTrigger({
15159
15260
  valueText,
15160
- totalCount: rawOptions.length
15261
+ totalCount: flatRawOptions.length
15161
15262
  });
15162
- }, [trigger, valueText, rawOptions.length]);
15263
+ }, [trigger, valueText, flatRawOptions.length]);
15163
15264
  const components = React59.useMemo(
15164
15265
  () => ({
15165
15266
  ...userComponents,
@@ -15173,7 +15274,6 @@ function SelectCheckboxesInternal(props, ref) {
15173
15274
  {
15174
15275
  label: selectAllLabel ?? t("select_all", { defaultValue: "Select All" }),
15175
15276
  checked: allVisibleSelected,
15176
- indeterminate: someVisibleSelected,
15177
15277
  onToggle: handleToggleAll
15178
15278
  }
15179
15279
  ) : void 0;
@@ -15184,11 +15284,10 @@ function SelectCheckboxesInternal(props, ref) {
15184
15284
  },
15185
15285
  [onSearchChange]
15186
15286
  );
15187
- const sharedProps = {
15287
+ const baseSharedProps = {
15188
15288
  ...paginationAndRest,
15189
15289
  value,
15190
15290
  onChange,
15191
- options: filteredOptions,
15192
15291
  filterOption: passthroughFilter2,
15193
15292
  components,
15194
15293
  closeMenuOnSelect,
@@ -15202,7 +15301,10 @@ function SelectCheckboxesInternal(props, ref) {
15202
15301
  InfiniteScrollSelect,
15203
15302
  {
15204
15303
  ref,
15205
- ...sharedProps
15304
+ ...{
15305
+ ...baseSharedProps,
15306
+ options: filteredFlat
15307
+ }
15206
15308
  }
15207
15309
  );
15208
15310
  }
@@ -15210,7 +15312,10 @@ function SelectCheckboxesInternal(props, ref) {
15210
15312
  Select,
15211
15313
  {
15212
15314
  ref,
15213
- ...sharedProps
15315
+ ...{
15316
+ ...baseSharedProps,
15317
+ options: filteredGrouped
15318
+ }
15214
15319
  }
15215
15320
  );
15216
15321
  }
@@ -16133,7 +16238,7 @@ var Datepicker = React63.forwardRef(
16133
16238
  hideErrorMessage,
16134
16239
  helperText,
16135
16240
  width,
16136
- locale = "en-US",
16241
+ locale,
16137
16242
  minDate,
16138
16243
  maxDate,
16139
16244
  formatValue
@@ -16152,10 +16257,11 @@ var Datepicker = React63.forwardRef(
16152
16257
  const yearId = `${baseId}-year`;
16153
16258
  const labelId = `${baseId}-label`;
16154
16259
  const errorId = `${baseId}-error`;
16155
- const { t } = (0, import_react_i18next39.useTranslation)();
16260
+ const { t, i18n } = (0, import_react_i18next39.useTranslation)();
16261
+ const resolvedLocale = locale ?? i18n.resolvedLanguage ?? i18n.language ?? "en-US";
16156
16262
  const resolvedMonthLabels = React63.useMemo(
16157
- () => monthLabels ?? getMonthLabels2(locale),
16158
- [locale, monthLabels]
16263
+ () => monthLabels ?? getMonthLabels2(resolvedLocale),
16264
+ [resolvedLocale, monthLabels]
16159
16265
  );
16160
16266
  const resolvedMonthPlaceholder = monthPlaceholder ?? t("month");
16161
16267
  const resolvedDoneLabel = doneLabel ?? t("done");
@@ -17954,7 +18060,7 @@ var AirbnbFieldTrigger = React72.forwardRef(
17954
18060
  const hasLabelMeta = Boolean(optionalLabel) || Boolean(tooltip);
17955
18061
  const resolvedLabelText = visibleLabelText && hasLabelMeta ? /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)("span", { className: "inline-flex max-w-full items-center gap-1.5 align-middle", children: [
17956
18062
  /* @__PURE__ */ (0, import_jsx_runtime184.jsx)("span", { className: "min-w-0 truncate", children: visibleLabelText }),
17957
- optionalLabel && /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)("span", { className: "shrink-0 text-[12px] relative top-[1px] font-normal leading-4 text-current opacity-70", children: [
18063
+ optionalLabel && /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)("span", { className: "text-current opacity-70 lowercase", children: [
17958
18064
  "(",
17959
18065
  optionalLabel,
17960
18066
  ")"
@@ -18008,8 +18114,8 @@ var AirbnbFieldTrigger = React72.forwardRef(
18008
18114
  {
18009
18115
  id: labelId,
18010
18116
  className: cn(
18011
- "absolute left-0 origin-left truncate transition-all duration-200 ease-out",
18012
- hasLabelMeta ? "" : "pointer-events-none",
18117
+ "absolute left-0 origin-left transition-all duration-200 ease-out",
18118
+ hasLabelMeta ? "max-w-full" : "pointer-events-none truncate",
18013
18119
  isAirbnbVariant ? isRaised ? "top-[-1px] 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-white px-1 text-[12px] font-medium leading-4" : "top-1/2 -translate-y-1/2 text-[16px] leading-6",
18014
18120
  hasInvalidState ? "text-[var(--error-message-color)]" : isAirbnbVariant ? "text-[#6c6c6c]" : "text-[#7A8399]"
18015
18121
  ),
@@ -18277,6 +18383,8 @@ AirbnbDatePicker.displayName = "AirbnbDatePicker";
18277
18383
 
18278
18384
  // src/airbnb-fields/input/Input.tsx
18279
18385
  var React74 = __toESM(require("react"), 1);
18386
+ var import_lucide_react54 = require("lucide-react");
18387
+ var import_react_i18next44 = require("react-i18next");
18280
18388
  var import_jsx_runtime186 = require("react/jsx-runtime");
18281
18389
  var getInputValue = (value) => value != null ? String(value) : "";
18282
18390
  var AirbnbInput = React74.forwardRef(
@@ -18308,6 +18416,7 @@ var AirbnbInput = React74.forwardRef(
18308
18416
  placeholder,
18309
18417
  ...props
18310
18418
  }, ref) => {
18419
+ const { t } = (0, import_react_i18next44.useTranslation)();
18311
18420
  const generatedId = React74.useId();
18312
18421
  const inputRef = React74.useRef(null);
18313
18422
  const inputId = id ?? generatedId;
@@ -18316,11 +18425,15 @@ var AirbnbInput = React74.forwardRef(
18316
18425
  const errorId = `${inputId}-error`;
18317
18426
  const accessibleLabel = placeholder ?? label;
18318
18427
  const [isFocused, setIsFocused] = React74.useState(false);
18428
+ const [isPasswordRevealed, setIsPasswordRevealed] = React74.useState(false);
18319
18429
  const [currentValue, setCurrentValue] = React74.useState(
18320
18430
  () => value != null ? getInputValue(value) : getInputValue(defaultValue)
18321
18431
  );
18322
18432
  const resolvedValue = value != null ? getInputValue(value) : currentValue;
18323
18433
  const hasValue = resolvedValue.length > 0;
18434
+ const isPasswordInput = type === "password";
18435
+ const inputType = isPasswordInput && isPasswordRevealed ? "text" : type;
18436
+ const shouldShowPasswordReveal = isPasswordInput && hasValue && !loading;
18324
18437
  const shouldShowLabel = hasValue || isFocused;
18325
18438
  const hasInvalidState = Boolean(error) || Boolean(invalid);
18326
18439
  const triggerError = error ?? invalid;
@@ -18330,6 +18443,11 @@ var AirbnbInput = React74.forwardRef(
18330
18443
  const nextValue = value != null ? getInputValue(value) : getInputValue(inputRef.current?.value);
18331
18444
  setCurrentValue((prevValue) => prevValue === nextValue ? prevValue : nextValue);
18332
18445
  }, [value]);
18446
+ React74.useEffect(() => {
18447
+ if (!isPasswordInput) {
18448
+ setIsPasswordRevealed(false);
18449
+ }
18450
+ }, [isPasswordInput]);
18333
18451
  const setRefs = React74.useCallback(
18334
18452
  (node) => {
18335
18453
  inputRef.current = node;
@@ -18360,7 +18478,10 @@ var AirbnbInput = React74.forwardRef(
18360
18478
  setIsFocused(false);
18361
18479
  onBlur?.(event);
18362
18480
  };
18363
- return /* @__PURE__ */ (0, import_jsx_runtime186.jsx)("div", { className: cn("w-full max-w-[var(--max-field-width)]", wrapperClassName), children: /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(
18481
+ const togglePasswordReveal = () => {
18482
+ setIsPasswordRevealed((isRevealed) => !isRevealed);
18483
+ };
18484
+ return /* @__PURE__ */ (0, import_jsx_runtime186.jsx)("div", { className: cn("w-full max-w-[var(--max-field-width)]", wrapperClassName), children: /* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(
18364
18485
  AirbnbFieldTrigger,
18365
18486
  {
18366
18487
  as: "div",
@@ -18388,39 +18509,63 @@ var AirbnbInput = React74.forwardRef(
18388
18509
  variant === "airbnb" ? "h-[42px]" : "h-[48px]",
18389
18510
  contentClassName
18390
18511
  ),
18391
- trailingAdornment,
18512
+ trailingAdornment: shouldShowPasswordReveal ? void 0 : trailingAdornment,
18392
18513
  forceFloatingLabel: shouldShowLabel,
18393
18514
  forceLabelText: hasLabelMeta,
18394
18515
  hideErrorMessage: !renderErrorMessage,
18395
- children: /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(
18396
- "input",
18397
- {
18398
- ...props,
18399
- id: inputId,
18400
- ref: setRefs,
18401
- type,
18402
- disabled: isBlocked,
18403
- value,
18404
- defaultValue,
18405
- onChange: handleChange,
18406
- onFocus: handleFocus,
18407
- onBlur: handleBlur,
18408
- placeholder: "",
18409
- "aria-invalid": hasInvalidState,
18410
- "aria-busy": loading,
18411
- "aria-describedby": error && renderErrorMessage ? errorId : void 0,
18412
- "aria-label": accessibleLabel && hasLabelMeta ? accessibleLabel : void 0,
18413
- "aria-labelledby": accessibleLabel && !hasLabelMeta ? labelId : void 0,
18414
- className: cn(
18415
- "absolute left-0 h-6 w-full border-0 bg-transparent p-0 text-[16px] leading-6 text-[#1F1F1B] outline-none placeholder:text-[#7A8399]",
18416
- variant === "airbnb" ? "bottom-0" : "bottom-[12px]",
18417
- hasInvalidState ? "text-[var(--status-danger)] placeholder:text-[var(--status-danger)]" : "",
18418
- disabled ? "cursor-not-allowed" : loading ? "cursor-progress" : "",
18419
- inputClassName,
18420
- className
18421
- )
18422
- }
18423
- )
18516
+ children: [
18517
+ /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(
18518
+ "input",
18519
+ {
18520
+ ...props,
18521
+ id: inputId,
18522
+ ref: setRefs,
18523
+ type: inputType,
18524
+ disabled: isBlocked,
18525
+ value,
18526
+ defaultValue,
18527
+ onChange: handleChange,
18528
+ onFocus: handleFocus,
18529
+ onBlur: handleBlur,
18530
+ placeholder: "",
18531
+ "aria-invalid": hasInvalidState,
18532
+ "aria-busy": loading,
18533
+ "aria-describedby": error && renderErrorMessage ? errorId : void 0,
18534
+ "aria-label": accessibleLabel && hasLabelMeta ? accessibleLabel : void 0,
18535
+ "aria-labelledby": accessibleLabel && !hasLabelMeta ? labelId : void 0,
18536
+ className: cn(
18537
+ "absolute left-0 h-6 w-full border-0 bg-transparent p-0 text-[16px] leading-6 text-[#1F1F1B] outline-none placeholder:text-[#7A8399]",
18538
+ variant === "airbnb" ? "bottom-0" : "bottom-[12px]",
18539
+ hasInvalidState ? "text-[var(--status-danger)] placeholder:text-[var(--status-danger)]" : "",
18540
+ disabled ? "cursor-not-allowed" : loading ? "cursor-progress" : "",
18541
+ shouldShowPasswordReveal ? "pr-8" : "",
18542
+ inputClassName,
18543
+ className
18544
+ )
18545
+ }
18546
+ ),
18547
+ shouldShowPasswordReveal && /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(
18548
+ "button",
18549
+ {
18550
+ type: "button",
18551
+ onClick: togglePasswordReveal,
18552
+ disabled: isBlocked,
18553
+ className: cn(
18554
+ "absolute right-0 flex h-6 w-6 items-center justify-center border-0 bg-transparent p-0 text-[#7A8399] hover:text-[#1F1F1B] hover:opacity-85 disabled:cursor-not-allowed disabled:opacity-50",
18555
+ variant === "airbnb" ? "bottom-0" : "bottom-[12px]"
18556
+ ),
18557
+ "aria-label": isPasswordRevealed ? t("hide_password") : t("show_password"),
18558
+ children: /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(
18559
+ import_lucide_react54.Eye,
18560
+ {
18561
+ size: 18,
18562
+ "aria-hidden": "true",
18563
+ className: cn(isPasswordRevealed ? "text-[#fc98dd]" : "")
18564
+ }
18565
+ )
18566
+ }
18567
+ )
18568
+ ]
18424
18569
  }
18425
18570
  ) });
18426
18571
  }
@@ -18429,7 +18574,7 @@ AirbnbInput.displayName = "AirbnbInput";
18429
18574
 
18430
18575
  // src/airbnb-fields/phone-field/PhoneField.tsx
18431
18576
  var React80 = __toESM(require("react"), 1);
18432
- var import_lucide_react55 = require("lucide-react");
18577
+ var import_lucide_react56 = require("lucide-react");
18433
18578
 
18434
18579
  // src/airbnb-fields/select/Select.tsx
18435
18580
  var React79 = __toESM(require("react"), 1);
@@ -18778,7 +18923,7 @@ function AirbnbSelectMobileContent({
18778
18923
 
18779
18924
  // src/airbnb-fields/select/SelectTrigger.tsx
18780
18925
  var React75 = __toESM(require("react"), 1);
18781
- var import_lucide_react54 = require("lucide-react");
18926
+ var import_lucide_react55 = require("lucide-react");
18782
18927
  var import_jsx_runtime191 = require("react/jsx-runtime");
18783
18928
  var AirbnbSelectTrigger = React75.forwardRef(
18784
18929
  ({
@@ -18835,7 +18980,7 @@ var AirbnbSelectTrigger = React75.forwardRef(
18835
18980
  onKeyDown,
18836
18981
  onBlur,
18837
18982
  trailingAdornment: /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(
18838
- import_lucide_react54.ChevronDown,
18983
+ import_lucide_react55.ChevronDown,
18839
18984
  {
18840
18985
  className: open ? "h-6 w-6 rotate-180 text-[#1F1F1B] transition-transform" : "h-6 w-6 text-[#1F1F1B] transition-transform"
18841
18986
  }
@@ -19622,7 +19767,7 @@ var AirbnbPhoneField = React80.forwardRef(
19622
19767
  children: [
19623
19768
  /* @__PURE__ */ (0, import_jsx_runtime193.jsx)("span", { children: valueLabel ?? codePlaceholder }),
19624
19769
  /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(
19625
- import_lucide_react55.ChevronDown,
19770
+ import_lucide_react56.ChevronDown,
19626
19771
  {
19627
19772
  className: cn("h-5 w-5 transition-transform", open ? "rotate-180" : ""),
19628
19773
  strokeWidth: 2
@@ -19673,7 +19818,7 @@ AirbnbPhoneField.displayName = "AirbnbPhoneField";
19673
19818
 
19674
19819
  // src/airbnb-fields/searchable-select/SearchableSelect.tsx
19675
19820
  var React81 = __toESM(require("react"), 1);
19676
- var import_lucide_react56 = require("lucide-react");
19821
+ var import_lucide_react57 = require("lucide-react");
19677
19822
  var import_react_virtual3 = require("@tanstack/react-virtual");
19678
19823
  var import_react90 = require("react");
19679
19824
  var import_jsx_runtime194 = require("react/jsx-runtime");
@@ -19911,7 +20056,7 @@ var AirbnbSearchableSelectInternal = ({
19911
20056
  onKeyDown: handleTriggerKeyDown,
19912
20057
  onBlur,
19913
20058
  trailingAdornment: /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(
19914
- import_lucide_react56.ChevronDown,
20059
+ import_lucide_react57.ChevronDown,
19915
20060
  {
19916
20061
  className: cn(
19917
20062
  "h-6 w-6 text-[#1F1F1B] transition-transform",
@@ -20009,7 +20154,7 @@ function AirbnbSearchableSelectContent({
20009
20154
  return /* @__PURE__ */ (0, import_jsx_runtime194.jsxs)("div", { className: "p-2", children: [
20010
20155
  /* @__PURE__ */ (0, import_jsx_runtime194.jsxs)("div", { className: "relative mb-2", children: [
20011
20156
  /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(
20012
- import_lucide_react56.Search,
20157
+ import_lucide_react57.Search,
20013
20158
  {
20014
20159
  "aria-hidden": "true",
20015
20160
  className: "absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 text-[#9696B9]"
@@ -20118,14 +20263,14 @@ function getNextEnabledIndex(options, startIndex, step) {
20118
20263
 
20119
20264
  // src/airbnb-fields/search-input/SearchInput.tsx
20120
20265
  var React82 = __toESM(require("react"), 1);
20121
- var import_react_i18next44 = require("react-i18next");
20122
- var import_lucide_react57 = require("lucide-react");
20266
+ var import_react_i18next45 = require("react-i18next");
20267
+ var import_lucide_react58 = require("lucide-react");
20123
20268
  var import_jsx_runtime195 = require("react/jsx-runtime");
20124
20269
  var AirbnbSearchInput = React82.forwardRef(({ onReset, placeholder, wrapperClassName, ...props }, ref) => {
20125
- const { t } = (0, import_react_i18next44.useTranslation)();
20270
+ const { t } = (0, import_react_i18next45.useTranslation)();
20126
20271
  const placeholderText = placeholder || t("search_property") + "...";
20127
20272
  return /* @__PURE__ */ (0, import_jsx_runtime195.jsxs)("div", { className: cn("input-wrapper relative", wrapperClassName), children: [
20128
- /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(import_lucide_react57.Search, { className: "absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 transform text-[#9696B9]" }),
20273
+ /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(import_lucide_react58.Search, { className: "absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 transform text-[#9696B9]" }),
20129
20274
  /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(
20130
20275
  "input",
20131
20276
  {
@@ -20151,12 +20296,72 @@ var AirbnbSearchInput = React82.forwardRef(({ onReset, placeholder, wrapperClass
20151
20296
  variant: "ghost",
20152
20297
  onClick: onReset,
20153
20298
  className: "absolute right-0 top-1/2 h-5 w-5 -translate-y-1/2 transform text-[#9696B9]",
20154
- children: /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(import_lucide_react57.X, { className: "h-5 w-5" })
20299
+ children: /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(import_lucide_react58.X, { className: "h-5 w-5" })
20155
20300
  }
20156
20301
  )
20157
20302
  ] });
20158
20303
  });
20159
20304
  AirbnbSearchInput.displayName = "AirbnbSearchInput";
20305
+
20306
+ // src/airbnb-fields/switch/Switch.tsx
20307
+ var React83 = __toESM(require("react"), 1);
20308
+ var SwitchPrimitives2 = __toESM(require("@radix-ui/react-switch"), 1);
20309
+ var import_lucide_react59 = require("lucide-react");
20310
+ var import_jsx_runtime196 = require("react/jsx-runtime");
20311
+ var AirbnbSwitch = React83.forwardRef(({ className, value, onChange, disabled, loading, readOnly, id, label, error, wrapperClassName, ...props }, ref) => {
20312
+ const generatedId = React83.useId();
20313
+ const fieldId = id || generatedId;
20314
+ const switchElement = /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(
20315
+ SwitchPrimitives2.Root,
20316
+ {
20317
+ ref,
20318
+ className: cn(
20319
+ "group inline-flex h-[24px] w-[36px] shrink-0 cursor-pointer items-center rounded-full border border-solid border-transparent p-[2px] transition-colors duration-200",
20320
+ "focus-visible:outline-none focus-visible:shadow-[var(--chekin-shadow-focus)]",
20321
+ "disabled:cursor-not-allowed disabled:opacity-50 aria-busy:cursor-wait aria-busy:opacity-50",
20322
+ "aria-readonly:cursor-default aria-readonly:opacity-100",
20323
+ "data-[state=checked]:bg-[#222222] data-[state=unchecked]:bg-[#E7E7E4]",
20324
+ className
20325
+ ),
20326
+ id: fieldId,
20327
+ disabled,
20328
+ checked: value,
20329
+ value: String(value),
20330
+ onCheckedChange: !disabled && !readOnly ? onChange : void 0,
20331
+ "aria-busy": loading,
20332
+ "aria-readonly": readOnly,
20333
+ ...props,
20334
+ children: /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(
20335
+ SwitchPrimitives2.Thumb,
20336
+ {
20337
+ className: cn(
20338
+ "flex h-[20px] w-[20px] items-center justify-center rounded-full bg-white shadow-[0_1px_3px_rgba(0,0,0,0.22)] transition-transform duration-200",
20339
+ "data-[state=checked]:translate-x-[12px] data-[state=unchecked]:translate-x-0"
20340
+ ),
20341
+ children: /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(
20342
+ import_lucide_react59.Check,
20343
+ {
20344
+ "aria-hidden": "true",
20345
+ className: "h-3 w-3 text-[#222222] opacity-0 transition-opacity duration-150 group-data-[state=checked]:opacity-100",
20346
+ strokeWidth: 3
20347
+ }
20348
+ )
20349
+ }
20350
+ )
20351
+ }
20352
+ );
20353
+ if (!label && !error) {
20354
+ return switchElement;
20355
+ }
20356
+ return /* @__PURE__ */ (0, import_jsx_runtime196.jsxs)(import_jsx_runtime196.Fragment, { children: [
20357
+ /* @__PURE__ */ (0, import_jsx_runtime196.jsxs)("div", { className: cn("flex items-center gap-x-3 gap-y-1.5", wrapperClassName), children: [
20358
+ switchElement,
20359
+ label && /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(Label, { htmlFor: fieldId, className: "cursor-pointer text-base font-medium", children: label })
20360
+ ] }),
20361
+ error && /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(ErrorMessage, { disabled, children: error })
20362
+ ] });
20363
+ });
20364
+ AirbnbSwitch.displayName = "AirbnbSwitch";
20160
20365
  // Annotate the CommonJS export names for ESM import in node:
20161
20366
  0 && (module.exports = {
20162
20367
  ALERT_BOX_VARIANTS,
@@ -20171,6 +20376,7 @@ AirbnbSearchInput.displayName = "AirbnbSearchInput";
20171
20376
  AirbnbSearchInput,
20172
20377
  AirbnbSearchableSelect,
20173
20378
  AirbnbSelect,
20379
+ AirbnbSwitch,
20174
20380
  Alert,
20175
20381
  AlertBox,
20176
20382
  AlertDescription,