@onesaz/ui 0.3.3 → 0.3.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
@@ -866,7 +866,7 @@ Caption.displayName = "Caption";
866
866
  import * as React6 from "react";
867
867
  import { jsx as jsx6 } from "react/jsx-runtime";
868
868
  var Button = React6.forwardRef(
869
- ({ className, variant = "default", size = "default", ...props }, ref) => {
869
+ ({ className, variant = "default", size = "default", fullWidth = false, ...props }, ref) => {
870
870
  return /* @__PURE__ */ jsx6(
871
871
  "button",
872
872
  {
@@ -888,6 +888,7 @@ var Button = React6.forwardRef(
888
888
  "h-11 rounded-md px-8": size === "lg",
889
889
  "h-10 w-10": size === "icon"
890
890
  },
891
+ fullWidth && "w-full",
891
892
  className
892
893
  ),
893
894
  ref,
@@ -941,7 +942,16 @@ var sizeClasses = {
941
942
  lg: "h-12 text-base px-4"
942
943
  };
943
944
  var Input = React7.forwardRef(
944
- ({ className, type, inputSize = "md", error, startAdornment, endAdornment, ...props }, ref) => {
945
+ ({
946
+ className,
947
+ type,
948
+ inputSize = "md",
949
+ error,
950
+ startAdornment,
951
+ endAdornment,
952
+ containerClassName,
953
+ ...props
954
+ }, ref) => {
945
955
  const hasAdornment = startAdornment || endAdornment;
946
956
  if (hasAdornment) {
947
957
  return /* @__PURE__ */ jsxs(
@@ -952,7 +962,8 @@ var Input = React7.forwardRef(
952
962
  "bg-background",
953
963
  error ? "border-destructive focus-within:ring-2 focus-within:ring-destructive/20" : "border-input focus-within:ring-2 focus-within:ring-ring/20 focus-within:border-ring",
954
964
  "transition-colors",
955
- props.disabled && "opacity-50 cursor-not-allowed bg-muted"
965
+ props.disabled && "opacity-50 cursor-not-allowed bg-muted",
966
+ containerClassName
956
967
  ),
957
968
  children: [
958
969
  startAdornment && /* @__PURE__ */ jsx7("div", { className: "flex items-center pl-3 text-muted-foreground", children: startAdornment }),
@@ -1075,7 +1086,7 @@ var Label = React10.forwardRef(
1075
1086
  Label.displayName = "Label";
1076
1087
 
1077
1088
  // src/components/text-field.tsx
1078
- import { jsx as jsx11, jsxs as jsxs2 } from "react/jsx-runtime";
1089
+ import { Fragment, jsx as jsx11, jsxs as jsxs2 } from "react/jsx-runtime";
1079
1090
  var TextField = React11.forwardRef(
1080
1091
  ({
1081
1092
  className,
@@ -1089,12 +1100,39 @@ var TextField = React11.forwardRef(
1089
1100
  error,
1090
1101
  startAdornment,
1091
1102
  endAdornment,
1103
+ inputProps,
1104
+ InputProps,
1105
+ InputLabelProps,
1106
+ inputRef,
1092
1107
  ...props
1093
1108
  }, ref) => {
1094
1109
  const generatedId = React11.useId();
1095
1110
  const id = idProp || generatedId;
1096
1111
  const helperId = `${id}-helper`;
1097
1112
  const hasError = error || !!errorMessage;
1113
+ const mergedRef = (node) => {
1114
+ if (typeof ref === "function") ref(node);
1115
+ else if (ref) ref.current = node;
1116
+ if (typeof inputRef === "function") inputRef(node);
1117
+ else if (inputRef) inputRef.current = node;
1118
+ };
1119
+ const { className: inputPropsClassName, ...restInputProps } = inputProps ?? {};
1120
+ const {
1121
+ className: inputSlotClassName,
1122
+ containerClassName,
1123
+ startAdornment: inputSlotStart,
1124
+ endAdornment: inputSlotEnd,
1125
+ ...restInputSlotProps
1126
+ } = InputProps ?? {};
1127
+ const resolvedStartAdornment = inputSlotStart ? /* @__PURE__ */ jsxs2(Fragment, { children: [
1128
+ inputSlotStart,
1129
+ startAdornment
1130
+ ] }) : startAdornment;
1131
+ const resolvedEndAdornment = inputSlotEnd ? /* @__PURE__ */ jsxs2(Fragment, { children: [
1132
+ endAdornment,
1133
+ inputSlotEnd
1134
+ ] }) : endAdornment;
1135
+ const resolvedSize = size === "small" ? "sm" : size === "medium" ? "md" : size;
1098
1136
  return /* @__PURE__ */ jsxs2("div", { className: cn("grid gap-1.5", fullWidth && "w-full", className), children: [
1099
1137
  label && /* @__PURE__ */ jsxs2(
1100
1138
  Label,
@@ -1104,6 +1142,7 @@ var TextField = React11.forwardRef(
1104
1142
  "text-sm font-medium",
1105
1143
  hasError && "text-destructive"
1106
1144
  ),
1145
+ ...InputLabelProps,
1107
1146
  children: [
1108
1147
  label,
1109
1148
  required && /* @__PURE__ */ jsx11("span", { className: "text-destructive ml-0.5", "aria-hidden": "true", children: "*" })
@@ -1113,15 +1152,19 @@ var TextField = React11.forwardRef(
1113
1152
  /* @__PURE__ */ jsx11(
1114
1153
  Input,
1115
1154
  {
1116
- ref,
1155
+ ref: mergedRef,
1117
1156
  id,
1118
- inputSize: size,
1157
+ inputSize: resolvedSize,
1119
1158
  error: hasError,
1120
- startAdornment,
1121
- endAdornment,
1159
+ startAdornment: resolvedStartAdornment,
1160
+ endAdornment: resolvedEndAdornment,
1122
1161
  "aria-describedby": helperText || errorMessage ? helperId : void 0,
1123
1162
  "aria-invalid": hasError,
1124
- ...props
1163
+ className: cn(inputSlotClassName, inputPropsClassName),
1164
+ containerClassName,
1165
+ ...props,
1166
+ ...restInputSlotProps,
1167
+ ...restInputProps
1125
1168
  }
1126
1169
  ),
1127
1170
  (helperText || errorMessage) && /* @__PURE__ */ jsx11(
@@ -2036,12 +2079,12 @@ Spinner.displayName = "Spinner";
2036
2079
  import * as React23 from "react";
2037
2080
  import { jsx as jsx23, jsxs as jsxs9 } from "react/jsx-runtime";
2038
2081
  var variantStyles2 = {
2039
- default: "bg-muted border-border text-foreground",
2040
- info: "bg-blue-50 dark:bg-blue-950/30 border-blue-200 dark:border-blue-800 text-blue-800 dark:text-blue-200",
2041
- success: "bg-green-50 dark:bg-green-950/30 border-green-200 dark:border-green-800 text-green-800 dark:text-green-200",
2042
- warning: "bg-yellow-50 dark:bg-yellow-950/30 border-yellow-200 dark:border-yellow-800 text-yellow-800 dark:text-yellow-200",
2043
- error: "bg-red-50 dark:bg-red-950/30 border-red-200 dark:border-red-800 text-red-800 dark:text-red-200",
2044
- destructive: "bg-red-50 dark:bg-red-950/30 border-red-200 dark:border-red-800 text-red-800 dark:text-red-200"
2082
+ default: "bg-muted border-border",
2083
+ info: "bg-blue-50 dark:bg-blue-950/30 border-blue-200 dark:border-blue-800",
2084
+ success: "bg-green-50 dark:bg-green-950/30 border-green-200 dark:border-green-800",
2085
+ warning: "bg-yellow-50 dark:bg-yellow-950/30 border-yellow-200 dark:border-yellow-800",
2086
+ error: "bg-red-50 dark:bg-red-950/30 border-red-200 dark:border-red-800",
2087
+ destructive: "bg-red-50 dark:bg-red-950/30 border-red-200 dark:border-red-800"
2045
2088
  };
2046
2089
  var iconColors = {
2047
2090
  default: "text-muted-foreground",
@@ -2101,7 +2144,7 @@ var Alert = React23.forwardRef(
2101
2144
  ref,
2102
2145
  role: "alert",
2103
2146
  className: cn(
2104
- "relative flex items-start gap-3 rounded-lg border p-4",
2147
+ "relative flex items-start gap-3 rounded-lg border p-4 text-foreground",
2105
2148
  variantStyles2[variant],
2106
2149
  className
2107
2150
  ),
@@ -2146,7 +2189,7 @@ var AlertTitle = React23.forwardRef(
2146
2189
  "h5",
2147
2190
  {
2148
2191
  ref,
2149
- className: cn("font-semibold leading-none tracking-tight", className),
2192
+ className: cn("font-semibold leading-none tracking-tight text-foreground", className),
2150
2193
  ...props,
2151
2194
  children
2152
2195
  }
@@ -2158,7 +2201,7 @@ var AlertDescription = React23.forwardRef(
2158
2201
  "p",
2159
2202
  {
2160
2203
  ref,
2161
- className: cn("mt-1 text-sm opacity-90", className),
2204
+ className: cn("mt-1 text-sm text-muted-foreground", className),
2162
2205
  ...props,
2163
2206
  children
2164
2207
  }
@@ -2169,7 +2212,7 @@ AlertDescription.displayName = "AlertDescription";
2169
2212
  // src/components/tooltip.tsx
2170
2213
  import * as React24 from "react";
2171
2214
  import * as TooltipPrimitive from "@radix-ui/react-tooltip";
2172
- import { Fragment, jsx as jsx24, jsxs as jsxs10 } from "react/jsx-runtime";
2215
+ import { Fragment as Fragment2, jsx as jsx24, jsxs as jsxs10 } from "react/jsx-runtime";
2173
2216
  var TooltipProvider = TooltipPrimitive.Provider;
2174
2217
  var TooltipRoot = TooltipPrimitive.Root;
2175
2218
  var TooltipTrigger = TooltipPrimitive.Trigger;
@@ -2220,7 +2263,7 @@ var Tooltip = React24.forwardRef(
2220
2263
  className
2221
2264
  }, ref) => {
2222
2265
  if (disabled) {
2223
- return /* @__PURE__ */ jsx24(Fragment, { children });
2266
+ return /* @__PURE__ */ jsx24(Fragment2, { children });
2224
2267
  }
2225
2268
  return /* @__PURE__ */ jsx24(TooltipProvider, { children: /* @__PURE__ */ jsxs10(
2226
2269
  TooltipRoot,
@@ -2916,7 +2959,7 @@ var PaginationNamespace = Object.assign(Pagination, {
2916
2959
 
2917
2960
  // src/components/combobox/index.tsx
2918
2961
  import * as React30 from "react";
2919
- import { Fragment as Fragment2, jsx as jsx30, jsxs as jsxs15 } from "react/jsx-runtime";
2962
+ import { Fragment as Fragment3, jsx as jsx30, jsxs as jsxs15 } from "react/jsx-runtime";
2920
2963
  function isMultipleProps(props) {
2921
2964
  return props.multiple === true;
2922
2965
  }
@@ -2928,55 +2971,83 @@ var Combobox = React30.forwardRef(
2928
2971
  searchPlaceholder = "Search...",
2929
2972
  emptyMessage = "No results found.",
2930
2973
  disabled = false,
2974
+ clearable = true,
2975
+ openOnFocus = true,
2931
2976
  className
2932
2977
  } = props;
2978
+ const labelKey = props.labelKey ?? "label";
2979
+ const valueKey = props.valueKey ?? "value";
2980
+ const normalizedOptions = React30.useMemo(() => {
2981
+ return (options ?? []).map((option) => {
2982
+ if (typeof option === "string") {
2983
+ return { label: option, value: option };
2984
+ }
2985
+ const record = option;
2986
+ const maybeLabel = record[labelKey];
2987
+ const maybeValue = record[valueKey];
2988
+ return {
2989
+ label: typeof maybeLabel === "string" ? maybeLabel : String(maybeLabel ?? ""),
2990
+ value: typeof maybeValue === "string" ? maybeValue : String(maybeValue ?? ""),
2991
+ disabled: Boolean(option.disabled)
2992
+ };
2993
+ });
2994
+ }, [options, labelKey, valueKey]);
2933
2995
  const [open, setOpen] = React30.useState(false);
2934
- const [search, setSearch] = React30.useState("");
2996
+ const [internalSearch, setInternalSearch] = React30.useState("");
2935
2997
  const containerRef = React30.useRef(null);
2998
+ const searchInputRef = React30.useRef(null);
2936
2999
  const isMultiple = isMultipleProps(props);
2937
- const [internalSingleValue, setInternalSingleValue] = React30.useState(
2938
- !isMultiple ? props.defaultValue ?? "" : ""
2939
- );
2940
- const [internalMultiValue, setInternalMultiValue] = React30.useState(
2941
- isMultiple ? props.defaultValue ?? [] : []
2942
- );
2943
- const singleValue = !isMultiple ? props.value !== void 0 ? props.value : internalSingleValue : "";
3000
+ const selectAll = isMultiple ? props.selectAll ?? false : false;
3001
+ const selectAllLabel = isMultiple ? props.selectAllLabel ?? "Select all" : "Select all";
3002
+ const [internalSingleValue, setInternalSingleValue] = React30.useState(!isMultiple ? props.defaultValue ?? null : null);
3003
+ const [internalMultiValue, setInternalMultiValue] = React30.useState(isMultiple ? props.defaultValue ?? [] : []);
3004
+ const singleValue = !isMultiple ? props.value !== void 0 ? props.value : internalSingleValue : null;
2944
3005
  const multiValue = isMultiple ? props.value !== void 0 ? props.value : internalMultiValue : [];
3006
+ const search = props.inputValue !== void 0 ? props.inputValue : internalSearch;
2945
3007
  const filteredOptions = React30.useMemo(() => {
2946
- if (!search) return options;
2947
- return options.filter(
3008
+ if (!search) return normalizedOptions;
3009
+ return normalizedOptions.filter(
2948
3010
  (option) => option.label.toLowerCase().includes(search.toLowerCase())
2949
3011
  );
2950
- }, [options, search]);
2951
- const selectedOption = !isMultiple ? options.find((option) => option.value === singleValue) : void 0;
2952
- const selectedOptions = isMultiple ? options.filter((option) => multiValue.includes(option.value)) : [];
2953
- const handleSingleSelect = (optionValue) => {
3012
+ }, [normalizedOptions, search]);
3013
+ const selectedOptions = isMultiple ? multiValue : [];
3014
+ const selectableOptions = React30.useMemo(
3015
+ () => normalizedOptions.filter((option) => !option.disabled),
3016
+ [normalizedOptions]
3017
+ );
3018
+ const allSelected = isMultiple && selectableOptions.length > 0 && selectableOptions.every(
3019
+ (option) => multiValue.some((item) => item.value === option.value)
3020
+ );
3021
+ const handleSingleSelect = (option) => {
2954
3022
  if (!isMultiple) {
2955
3023
  if (props.value === void 0) {
2956
- setInternalSingleValue(optionValue);
3024
+ setInternalSingleValue(option);
2957
3025
  }
2958
- props.onValueChange?.(optionValue);
3026
+ props.onChange?.(option);
2959
3027
  setOpen(false);
2960
- setSearch("");
3028
+ if (props.inputValue === void 0) {
3029
+ setInternalSearch("");
3030
+ }
2961
3031
  }
2962
3032
  };
2963
- const handleMultiSelect = (optionValue) => {
3033
+ const handleMultiSelect = (option) => {
2964
3034
  if (isMultiple) {
2965
- const newValue = multiValue.includes(optionValue) ? multiValue.filter((v) => v !== optionValue) : [...multiValue, optionValue];
3035
+ const exists = multiValue.some((item) => item.value === option.value);
3036
+ const newValue = exists ? multiValue.filter((item) => item.value !== option.value) : [...multiValue, option];
2966
3037
  if (props.value === void 0) {
2967
3038
  setInternalMultiValue(newValue);
2968
3039
  }
2969
- props.onValueChange?.(newValue);
3040
+ props.onChange?.(newValue);
2970
3041
  }
2971
3042
  };
2972
3043
  const handleRemoveItem = (optionValue, e) => {
2973
3044
  e.stopPropagation();
2974
3045
  if (isMultiple) {
2975
- const newValue = multiValue.filter((v) => v !== optionValue);
3046
+ const newValue = multiValue.filter((v) => v.value !== optionValue);
2976
3047
  if (props.value === void 0) {
2977
3048
  setInternalMultiValue(newValue);
2978
3049
  }
2979
- props.onValueChange?.(newValue);
3050
+ props.onChange?.(newValue);
2980
3051
  }
2981
3052
  };
2982
3053
  const handleClearAll = (e) => {
@@ -2985,7 +3056,28 @@ var Combobox = React30.forwardRef(
2985
3056
  if (props.value === void 0) {
2986
3057
  setInternalMultiValue([]);
2987
3058
  }
2988
- props.onValueChange?.([]);
3059
+ props.onChange?.([]);
3060
+ }
3061
+ };
3062
+ const handleSelectAll = (e) => {
3063
+ e.stopPropagation();
3064
+ if (!isMultiple) return;
3065
+ const nextValue = allSelected ? [] : selectableOptions;
3066
+ if (props.value === void 0) {
3067
+ setInternalMultiValue(nextValue);
3068
+ }
3069
+ props.onChange?.(nextValue);
3070
+ };
3071
+ const handleClearSingle = (e) => {
3072
+ e.stopPropagation();
3073
+ if (!isMultiple) {
3074
+ if (props.value === void 0) {
3075
+ setInternalSingleValue(null);
3076
+ }
3077
+ props.onChange?.(null);
3078
+ if (props.inputValue === void 0) {
3079
+ setInternalSearch("");
3080
+ }
2989
3081
  }
2990
3082
  };
2991
3083
  React30.useEffect(() => {
@@ -2997,6 +3089,19 @@ var Combobox = React30.forwardRef(
2997
3089
  document.addEventListener("mousedown", handleClickOutside);
2998
3090
  return () => document.removeEventListener("mousedown", handleClickOutside);
2999
3091
  }, []);
3092
+ React30.useEffect(() => {
3093
+ if (open) {
3094
+ searchInputRef.current?.focus();
3095
+ }
3096
+ }, [open]);
3097
+ React30.useImperativeHandle(
3098
+ ref,
3099
+ () => searchInputRef.current,
3100
+ []
3101
+ );
3102
+ const setSearchRef = (node) => {
3103
+ searchInputRef.current = node;
3104
+ };
3000
3105
  const maxDisplayItems = isMultiple ? props.maxDisplayItems ?? 3 : 0;
3001
3106
  const displayedOptions = selectedOptions.slice(0, maxDisplayItems);
3002
3107
  const remainingCount = selectedOptions.length - maxDisplayItems;
@@ -3018,7 +3123,7 @@ var Combobox = React30.forwardRef(
3018
3123
  className
3019
3124
  ),
3020
3125
  children: [
3021
- isMultiple ? /* @__PURE__ */ jsx30("div", { className: "flex flex-1 flex-wrap items-center gap-1", children: selectedOptions.length === 0 ? /* @__PURE__ */ jsx30("span", { className: "text-muted-foreground", children: placeholder }) : /* @__PURE__ */ jsxs15(Fragment2, { children: [
3126
+ isMultiple ? /* @__PURE__ */ jsx30("div", { className: "flex flex-1 flex-wrap items-center gap-1", children: selectedOptions.length === 0 ? /* @__PURE__ */ jsx30("span", { className: "text-muted-foreground", children: placeholder }) : /* @__PURE__ */ jsxs15(Fragment3, { children: [
3022
3127
  displayedOptions.map((option) => /* @__PURE__ */ jsxs15(
3023
3128
  "span",
3024
3129
  {
@@ -3057,7 +3162,7 @@ var Combobox = React30.forwardRef(
3057
3162
  remainingCount,
3058
3163
  " more"
3059
3164
  ] })
3060
- ] }) }) : /* @__PURE__ */ jsx30("span", { className: cn(!selectedOption && "text-muted-foreground"), children: selectedOption?.label ?? placeholder }),
3165
+ ] }) }) : /* @__PURE__ */ jsx30("span", { className: cn(!singleValue && "text-muted-foreground"), children: singleValue?.label ?? placeholder }),
3061
3166
  /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1", children: [
3062
3167
  isMultiple && selectedOptions.length > 0 && /* @__PURE__ */ jsx30(
3063
3168
  "button",
@@ -3083,6 +3188,31 @@ var Combobox = React30.forwardRef(
3083
3188
  )
3084
3189
  }
3085
3190
  ),
3191
+ !isMultiple && clearable && singleValue && /* @__PURE__ */ jsx30(
3192
+ "button",
3193
+ {
3194
+ type: "button",
3195
+ onClick: handleClearSingle,
3196
+ className: "rounded p-0.5 hover:bg-muted",
3197
+ "aria-label": "Clear selection",
3198
+ children: /* @__PURE__ */ jsx30(
3199
+ "svg",
3200
+ {
3201
+ xmlns: "http://www.w3.org/2000/svg",
3202
+ width: "14",
3203
+ height: "14",
3204
+ viewBox: "0 0 24 24",
3205
+ fill: "none",
3206
+ stroke: "currentColor",
3207
+ strokeWidth: "2",
3208
+ strokeLinecap: "round",
3209
+ strokeLinejoin: "round",
3210
+ className: "opacity-50 hover:opacity-100",
3211
+ children: /* @__PURE__ */ jsx30("path", { d: "M18 6 6 18M6 6l12 12" })
3212
+ }
3213
+ )
3214
+ }
3215
+ ),
3086
3216
  /* @__PURE__ */ jsx30(
3087
3217
  "svg",
3088
3218
  {
@@ -3130,82 +3260,133 @@ var Combobox = React30.forwardRef(
3130
3260
  /* @__PURE__ */ jsx30(
3131
3261
  "input",
3132
3262
  {
3133
- ref,
3263
+ ref: setSearchRef,
3134
3264
  className: "flex h-10 w-full bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground",
3135
3265
  placeholder: searchPlaceholder,
3136
3266
  value: search,
3137
- onChange: (e) => setSearch(e.target.value)
3267
+ onChange: (e) => {
3268
+ if (props.inputValue === void 0) {
3269
+ setInternalSearch(e.target.value);
3270
+ }
3271
+ props.onInputChange?.(e.target.value);
3272
+ },
3273
+ onFocus: () => {
3274
+ if (openOnFocus && !disabled) setOpen(true);
3275
+ }
3138
3276
  }
3139
3277
  )
3140
3278
  ] }),
3141
- /* @__PURE__ */ jsx30("div", { className: "max-h-[300px] overflow-y-auto p-1", children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx30("div", { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) : filteredOptions.map((option) => {
3142
- const isSelected = isMultiple ? multiValue.includes(option.value) : option.value === singleValue;
3143
- return /* @__PURE__ */ jsxs15(
3279
+ /* @__PURE__ */ jsx30("div", { className: "max-h-[300px] overflow-y-auto p-1", children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx30("div", { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ jsxs15(Fragment3, { children: [
3280
+ isMultiple && selectAll && /* @__PURE__ */ jsxs15(
3144
3281
  "button",
3145
3282
  {
3146
3283
  type: "button",
3147
- disabled: option.disabled,
3148
- onClick: () => isMultiple ? handleMultiSelect(option.value) : handleSingleSelect(option.value),
3284
+ onClick: handleSelectAll,
3149
3285
  className: cn(
3150
3286
  "relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
3151
3287
  "hover:bg-muted hover:text-foreground",
3152
3288
  "focus:bg-muted focus:text-foreground",
3153
- "disabled:pointer-events-none disabled:opacity-50",
3154
- isSelected && "bg-muted"
3289
+ allSelected && "bg-muted"
3155
3290
  ),
3156
3291
  children: [
3157
- /* @__PURE__ */ jsx30("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: isMultiple ? (
3158
- // Checkbox for multi-select
3159
- /* @__PURE__ */ jsx30(
3160
- "div",
3161
- {
3162
- className: cn(
3163
- "h-4 w-4 rounded border border-input",
3164
- isSelected && "bg-accent border-accent"
3165
- ),
3166
- children: isSelected && /* @__PURE__ */ jsx30(
3167
- "svg",
3168
- {
3169
- xmlns: "http://www.w3.org/2000/svg",
3170
- width: "24",
3171
- height: "24",
3172
- viewBox: "0 0 24 24",
3173
- fill: "none",
3174
- stroke: "white",
3175
- strokeWidth: "3",
3176
- strokeLinecap: "round",
3177
- strokeLinejoin: "round",
3178
- className: "h-4 w-4",
3179
- children: /* @__PURE__ */ jsx30("polyline", { points: "20 6 9 17 4 12" })
3180
- }
3181
- )
3182
- }
3183
- )
3184
- ) : (
3185
- // Checkmark for single-select
3186
- isSelected && /* @__PURE__ */ jsx30(
3187
- "svg",
3188
- {
3189
- xmlns: "http://www.w3.org/2000/svg",
3190
- width: "24",
3191
- height: "24",
3192
- viewBox: "0 0 24 24",
3193
- fill: "none",
3194
- stroke: "currentColor",
3195
- strokeWidth: "2",
3196
- strokeLinecap: "round",
3197
- strokeLinejoin: "round",
3198
- className: "h-4 w-4",
3199
- children: /* @__PURE__ */ jsx30("polyline", { points: "20 6 9 17 4 12" })
3200
- }
3201
- )
3292
+ /* @__PURE__ */ jsx30("span", { className: "absolute left-2 flex h-4 w-4 items-center justify-center", children: /* @__PURE__ */ jsx30(
3293
+ "div",
3294
+ {
3295
+ className: cn(
3296
+ "flex h-4 w-4 items-center justify-center rounded border border-input",
3297
+ allSelected && "bg-accent border-accent"
3298
+ ),
3299
+ children: allSelected && /* @__PURE__ */ jsx30(
3300
+ "svg",
3301
+ {
3302
+ xmlns: "http://www.w3.org/2000/svg",
3303
+ width: "24",
3304
+ height: "24",
3305
+ viewBox: "0 0 24 24",
3306
+ fill: "none",
3307
+ stroke: "white",
3308
+ strokeWidth: "3",
3309
+ strokeLinecap: "round",
3310
+ strokeLinejoin: "round",
3311
+ className: "h-3 w-3",
3312
+ children: /* @__PURE__ */ jsx30("polyline", { points: "20 6 9 17 4 12" })
3313
+ }
3314
+ )
3315
+ }
3202
3316
  ) }),
3203
- option.label
3317
+ selectAllLabel
3204
3318
  ]
3205
- },
3206
- option.value
3207
- );
3208
- }) })
3319
+ }
3320
+ ),
3321
+ filteredOptions.map((option) => {
3322
+ const isSelected = isMultiple ? multiValue.some((item) => item.value === option.value) : option.value === singleValue?.value;
3323
+ return /* @__PURE__ */ jsxs15(
3324
+ "button",
3325
+ {
3326
+ type: "button",
3327
+ disabled: option.disabled,
3328
+ onClick: () => isMultiple ? handleMultiSelect(option) : handleSingleSelect(option),
3329
+ className: cn(
3330
+ "relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
3331
+ "hover:bg-muted hover:text-foreground",
3332
+ "focus:bg-muted focus:text-foreground",
3333
+ "disabled:pointer-events-none disabled:opacity-50",
3334
+ isSelected && "bg-muted"
3335
+ ),
3336
+ children: [
3337
+ /* @__PURE__ */ jsx30("span", { className: "absolute left-2 flex h-4 w-4 items-center justify-center", children: isMultiple ? (
3338
+ // Checkbox for multi-select
3339
+ /* @__PURE__ */ jsx30(
3340
+ "div",
3341
+ {
3342
+ className: cn(
3343
+ "flex h-4 w-4 items-center justify-center rounded border border-input",
3344
+ isSelected && "bg-accent border-accent"
3345
+ ),
3346
+ children: isSelected && /* @__PURE__ */ jsx30(
3347
+ "svg",
3348
+ {
3349
+ xmlns: "http://www.w3.org/2000/svg",
3350
+ width: "24",
3351
+ height: "24",
3352
+ viewBox: "0 0 24 24",
3353
+ fill: "none",
3354
+ stroke: "white",
3355
+ strokeWidth: "3",
3356
+ strokeLinecap: "round",
3357
+ strokeLinejoin: "round",
3358
+ className: "h-3 w-3",
3359
+ children: /* @__PURE__ */ jsx30("polyline", { points: "20 6 9 17 4 12" })
3360
+ }
3361
+ )
3362
+ }
3363
+ )
3364
+ ) : (
3365
+ // Checkmark for single-select
3366
+ isSelected && /* @__PURE__ */ jsx30(
3367
+ "svg",
3368
+ {
3369
+ xmlns: "http://www.w3.org/2000/svg",
3370
+ width: "24",
3371
+ height: "24",
3372
+ viewBox: "0 0 24 24",
3373
+ fill: "none",
3374
+ stroke: "currentColor",
3375
+ strokeWidth: "2",
3376
+ strokeLinecap: "round",
3377
+ strokeLinejoin: "round",
3378
+ className: "h-4 w-4",
3379
+ children: /* @__PURE__ */ jsx30("polyline", { points: "20 6 9 17 4 12" })
3380
+ }
3381
+ )
3382
+ ) }),
3383
+ option.label
3384
+ ]
3385
+ },
3386
+ option.value
3387
+ );
3388
+ })
3389
+ ] }) })
3209
3390
  ] })
3210
3391
  ] });
3211
3392
  }
@@ -4944,7 +5125,7 @@ var SheetFooter = DrawerFooter;
4944
5125
 
4945
5126
  // src/components/topbar.tsx
4946
5127
  import * as React36 from "react";
4947
- import { Fragment as Fragment3, jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
5128
+ import { Fragment as Fragment4, jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
4948
5129
  var sizeClasses4 = {
4949
5130
  sm: "h-12",
4950
5131
  md: "h-14",
@@ -4972,7 +5153,7 @@ var TopBar = React36.forwardRef(
4972
5153
  TopBar.displayName = "TopBar";
4973
5154
  var TopBarBrand = React36.forwardRef(
4974
5155
  ({ className, logo, name, href, children, ...props }, ref) => {
4975
- const content = /* @__PURE__ */ jsxs21(Fragment3, { children: [
5156
+ const content = /* @__PURE__ */ jsxs21(Fragment4, { children: [
4976
5157
  logo && /* @__PURE__ */ jsx36("span", { className: "shrink-0", children: logo }),
4977
5158
  name && /* @__PURE__ */ jsx36("span", { className: "font-semibold text-lg", children: name }),
4978
5159
  children
@@ -5054,7 +5235,7 @@ TopBarDivider.displayName = "TopBarDivider";
5054
5235
 
5055
5236
  // src/components/sidebar.tsx
5056
5237
  import * as React37 from "react";
5057
- import { Fragment as Fragment4, jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
5238
+ import { Fragment as Fragment5, jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
5058
5239
  var SidebarContext = React37.createContext(void 0);
5059
5240
  var useSidebar = () => {
5060
5241
  const context = React37.useContext(SidebarContext);
@@ -5163,9 +5344,9 @@ SidebarGroup.displayName = "SidebarGroup";
5163
5344
  var SidebarItem = React37.forwardRef(
5164
5345
  ({ className, icon, active, disabled, badge, onClick, href, children, ...props }, ref) => {
5165
5346
  const { collapsed } = useSidebar();
5166
- const content = /* @__PURE__ */ jsxs22(Fragment4, { children: [
5347
+ const content = /* @__PURE__ */ jsxs22(Fragment5, { children: [
5167
5348
  icon && /* @__PURE__ */ jsx37("span", { className: cn("shrink-0", collapsed ? "mx-auto" : ""), children: icon }),
5168
- !collapsed && /* @__PURE__ */ jsxs22(Fragment4, { children: [
5349
+ !collapsed && /* @__PURE__ */ jsxs22(Fragment5, { children: [
5169
5350
  /* @__PURE__ */ jsx37("span", { className: "flex-1 truncate", children }),
5170
5351
  badge && /* @__PURE__ */ jsx37("span", { className: "shrink-0", children: badge })
5171
5352
  ] })
@@ -5286,7 +5467,7 @@ SidebarToggle.displayName = "SidebarToggle";
5286
5467
 
5287
5468
  // src/components/sidebar-rail.tsx
5288
5469
  import * as React38 from "react";
5289
- import { Fragment as Fragment5, jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
5470
+ import { Fragment as Fragment6, jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
5290
5471
  var SidebarRailContext = React38.createContext(void 0);
5291
5472
  var useSidebarRail = () => {
5292
5473
  const context = React38.useContext(SidebarRailContext);
@@ -5429,7 +5610,7 @@ var IconRailContent = React38.forwardRef(
5429
5610
  "div",
5430
5611
  {
5431
5612
  ref,
5432
- className: cn("flex-1 flex flex-col items-center py-2 gap-1 overflow-y-auto", className),
5613
+ className: cn("flex-1 flex flex-col items-center py-2 px-2 gap-1 overflow-y-auto", className),
5433
5614
  ...props,
5434
5615
  children
5435
5616
  }
@@ -5576,7 +5757,7 @@ var RailPanelGroup = React38.forwardRef(
5576
5757
  RailPanelGroup.displayName = "RailPanelGroup";
5577
5758
  var RailPanelItem = React38.forwardRef(
5578
5759
  ({ className, icon, active, disabled, badge, href, children, onClick, ...props }, ref) => {
5579
- const content = /* @__PURE__ */ jsxs23(Fragment5, { children: [
5760
+ const content = /* @__PURE__ */ jsxs23(Fragment6, { children: [
5580
5761
  icon && /* @__PURE__ */ jsx38("span", { className: "shrink-0", children: icon }),
5581
5762
  /* @__PURE__ */ jsx38("span", { className: "flex-1 truncate", children }),
5582
5763
  badge && /* @__PURE__ */ jsx38("span", { className: "shrink-0", children: badge })
@@ -5634,7 +5815,7 @@ var PlaygroundContent = () => {
5634
5815
  const [inputValue, setInputValue] = React39.useState("");
5635
5816
  const [textareaValue, setTextareaValue] = React39.useState("");
5636
5817
  const [selectValue, setSelectValue] = React39.useState("");
5637
- const [comboboxValue, setComboboxValue] = React39.useState("");
5818
+ const [comboboxValue, setComboboxValue] = React39.useState(null);
5638
5819
  const comboboxOptions = [
5639
5820
  { value: "react", label: "React" },
5640
5821
  { value: "vue", label: "Vue" },
@@ -5752,7 +5933,7 @@ var PlaygroundContent = () => {
5752
5933
  {
5753
5934
  options: comboboxOptions,
5754
5935
  value: comboboxValue,
5755
- onValueChange: setComboboxValue,
5936
+ onChange: setComboboxValue,
5756
5937
  placeholder: "Search frameworks..."
5757
5938
  }
5758
5939
  )