@bearmenu/ui 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/dist/{chunk-ERMIA7NP.js → chunk-7PPCH42H.js} +3 -3
  2. package/dist/{chunk-HLQ2IRE7.js → chunk-BAZFVSSG.js} +3 -3
  3. package/dist/chunk-D5QHEHXJ.js +26 -0
  4. package/dist/{chunk-UISA4CIG.js → chunk-N2KNBPAQ.js} +2 -2
  5. package/dist/{chunk-7H54PTVH.js → chunk-PSR7N36A.js} +38 -10
  6. package/dist/chunk-RIDXFY6M.js +38 -0
  7. package/dist/chunk-UUJVXN2O.js +82 -0
  8. package/dist/chunk-WKMLZDUT.js +122 -0
  9. package/dist/chunk-XK2ZDQVE.js +122 -0
  10. package/dist/{chunk-4KOMHDZD.js → chunk-Y5D5LP4A.js} +18 -3
  11. package/dist/chunk-YJ6OBKZJ.js +32 -0
  12. package/dist/{chunk-ESO2EM3L.js → chunk-ZBBUKXM5.js} +2 -2
  13. package/dist/chunk-ZFNOCP6W.js +106 -0
  14. package/dist/components/accordion.js +11 -5
  15. package/dist/components/alert-dialog.js +5 -3
  16. package/dist/components/alert.d.ts +5 -2
  17. package/dist/components/alert.js +25 -9
  18. package/dist/components/avatar.d.ts +17 -2
  19. package/dist/components/avatar.js +91 -12
  20. package/dist/components/badge.d.ts +1 -1
  21. package/dist/components/badge.js +1 -1
  22. package/dist/components/breadcrumb.js +5 -2
  23. package/dist/components/button-group.d.ts +14 -0
  24. package/dist/components/button-group.js +39 -0
  25. package/dist/components/button.d.ts +4 -2
  26. package/dist/components/button.js +1 -1
  27. package/dist/components/calendar.js +3 -3
  28. package/dist/components/card.d.ts +13 -5
  29. package/dist/components/card.js +2 -2
  30. package/dist/components/carousel.d.ts +20 -3
  31. package/dist/components/carousel.js +72 -12
  32. package/dist/components/checkbox.js +1 -1
  33. package/dist/components/circular-progress.d.ts +16 -0
  34. package/dist/components/circular-progress.js +105 -0
  35. package/dist/components/combobox.d.ts +27 -0
  36. package/dist/components/combobox.js +102 -0
  37. package/dist/components/command.d.ts +29 -16
  38. package/dist/components/command.js +2 -2
  39. package/dist/components/currency-input.d.ts +1 -0
  40. package/dist/components/currency-input.js +73 -52
  41. package/dist/components/date-input.d.ts +10 -0
  42. package/dist/components/date-input.js +40 -0
  43. package/dist/components/description-list.d.ts +15 -0
  44. package/dist/components/description-list.js +67 -0
  45. package/dist/components/dialog.d.ts +13 -2
  46. package/dist/components/dialog.js +1 -1
  47. package/dist/components/drawer.d.ts +5 -2
  48. package/dist/components/drawer.js +47 -9
  49. package/dist/components/dropdown-menu.d.ts +7 -2
  50. package/dist/components/dropdown-menu.js +22 -6
  51. package/dist/components/empty-state.js +2 -2
  52. package/dist/components/field.d.ts +22 -0
  53. package/dist/components/field.js +130 -0
  54. package/dist/components/form.d.ts +2 -1
  55. package/dist/components/form.js +11 -1
  56. package/dist/components/haptic-button.js +3 -3
  57. package/dist/components/input-group.d.ts +18 -0
  58. package/dist/components/input-group.js +92 -0
  59. package/dist/components/input.d.ts +8 -2
  60. package/dist/components/input.js +1 -1
  61. package/dist/components/item.d.ts +23 -0
  62. package/dist/components/item.js +120 -0
  63. package/dist/components/kbd.d.ts +13 -0
  64. package/dist/components/kbd.js +49 -0
  65. package/dist/components/lazy-markdown.d.ts +3 -1
  66. package/dist/components/lazy-markdown.js +7 -7
  67. package/dist/components/link-button.js +1 -1
  68. package/dist/components/multi-select-combobox.js +92 -83
  69. package/dist/components/multi-select-menu.d.ts +0 -4
  70. package/dist/components/multi-select-menu.js +28 -17
  71. package/dist/components/native-select.d.ts +12 -0
  72. package/dist/components/native-select.js +49 -0
  73. package/dist/components/pagination.d.ts +5 -2
  74. package/dist/components/pagination.js +66 -7
  75. package/dist/components/place-about-tab.js +4 -4
  76. package/dist/components/place-card.js +1 -1
  77. package/dist/components/place-details-mobile.js +4 -4
  78. package/dist/components/popover.d.ts +7 -1
  79. package/dist/components/popover.js +1 -1
  80. package/dist/components/progress.d.ts +5 -1
  81. package/dist/components/progress.js +17 -3
  82. package/dist/components/radio-group.js +12 -3
  83. package/dist/components/rating.d.ts +2 -0
  84. package/dist/components/rating.js +88 -70
  85. package/dist/components/search-bar.d.ts +1 -2
  86. package/dist/components/search-bar.js +37 -60
  87. package/dist/components/searchable-select.js +76 -72
  88. package/dist/components/select.d.ts +5 -1
  89. package/dist/components/select.js +30 -14
  90. package/dist/components/selection-bar.d.ts +11 -0
  91. package/dist/components/selection-bar.js +65 -0
  92. package/dist/components/separator.js +3 -2
  93. package/dist/components/sheet.d.ts +1 -1
  94. package/dist/components/sheet.js +1 -1
  95. package/dist/components/skeleton-card.js +1 -1
  96. package/dist/components/skeleton.js +1 -1
  97. package/dist/components/slider.js +21 -4
  98. package/dist/components/sliding-panels.js +15 -13
  99. package/dist/components/spinner.d.ts +17 -0
  100. package/dist/components/spinner.js +50 -0
  101. package/dist/components/stepper.d.ts +18 -0
  102. package/dist/components/stepper.js +199 -0
  103. package/dist/components/sticky-container.js +1 -0
  104. package/dist/components/switch.js +4 -3
  105. package/dist/components/table.d.ts +23 -5
  106. package/dist/components/table.js +121 -35
  107. package/dist/components/tabs.d.ts +3 -1
  108. package/dist/components/tabs.js +37 -9
  109. package/dist/components/tag-group.d.ts +9 -0
  110. package/dist/components/tag-group.js +26 -0
  111. package/dist/components/tag.d.ts +17 -0
  112. package/dist/components/tag.js +61 -0
  113. package/dist/components/text.d.ts +3 -3
  114. package/dist/components/text.js +1 -1
  115. package/dist/components/textarea.js +2 -1
  116. package/dist/components/toast.js +1 -1
  117. package/dist/components/toaster.js +1 -1
  118. package/dist/components/toggle-group.js +1 -1
  119. package/dist/components/toggle.js +1 -1
  120. package/dist/components/tooltip.d.ts +3 -2
  121. package/dist/components/tooltip.js +16 -2
  122. package/package.json +44 -26
  123. package/src/components/accordion.tsx +11 -6
  124. package/src/components/alert-dialog.tsx +4 -2
  125. package/src/components/alert.tsx +20 -8
  126. package/src/components/avatar.tsx +106 -13
  127. package/src/components/badge.tsx +12 -11
  128. package/src/components/breadcrumb.tsx +5 -2
  129. package/src/components/button-group.stories.tsx +52 -0
  130. package/src/components/button-group.tsx +40 -0
  131. package/src/components/button.test.tsx +174 -0
  132. package/src/components/button.tsx +42 -19
  133. package/src/components/calendar.tsx +2 -2
  134. package/src/components/card.tsx +55 -13
  135. package/src/components/carousel.tsx +85 -13
  136. package/src/components/checkbox.test.tsx +58 -0
  137. package/src/components/checkbox.tsx +8 -3
  138. package/src/components/circular-progress.stories.tsx +39 -0
  139. package/src/components/circular-progress.tsx +102 -0
  140. package/src/components/collapsible.stories.tsx +7 -3
  141. package/src/components/combobox.stories.tsx +82 -0
  142. package/src/components/combobox.test.tsx +118 -0
  143. package/src/components/combobox.tsx +136 -0
  144. package/src/components/command.test.tsx +91 -0
  145. package/src/components/command.tsx +38 -15
  146. package/src/components/currency-input.test.tsx +63 -0
  147. package/src/components/currency-input.tsx +84 -66
  148. package/src/components/date-input.stories.tsx +31 -0
  149. package/src/components/date-input.tsx +43 -0
  150. package/src/components/description-list.stories.tsx +62 -0
  151. package/src/components/description-list.tsx +68 -0
  152. package/src/components/dialog.test.tsx +84 -0
  153. package/src/components/dialog.tsx +64 -24
  154. package/src/components/drawer.tsx +72 -23
  155. package/src/components/dropdown-menu.test.tsx +180 -0
  156. package/src/components/dropdown-menu.tsx +31 -6
  157. package/src/components/field.stories.tsx +36 -0
  158. package/src/components/field.test.tsx +157 -0
  159. package/src/components/field.tsx +146 -0
  160. package/src/components/form.stories.tsx +3 -2
  161. package/src/components/form.test.tsx +95 -0
  162. package/src/components/form.tsx +9 -0
  163. package/src/components/haptic-button.tsx +1 -1
  164. package/src/components/input-group.stories.tsx +61 -0
  165. package/src/components/input-group.tsx +99 -0
  166. package/src/components/input.test.tsx +103 -0
  167. package/src/components/input.tsx +24 -7
  168. package/src/components/item.stories.tsx +52 -0
  169. package/src/components/item.tsx +115 -0
  170. package/src/components/kbd.stories.tsx +33 -0
  171. package/src/components/kbd.tsx +46 -0
  172. package/src/components/lazy-markdown.tsx +10 -7
  173. package/src/components/multi-select-combobox.test.tsx +101 -0
  174. package/src/components/multi-select-combobox.tsx +85 -82
  175. package/src/components/multi-select-menu.tsx +49 -41
  176. package/src/components/native-select.stories.tsx +52 -0
  177. package/src/components/native-select.tsx +45 -0
  178. package/src/components/pagination.tsx +64 -5
  179. package/src/components/popover.tsx +66 -3
  180. package/src/components/progress.tsx +27 -4
  181. package/src/components/radio-group.test.tsx +64 -0
  182. package/src/components/radio-group.tsx +11 -3
  183. package/src/components/rating.test.tsx +112 -0
  184. package/src/components/rating.tsx +97 -82
  185. package/src/components/search-bar.stories.tsx +1 -32
  186. package/src/components/search-bar.tsx +22 -59
  187. package/src/components/searchable-select.tsx +69 -73
  188. package/src/components/select.tsx +34 -19
  189. package/src/components/selection-bar.stories.tsx +37 -0
  190. package/src/components/selection-bar.tsx +65 -0
  191. package/src/components/separator.tsx +5 -2
  192. package/src/components/sheet.tsx +1 -1
  193. package/src/components/skeleton.tsx +2 -2
  194. package/src/components/slider.test.tsx +45 -0
  195. package/src/components/slider.tsx +31 -12
  196. package/src/components/sliding-panels.tsx +14 -12
  197. package/src/components/spinner.stories.tsx +35 -0
  198. package/src/components/spinner.tsx +50 -0
  199. package/src/components/stepper.stories.tsx +71 -0
  200. package/src/components/stepper.tsx +220 -0
  201. package/src/components/sticky-container.tsx +1 -0
  202. package/src/components/switch.test.tsx +52 -0
  203. package/src/components/switch.tsx +4 -3
  204. package/src/components/table.tsx +140 -35
  205. package/src/components/tabs.test.tsx +107 -0
  206. package/src/components/tabs.tsx +70 -23
  207. package/src/components/tag-group.stories.tsx +39 -0
  208. package/src/components/tag-group.tsx +28 -0
  209. package/src/components/tag.stories.tsx +50 -0
  210. package/src/components/tag.tsx +63 -0
  211. package/src/components/text.test.tsx +1 -1
  212. package/src/components/text.tsx +19 -3
  213. package/src/components/textarea.test.tsx +48 -0
  214. package/src/components/textarea.tsx +2 -1
  215. package/src/components/toast.tsx +4 -3
  216. package/src/components/toggle.tsx +2 -2
  217. package/src/components/tooltip.tsx +12 -2
  218. package/src/globals.css +142 -90
  219. package/dist/chunk-2BMJRXQX.js +0 -80
  220. package/dist/chunk-4AVS6CV4.js +0 -89
  221. package/dist/chunk-4UO73SKC.js +0 -26
  222. package/dist/chunk-CW24PLDW.js +0 -24
  223. package/dist/chunk-IQASCH2V.js +0 -25
  224. package/dist/chunk-NKHH23YK.js +0 -31
  225. package/dist/chunk-QJ54Z7TC.js +0 -83
@@ -9,6 +9,8 @@ interface RatingProps {
9
9
  readonly?: boolean;
10
10
  onRatingChange?: (rating: number) => void;
11
11
  className?: string;
12
+ /** Accessible label for the rating control. Defaults to "Rating". */
13
+ label?: string;
12
14
  }
13
15
  declare const Rating: React.ForwardRefExoticComponent<RatingProps & React.RefAttributes<HTMLDivElement>>;
14
16
 
@@ -4,6 +4,18 @@ import * as React from 'react';
4
4
  import { Star, StarHalf } from 'lucide-react';
5
5
  import { jsxs, jsx } from 'react/jsx-runtime';
6
6
 
7
+ var sizeClasses = {
8
+ sm: "size-3",
9
+ md: "size-4",
10
+ lg: "size-5"
11
+ };
12
+ var textSizeClasses = {
13
+ sm: "text-xs",
14
+ md: "text-sm",
15
+ lg: "text-base"
16
+ };
17
+ var FILLED_CLASSES = "fill-amber-400 text-amber-400";
18
+ var EMPTY_CLASSES = "fill-transparent text-muted-foreground/40";
7
19
  var Rating = React.forwardRef(
8
20
  (_a, ref) => {
9
21
  var _b = _a, {
@@ -14,7 +26,8 @@ var Rating = React.forwardRef(
14
26
  reviewCount,
15
27
  readonly = true,
16
28
  onRatingChange,
17
- className
29
+ className,
30
+ label = "Rating"
18
31
  } = _b, props = __objRest(_b, [
19
32
  "value",
20
33
  "max",
@@ -23,89 +36,94 @@ var Rating = React.forwardRef(
23
36
  "reviewCount",
24
37
  "readonly",
25
38
  "onRatingChange",
26
- "className"
39
+ "className",
40
+ "label"
27
41
  ]);
28
42
  const [hoverValue, setHoverValue] = React.useState(null);
29
- const sizeClasses = {
30
- sm: "h-3 w-3",
31
- md: "h-4 w-4",
32
- lg: "h-5 w-5"
33
- };
34
- const textSizeClasses = {
35
- sm: "text-xs",
36
- md: "text-sm",
37
- lg: "text-base"
38
- };
39
- const handleClick = (rating) => {
40
- if (!readonly && onRatingChange) {
41
- onRatingChange(rating);
42
- }
43
- };
44
- const handleMouseEnter = (rating) => {
45
- if (!readonly) {
46
- setHoverValue(rating);
47
- }
48
- };
49
- const handleMouseLeave = () => {
50
- if (!readonly) {
51
- setHoverValue(null);
43
+ const displayValue = hoverValue != null ? hoverValue : value;
44
+ if (readonly) {
45
+ const fullStars = Math.floor(displayValue);
46
+ const hasHalfStar = displayValue % 1 !== 0;
47
+ const emptyStars = max - fullStars - (hasHalfStar ? 1 : 0);
48
+ return /* @__PURE__ */ jsxs(
49
+ "div",
50
+ __spreadProps(__spreadValues({
51
+ ref,
52
+ role: "img",
53
+ "aria-label": `${label}: ${value} out of ${max}`,
54
+ className: cn("flex items-center gap-1", className)
55
+ }, props), {
56
+ children: [
57
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
58
+ Array.from({ length: fullStars }).map((_, i) => /* @__PURE__ */ jsx(Star, { className: cn(sizeClasses[size], FILLED_CLASSES) }, `full-${i}`)),
59
+ hasHalfStar && /* @__PURE__ */ jsx(StarHalf, { className: cn(sizeClasses[size], FILLED_CLASSES) }),
60
+ Array.from({ length: emptyStars }).map((_, i) => /* @__PURE__ */ jsx(Star, { className: cn(sizeClasses[size], EMPTY_CLASSES) }, `empty-${i}`))
61
+ ] }),
62
+ showCount && reviewCount !== void 0 && /* @__PURE__ */ jsxs("span", { className: cn("ml-1 text-muted-foreground", textSizeClasses[size]), children: [
63
+ "(",
64
+ reviewCount,
65
+ ")"
66
+ ] })
67
+ ]
68
+ })
69
+ );
70
+ }
71
+ const handleKeyDown = (e) => {
72
+ if (!onRatingChange) return;
73
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") {
74
+ e.preventDefault();
75
+ onRatingChange(Math.min(max, value + 1));
76
+ } else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
77
+ e.preventDefault();
78
+ onRatingChange(Math.max(0, value - 1));
79
+ } else if (e.key === "Home") {
80
+ e.preventDefault();
81
+ onRatingChange(0);
82
+ } else if (e.key === "End") {
83
+ e.preventDefault();
84
+ onRatingChange(max);
52
85
  }
53
86
  };
54
- const displayValue = hoverValue != null ? hoverValue : value;
55
- const fullStars = Math.floor(displayValue);
56
- const hasHalfStar = displayValue % 1 !== 0;
57
- const emptyStars = max - fullStars - (hasHalfStar ? 1 : 0);
58
87
  return /* @__PURE__ */ jsxs(
59
88
  "div",
60
89
  __spreadProps(__spreadValues({
61
90
  ref,
62
- className: cn("flex items-center gap-1", !readonly && "cursor-pointer", className)
91
+ role: "radiogroup",
92
+ "aria-label": label,
93
+ onKeyDown: handleKeyDown,
94
+ className: cn("flex items-center gap-1", className)
63
95
  }, props), {
64
96
  children: [
65
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
66
- Array.from({ length: fullStars }).map((_, i) => /* @__PURE__ */ jsx(
67
- Star,
68
- {
69
- className: cn(
70
- sizeClasses[size],
71
- "fill-primary text-primary transition-colors",
72
- !readonly && "hover:fill-primary/80"
73
- ),
74
- onClick: () => handleClick(i + 1),
75
- onMouseEnter: () => handleMouseEnter(i + 1),
76
- onMouseLeave: handleMouseLeave
77
- },
78
- `full-${i}`
79
- )),
80
- hasHalfStar && /* @__PURE__ */ jsx(
81
- StarHalf,
82
- {
83
- className: cn(
84
- sizeClasses[size],
85
- "fill-primary text-primary transition-colors",
86
- !readonly && "hover:fill-primary/80"
87
- ),
88
- onClick: () => handleClick(fullStars + 1),
89
- onMouseEnter: () => handleMouseEnter(fullStars + 1),
90
- onMouseLeave: handleMouseLeave
91
- }
92
- ),
93
- Array.from({ length: emptyStars }).map((_, i) => /* @__PURE__ */ jsx(
94
- Star,
97
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5", onMouseLeave: () => setHoverValue(null), children: Array.from({ length: max }).map((_, i) => {
98
+ const starValue = i + 1;
99
+ const isActive = starValue <= displayValue;
100
+ return /* @__PURE__ */ jsx(
101
+ "button",
95
102
  {
103
+ type: "button",
104
+ role: "radio",
105
+ "aria-checked": value === starValue,
106
+ "aria-label": `${starValue} star${starValue === 1 ? "" : "s"}`,
107
+ onClick: () => onRatingChange == null ? void 0 : onRatingChange(starValue),
108
+ onMouseEnter: () => setHoverValue(starValue),
96
109
  className: cn(
97
- sizeClasses[size],
98
- "text-muted-foreground/30 transition-colors",
99
- !readonly && "hover:text-primary/50"
110
+ "rounded-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"
100
111
  ),
101
- onClick: () => handleClick(fullStars + (hasHalfStar ? 1 : 0) + i + 1),
102
- onMouseEnter: () => handleMouseEnter(fullStars + (hasHalfStar ? 1 : 0) + i + 1),
103
- onMouseLeave: handleMouseLeave
112
+ children: /* @__PURE__ */ jsx(
113
+ Star,
114
+ {
115
+ className: cn(
116
+ sizeClasses[size],
117
+ isActive ? FILLED_CLASSES : EMPTY_CLASSES,
118
+ "transition-colors"
119
+ )
120
+ }
121
+ )
104
122
  },
105
- `empty-${i}`
106
- ))
107
- ] }),
108
- showCount && reviewCount !== void 0 && /* @__PURE__ */ jsxs("span", { className: cn("text-muted-foreground ml-1", textSizeClasses[size]), children: [
123
+ starValue
124
+ );
125
+ }) }),
126
+ showCount && reviewCount !== void 0 && /* @__PURE__ */ jsxs("span", { className: cn("ml-1 text-muted-foreground", textSizeClasses[size]), children: [
109
127
  "(",
110
128
  reviewCount,
111
129
  ")"
@@ -10,8 +10,7 @@ interface SearchBarProps {
10
10
  autoFocus?: boolean;
11
11
  inputAriaLabel?: string;
12
12
  size?: "default" | "compact";
13
- variant?: "primary" | "secondary" | "editorial";
14
13
  }
15
- declare function SearchBar({ placeholder, value, onChange, isSearching, className, inputClassName, autoFocus, inputAriaLabel, size, variant, }: SearchBarProps): react_jsx_runtime.JSX.Element;
14
+ declare function SearchBar({ placeholder, value, onChange, isSearching, className, inputClassName, autoFocus, inputAriaLabel, size, }: SearchBarProps): react_jsx_runtime.JSX.Element;
16
15
 
17
16
  export { SearchBar };
@@ -1,5 +1,3 @@
1
- import { Card } from '../chunk-QJ54Z7TC.js';
2
- import '../chunk-4KOMHDZD.js';
3
1
  import { cn } from '../chunk-FEK5XGZW.js';
4
2
  import '../chunk-3GWWZKX7.js';
5
3
  import { Search, Loader2 } from 'lucide-react';
@@ -14,79 +12,58 @@ function SearchBar({
14
12
  inputClassName,
15
13
  autoFocus = false,
16
14
  inputAriaLabel,
17
- size = "default",
18
- variant = "editorial"
15
+ size = "default"
19
16
  }) {
20
17
  const handleInputChange = (e) => {
21
- const newValue = e.target.value;
22
- onChange == null ? void 0 : onChange(newValue);
18
+ onChange == null ? void 0 : onChange(e.target.value);
23
19
  };
24
- const Wrapper = variant === "editorial" ? "div" : Card;
25
- const wrapperClassName = variant === "editorial" ? cn(
26
- "bg-surface border border-border rounded-[14px] h-12 flex items-center transition-colors focus-within:border-primary",
27
- className
28
- ) : cn(
29
- "border-2 border-primary-foreground/20 backdrop-blur-xl rounded-lg p-0",
30
- size === "compact" ? "md:p-1.5" : "md:p-2",
31
- variant === "primary" ? "!bg-primary-foreground/10 !text-primary !border-primary/20" : "!bg-primary !text-primary-foreground !border-primary/20",
32
- className
33
- );
34
- return /* @__PURE__ */ jsx(Wrapper, { className: wrapperClassName, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center relative", children: [
35
- /* @__PURE__ */ jsx(
36
- "div",
37
- {
38
- className: cn(
39
- "absolute top-1/2 z-10 -translate-y-1/2",
40
- size === "compact" ? "left-3.5" : "left-4"
41
- ),
42
- children: /* @__PURE__ */ jsx(
20
+ return /* @__PURE__ */ jsx(
21
+ "div",
22
+ {
23
+ className: cn(
24
+ "flex w-full items-center rounded-[14px] border border-border bg-surface transition-colors focus-within:border-primary",
25
+ size === "compact" ? "h-10" : "h-12",
26
+ className
27
+ ),
28
+ children: /* @__PURE__ */ jsxs("div", { className: "relative flex w-full items-center", children: [
29
+ /* @__PURE__ */ jsx(
43
30
  Search,
44
31
  {
45
32
  className: cn(
46
- variant === "editorial" ? "text-muted-foreground" : variant === "primary" ? "text-primary" : "text-primary-foreground",
47
- size === "compact" ? "h-3.5 w-3.5" : "h-4 w-4"
33
+ "pointer-events-none absolute top-1/2 z-10 -translate-y-1/2 text-muted-foreground",
34
+ size === "compact" ? "left-3.5 h-3.5 w-3.5" : "left-4 h-4 w-4"
35
+ )
36
+ }
37
+ ),
38
+ /* @__PURE__ */ jsx(
39
+ "input",
40
+ {
41
+ type: "text",
42
+ placeholder,
43
+ value,
44
+ onChange: handleInputChange,
45
+ autoFocus,
46
+ "aria-label": inputAriaLabel != null ? inputAriaLabel : placeholder,
47
+ className: cn(
48
+ "w-full border-0 bg-transparent text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:outline-none",
49
+ size === "compact" ? "rounded-lg py-2.5 pl-9 pr-3 text-base placeholder:text-base md:text-sm md:placeholder:text-sm" : "rounded-[14px] py-3 pl-10 pr-4 text-base placeholder:text-base md:text-[14px] md:placeholder:text-[14px]",
50
+ inputClassName
48
51
  )
49
52
  }
50
- )
51
- }
52
- ),
53
- /* @__PURE__ */ jsx(
54
- "input",
55
- {
56
- type: "text",
57
- placeholder,
58
- value,
59
- onChange: handleInputChange,
60
- autoFocus,
61
- "aria-label": inputAriaLabel != null ? inputAriaLabel : placeholder,
62
- className: cn(
63
- "w-full bg-transparent border-0 focus:outline-none focus-visible:outline-none",
64
- size === "compact" ? "pl-9 pr-3 py-2.5 text-sm placeholder:text-sm rounded-lg" : "pl-10 pr-4 py-3 text-[14px] placeholder:text-[14px] rounded-[14px]",
65
- variant === "editorial" ? "text-foreground placeholder:text-muted-foreground" : variant === "primary" ? "!text-primary placeholder:text-primary/60" : "!text-primary-foreground placeholder:text-primary-foreground/60",
66
- inputClassName
67
- )
68
- }
69
- ),
70
- isSearching && /* @__PURE__ */ jsx(
71
- "div",
72
- {
73
- className: cn(
74
- "absolute top-1/2 -translate-y-1/2",
75
- size === "compact" ? "right-3.5" : "right-4"
76
53
  ),
77
- children: /* @__PURE__ */ jsx(
54
+ isSearching && /* @__PURE__ */ jsx(
78
55
  Loader2,
79
56
  {
57
+ "aria-hidden": true,
80
58
  className: cn(
81
- "animate-spin",
82
- variant === "editorial" ? "text-muted-foreground" : "text-primary/60",
83
- size === "compact" ? "h-3.5 w-3.5" : "h-4 w-4"
59
+ "absolute top-1/2 -translate-y-1/2 animate-spin text-muted-foreground",
60
+ size === "compact" ? "right-3.5 h-3.5 w-3.5" : "right-4 h-4 w-4"
84
61
  )
85
62
  }
86
63
  )
87
- }
88
- )
89
- ] }) });
64
+ ] })
65
+ }
66
+ );
90
67
  }
91
68
 
92
69
  export { SearchBar };
@@ -1,12 +1,12 @@
1
- import { Popover, PopoverTrigger, PopoverContent } from '../chunk-4UO73SKC.js';
2
- import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from '../chunk-7H54PTVH.js';
3
- import '../chunk-4AVS6CV4.js';
4
- import { Button } from '../chunk-2BMJRXQX.js';
1
+ import { Popover, PopoverTrigger, PopoverContent } from '../chunk-UUJVXN2O.js';
2
+ import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from '../chunk-PSR7N36A.js';
3
+ import '../chunk-WKMLZDUT.js';
4
+ import { Button } from '../chunk-ZFNOCP6W.js';
5
5
  import '../chunk-R47NEOSI.js';
6
6
  import { cn } from '../chunk-FEK5XGZW.js';
7
7
  import '../chunk-3GWWZKX7.js';
8
8
  import * as React from 'react';
9
- import { X, ChevronsUpDown, Check } from 'lucide-react';
9
+ import { ChevronsUpDown, Check, X } from 'lucide-react';
10
10
  import { jsxs, jsx } from 'react/jsx-runtime';
11
11
 
12
12
  function SearchableSelect({
@@ -22,82 +22,86 @@ function SearchableSelect({
22
22
  onSearchChange
23
23
  }) {
24
24
  const [open, setOpen] = React.useState(false);
25
+ const listboxId = React.useId();
25
26
  const selectedOption = options.find((opt) => opt.value === value);
26
27
  const displayLabel = (selectedOption == null ? void 0 : selectedOption.label) || (value ? value : void 0);
27
28
  const handleSelect = (selectedValue) => {
28
29
  onValueChange(selectedValue === value ? void 0 : selectedValue);
29
30
  setOpen(false);
30
31
  };
31
- const handleClear = (e) => {
32
- e.stopPropagation();
33
- onValueChange(void 0);
34
- };
35
- return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
36
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
37
- Button,
38
- {
39
- variant: "outline",
40
- role: "combobox",
41
- "aria-expanded": open,
42
- className: cn(
43
- "w-full justify-between h-10",
44
- !value && "text-muted-foreground",
45
- className
46
- ),
47
- disabled,
48
- children: [
49
- /* @__PURE__ */ jsx("span", { className: "truncate", children: displayLabel || placeholder }),
50
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
51
- value && /* @__PURE__ */ jsx(
52
- "div",
53
- {
54
- role: "button",
55
- tabIndex: 0,
56
- className: "rounded-full p-0.5 hover:bg-accent cursor-pointer",
57
- onClick: handleClear,
58
- onKeyDown: (e) => {
59
- if (e.key === "Enter" || e.key === " ") {
60
- e.preventDefault();
61
- handleClear(e);
62
- }
32
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
33
+ /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
34
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
35
+ Button,
36
+ {
37
+ variant: "outline",
38
+ role: "combobox",
39
+ "aria-expanded": open,
40
+ "aria-haspopup": "listbox",
41
+ "aria-controls": open ? listboxId : void 0,
42
+ className: cn(
43
+ "w-full justify-between font-normal",
44
+ value && "pr-16",
45
+ !value && "text-muted-foreground"
46
+ ),
47
+ disabled,
48
+ children: [
49
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: displayLabel || placeholder }),
50
+ /* @__PURE__ */ jsx(ChevronsUpDown, { className: "size-4 shrink-0 opacity-50" })
51
+ ]
52
+ }
53
+ ) }),
54
+ /* @__PURE__ */ jsx(
55
+ PopoverContent,
56
+ {
57
+ id: listboxId,
58
+ className: "w-[var(--radix-popover-trigger-width)] p-0",
59
+ align: "start",
60
+ children: /* @__PURE__ */ jsxs(Command, { shouldFilter: !onSearchChange, children: [
61
+ /* @__PURE__ */ jsx(CommandInput, { placeholder: searchPlaceholder, onValueChange: onSearchChange }),
62
+ /* @__PURE__ */ jsxs(CommandList, { children: [
63
+ /* @__PURE__ */ jsx(CommandEmpty, { children: loading ? "Loading\u2026" : emptyText }),
64
+ /* @__PURE__ */ jsx(CommandGroup, { children: options.map((option) => /* @__PURE__ */ jsxs(
65
+ CommandItem,
66
+ {
67
+ value: option.value,
68
+ onSelect: () => handleSelect(option.value),
69
+ children: [
70
+ /* @__PURE__ */ jsx(
71
+ Check,
72
+ {
73
+ className: cn(
74
+ "mr-2 size-4",
75
+ value === option.value ? "opacity-100" : "opacity-0"
76
+ )
77
+ }
78
+ ),
79
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
80
+ /* @__PURE__ */ jsx("span", { children: option.label }),
81
+ option.description && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: option.description })
82
+ ] })
83
+ ]
63
84
  },
64
- children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
65
- }
66
- ),
67
- /* @__PURE__ */ jsx(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
85
+ option.value
86
+ )) })
87
+ ] })
68
88
  ] })
69
- ]
89
+ }
90
+ )
91
+ ] }),
92
+ value && !disabled && /* @__PURE__ */ jsx(
93
+ "button",
94
+ {
95
+ type: "button",
96
+ "aria-label": "Clear selection",
97
+ onClick: (e) => {
98
+ e.stopPropagation();
99
+ onValueChange(void 0);
100
+ },
101
+ className: "absolute right-9 top-1/2 -translate-y-1/2 inline-flex size-6 items-center justify-center rounded-full text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 transition-colors",
102
+ children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
70
103
  }
71
- ) }),
72
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-full p-0", align: "start", children: /* @__PURE__ */ jsxs(Command, { shouldFilter: !onSearchChange, children: [
73
- /* @__PURE__ */ jsx(CommandInput, { placeholder: searchPlaceholder, onValueChange: onSearchChange }),
74
- /* @__PURE__ */ jsxs(CommandList, { children: [
75
- /* @__PURE__ */ jsx(CommandEmpty, { children: loading ? "Loading..." : emptyText }),
76
- /* @__PURE__ */ jsx(CommandGroup, { children: options.map((option) => /* @__PURE__ */ jsxs(
77
- CommandItem,
78
- {
79
- value: option.value,
80
- onSelect: () => handleSelect(option.value),
81
- children: [
82
- /* @__PURE__ */ jsx(
83
- Check,
84
- {
85
- className: cn(
86
- "mr-2 h-4 w-4",
87
- value === option.value ? "opacity-100" : "opacity-0"
88
- )
89
- }
90
- ),
91
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
92
- /* @__PURE__ */ jsx("span", { children: option.label }),
93
- option.description && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: option.description })
94
- ] })
95
- ]
96
- },
97
- option.value
98
- )) })
99
- ] })
100
- ] }) })
104
+ )
101
105
  ] });
102
106
  }
103
107
 
@@ -1,10 +1,14 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
1
2
  import * as React from 'react';
2
3
  import * as SelectPrimitive from '@radix-ui/react-select';
4
+ import { VariantProps } from 'class-variance-authority';
3
5
 
4
6
  declare const Select: React.FC<SelectPrimitive.SelectProps>;
5
7
  declare const SelectGroup: React.ForwardRefExoticComponent<SelectPrimitive.SelectGroupProps & React.RefAttributes<HTMLDivElement>>;
6
8
  declare const SelectValue: React.ForwardRefExoticComponent<SelectPrimitive.SelectValueProps & React.RefAttributes<HTMLSpanElement>>;
7
- declare const SelectTrigger: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
9
+ declare const SelectTrigger: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
10
+ size?: "default" | "sm" | "lg" | null | undefined;
11
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLButtonElement>>;
8
12
  declare const SelectScrollUpButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollUpButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
9
13
  declare const SelectScrollDownButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollDownButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
10
14
  declare const SelectContent: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
@@ -2,26 +2,40 @@ import { cn } from '../chunk-FEK5XGZW.js';
2
2
  import { __objRest, __spreadProps, __spreadValues } from '../chunk-3GWWZKX7.js';
3
3
  import * as React from 'react';
4
4
  import * as SelectPrimitive from '@radix-ui/react-select';
5
+ import { cva } from 'class-variance-authority';
5
6
  import { ChevronDown, ChevronUp, Check } from 'lucide-react';
6
7
  import { jsxs, jsx } from 'react/jsx-runtime';
7
8
 
8
9
  var Select = SelectPrimitive.Root;
9
10
  var SelectGroup = SelectPrimitive.Group;
10
11
  var SelectValue = SelectPrimitive.Value;
12
+ var selectTriggerVariants = cva(
13
+ "flex w-full items-center justify-between rounded-xl bg-background border border-border text-sm font-medium text-foreground transition-colors focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground [&>span]:line-clamp-1 hover:border-foreground/30 aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive/40",
14
+ {
15
+ variants: {
16
+ size: {
17
+ sm: "h-9 px-3",
18
+ default: "h-11 px-4 py-2",
19
+ lg: "h-12 px-5"
20
+ }
21
+ },
22
+ defaultVariants: {
23
+ size: "default"
24
+ }
25
+ }
26
+ );
11
27
  var SelectTrigger = React.forwardRef((_a, ref) => {
12
- var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
28
+ var _b = _a, { className, size, children } = _b, props = __objRest(_b, ["className", "size", "children"]);
13
29
  return /* @__PURE__ */ jsxs(
14
30
  SelectPrimitive.Trigger,
15
31
  __spreadProps(__spreadValues({
16
32
  ref,
17
- className: cn(
18
- "flex h-11 w-full items-center justify-between rounded-xl bg-surface border border-border px-4 py-2 text-sm font-medium text-muted-foreground transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 hover:border-foreground/20 hover:text-foreground",
19
- className
20
- )
33
+ "data-slot": "select-trigger",
34
+ className: cn(selectTriggerVariants({ size }), className)
21
35
  }, props), {
22
36
  children: [
23
37
  children,
24
- /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) })
38
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 opacity-60" }) })
25
39
  ]
26
40
  })
27
41
  );
@@ -35,7 +49,7 @@ var SelectScrollUpButton = React.forwardRef((_a, ref) => {
35
49
  ref,
36
50
  className: cn("flex cursor-default items-center justify-center py-1", className)
37
51
  }, props), {
38
- children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" })
52
+ children: /* @__PURE__ */ jsx(ChevronUp, { className: "size-4" })
39
53
  })
40
54
  );
41
55
  });
@@ -48,7 +62,7 @@ var SelectScrollDownButton = React.forwardRef((_a, ref) => {
48
62
  ref,
49
63
  className: cn("flex cursor-default items-center justify-center py-1", className)
50
64
  }, props), {
51
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
65
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4" })
52
66
  })
53
67
  );
54
68
  });
@@ -59,8 +73,9 @@ var SelectContent = React.forwardRef((_a, ref) => {
59
73
  SelectPrimitive.Content,
60
74
  __spreadProps(__spreadValues({
61
75
  ref,
76
+ "data-slot": "select-content",
62
77
  className: cn(
63
- "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-card text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
78
+ "relative z-50 max-h-96 min-w-32 overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
64
79
  position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
65
80
  className
66
81
  ),
@@ -72,7 +87,7 @@ var SelectContent = React.forwardRef((_a, ref) => {
72
87
  SelectPrimitive.Viewport,
73
88
  {
74
89
  className: cn(
75
- "p-1 flex flex-col gap-1",
90
+ "p-1 flex flex-col gap-0.5",
76
91
  position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
77
92
  ),
78
93
  children
@@ -90,7 +105,7 @@ var SelectLabel = React.forwardRef((_a, ref) => {
90
105
  SelectPrimitive.Label,
91
106
  __spreadValues({
92
107
  ref,
93
- className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)
108
+ className: cn("py-1.5 pl-8 pr-2 text-xs font-semibold text-muted-foreground", className)
94
109
  }, props)
95
110
  );
96
111
  });
@@ -101,13 +116,14 @@ var SelectItem = React.forwardRef((_a, ref) => {
101
116
  SelectPrimitive.Item,
102
117
  __spreadProps(__spreadValues({
103
118
  ref,
119
+ "data-slot": "select-item",
104
120
  className: cn(
105
- "relative flex w-full cursor-default select-none items-center rounded-lg py-2 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[state=checked]:bg-primary/10 data-[state=checked]:text-primary data-[state=checked]:font-medium",
121
+ "relative flex w-full cursor-default select-none items-center rounded-md py-2 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[state=checked]:font-medium",
106
122
  className
107
123
  )
108
124
  }, props), {
109
125
  children: [
110
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
126
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "size-4" }) }) }),
111
127
  /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
112
128
  ]
113
129
  })
@@ -120,7 +136,7 @@ var SelectSeparator = React.forwardRef((_a, ref) => {
120
136
  SelectPrimitive.Separator,
121
137
  __spreadValues({
122
138
  ref,
123
- className: cn("-mx-1 my-1 h-px bg-muted", className)
139
+ className: cn("-mx-1 my-1 h-px bg-border", className)
124
140
  }, props)
125
141
  );
126
142
  });