analytica-frontend-lib 1.0.94 → 1.0.95

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.
@@ -0,0 +1,27 @@
1
+ import * as react from 'react';
2
+ import { InputHTMLAttributes } from 'react';
3
+
4
+ declare const Search: react.ForwardRefExoticComponent<{
5
+ /** List of options to show in dropdown */
6
+ options: string[];
7
+ /** Callback when an option is selected from dropdown */
8
+ onSelect?: (value: string) => void;
9
+ /** Callback when search input changes */
10
+ onSearch?: (query: string) => void;
11
+ /** Control dropdown visibility externally */
12
+ showDropdown?: boolean;
13
+ /** Callback when dropdown open state changes */
14
+ onDropdownChange?: (open: boolean) => void;
15
+ /** Maximum height of dropdown in pixels */
16
+ dropdownMaxHeight?: number;
17
+ /** Text to show when no results are found */
18
+ noResultsText?: string;
19
+ /** Additional CSS classes to apply to the input */
20
+ className?: string;
21
+ /** Additional CSS classes to apply to the container */
22
+ containerClassName?: string;
23
+ /** Callback when clear button is clicked */
24
+ onClear?: () => void;
25
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "onSelect"> & react.RefAttributes<HTMLInputElement>>;
26
+
27
+ export { Search as default };
@@ -0,0 +1,27 @@
1
+ import * as react from 'react';
2
+ import { InputHTMLAttributes } from 'react';
3
+
4
+ declare const Search: react.ForwardRefExoticComponent<{
5
+ /** List of options to show in dropdown */
6
+ options: string[];
7
+ /** Callback when an option is selected from dropdown */
8
+ onSelect?: (value: string) => void;
9
+ /** Callback when search input changes */
10
+ onSearch?: (query: string) => void;
11
+ /** Control dropdown visibility externally */
12
+ showDropdown?: boolean;
13
+ /** Callback when dropdown open state changes */
14
+ onDropdownChange?: (open: boolean) => void;
15
+ /** Maximum height of dropdown in pixels */
16
+ dropdownMaxHeight?: number;
17
+ /** Text to show when no results are found */
18
+ noResultsText?: string;
19
+ /** Additional CSS classes to apply to the input */
20
+ className?: string;
21
+ /** Additional CSS classes to apply to the container */
22
+ containerClassName?: string;
23
+ /** Callback when clear button is clicked */
24
+ onClear?: () => void;
25
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "onSelect"> & react.RefAttributes<HTMLInputElement>>;
26
+
27
+ export { Search as default };
@@ -0,0 +1,639 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/components/Search/Search.tsx
21
+ var Search_exports = {};
22
+ __export(Search_exports, {
23
+ default: () => Search_default
24
+ });
25
+ module.exports = __toCommonJS(Search_exports);
26
+ var import_phosphor_react2 = require("phosphor-react");
27
+ var import_react2 = require("react");
28
+
29
+ // src/components/DropdownMenu/DropdownMenu.tsx
30
+ var import_phosphor_react = require("phosphor-react");
31
+ var import_react = require("react");
32
+ var import_zustand = require("zustand");
33
+
34
+ // src/utils/utils.ts
35
+ var import_clsx = require("clsx");
36
+ var import_tailwind_merge = require("tailwind-merge");
37
+ function cn(...inputs) {
38
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
39
+ }
40
+
41
+ // src/components/Button/Button.tsx
42
+ var import_jsx_runtime = require("react/jsx-runtime");
43
+ var VARIANT_ACTION_CLASSES = {
44
+ solid: {
45
+ primary: "bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed",
46
+ positive: "bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed",
47
+ negative: "bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed"
48
+ },
49
+ outline: {
50
+ primary: "bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed",
51
+ positive: "bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed",
52
+ negative: "bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed"
53
+ },
54
+ link: {
55
+ primary: "bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed",
56
+ positive: "bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed",
57
+ negative: "bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed"
58
+ }
59
+ };
60
+ var SIZE_CLASSES = {
61
+ "extra-small": "text-xs px-3.5 py-2",
62
+ small: "text-sm px-4 py-2.5",
63
+ medium: "text-md px-5 py-2.5",
64
+ large: "text-lg px-6 py-3",
65
+ "extra-large": "text-lg px-7 py-3.5"
66
+ };
67
+ var Button = ({
68
+ children,
69
+ iconLeft,
70
+ iconRight,
71
+ size = "medium",
72
+ variant = "solid",
73
+ action = "primary",
74
+ className = "",
75
+ disabled,
76
+ type = "button",
77
+ ...props
78
+ }) => {
79
+ const sizeClasses = SIZE_CLASSES[size];
80
+ const variantClasses = VARIANT_ACTION_CLASSES[variant][action];
81
+ const baseClasses = "inline-flex items-center justify-center rounded-full cursor-pointer font-medium";
82
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
83
+ "button",
84
+ {
85
+ className: cn(baseClasses, variantClasses, sizeClasses, className),
86
+ disabled,
87
+ type,
88
+ ...props,
89
+ children: [
90
+ iconLeft && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mr-2 flex items-center", children: iconLeft }),
91
+ children,
92
+ iconRight && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-2 flex items-center", children: iconRight })
93
+ ]
94
+ }
95
+ );
96
+ };
97
+ var Button_default = Button;
98
+
99
+ // src/components/DropdownMenu/DropdownMenu.tsx
100
+ var import_jsx_runtime2 = require("react/jsx-runtime");
101
+ function createDropdownStore() {
102
+ return (0, import_zustand.create)((set) => ({
103
+ open: false,
104
+ setOpen: (open) => set({ open })
105
+ }));
106
+ }
107
+ var useDropdownStore = (externalStore) => {
108
+ if (!externalStore) {
109
+ throw new Error(
110
+ "Component must be used within a DropdownMenu (store is missing)"
111
+ );
112
+ }
113
+ return externalStore;
114
+ };
115
+ var injectStore = (children, store) => {
116
+ return import_react.Children.map(children, (child) => {
117
+ if ((0, import_react.isValidElement)(child)) {
118
+ const typedChild = child;
119
+ const newProps = {
120
+ store
121
+ };
122
+ if (typedChild.props.children) {
123
+ newProps.children = injectStore(typedChild.props.children, store);
124
+ }
125
+ return (0, import_react.cloneElement)(typedChild, newProps);
126
+ }
127
+ return child;
128
+ });
129
+ };
130
+ var DropdownMenu = ({
131
+ children,
132
+ open: propOpen,
133
+ onOpenChange
134
+ }) => {
135
+ const storeRef = (0, import_react.useRef)(null);
136
+ storeRef.current ??= createDropdownStore();
137
+ const store = storeRef.current;
138
+ const { open, setOpen: storeSetOpen } = (0, import_zustand.useStore)(store, (s) => s);
139
+ const setOpen = (newOpen) => {
140
+ storeSetOpen(newOpen);
141
+ };
142
+ const menuRef = (0, import_react.useRef)(null);
143
+ const handleArrowDownOrArrowUp = (event) => {
144
+ const menuContent = menuRef.current?.querySelector('[role="menu"]');
145
+ if (menuContent) {
146
+ event.preventDefault();
147
+ const items = Array.from(
148
+ menuContent.querySelectorAll(
149
+ '[role="menuitem"]:not([aria-disabled="true"])'
150
+ )
151
+ ).filter((el) => el instanceof HTMLElement);
152
+ if (items.length === 0) return;
153
+ const focusedItem = document.activeElement;
154
+ const currentIndex = items.findIndex((item) => item === focusedItem);
155
+ let nextIndex;
156
+ if (event.key === "ArrowDown") {
157
+ nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;
158
+ } else {
159
+ nextIndex = currentIndex === -1 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;
160
+ }
161
+ items[nextIndex]?.focus();
162
+ }
163
+ };
164
+ const handleDownkey = (event) => {
165
+ if (event.key === "Escape") {
166
+ setOpen(false);
167
+ } else if (event.key === "ArrowDown" || event.key === "ArrowUp") {
168
+ handleArrowDownOrArrowUp(event);
169
+ }
170
+ };
171
+ const handleClickOutside = (event) => {
172
+ if (menuRef.current && !menuRef.current.contains(event.target)) {
173
+ setOpen(false);
174
+ }
175
+ };
176
+ (0, import_react.useEffect)(() => {
177
+ if (open) {
178
+ document.addEventListener("mousedown", handleClickOutside);
179
+ document.addEventListener("keydown", handleDownkey);
180
+ }
181
+ return () => {
182
+ document.removeEventListener("mousedown", handleClickOutside);
183
+ document.removeEventListener("keydown", handleDownkey);
184
+ };
185
+ }, [open]);
186
+ (0, import_react.useEffect)(() => {
187
+ setOpen(open);
188
+ onOpenChange?.(open);
189
+ }, [open, onOpenChange]);
190
+ (0, import_react.useEffect)(() => {
191
+ if (propOpen) {
192
+ setOpen(propOpen);
193
+ }
194
+ }, [propOpen]);
195
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "relative", ref: menuRef, children: injectStore(children, store) });
196
+ };
197
+ var DropdownMenuTrigger = ({
198
+ className,
199
+ children,
200
+ onClick,
201
+ store: externalStore,
202
+ ...props
203
+ }) => {
204
+ const store = useDropdownStore(externalStore);
205
+ const open = (0, import_zustand.useStore)(store, (s) => s.open);
206
+ const toggleOpen = () => store.setState({ open: !open });
207
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
208
+ "button",
209
+ {
210
+ onClick: (e) => {
211
+ e.stopPropagation();
212
+ toggleOpen();
213
+ if (onClick) onClick(e);
214
+ },
215
+ "aria-expanded": open,
216
+ className: cn(className),
217
+ ...props,
218
+ children
219
+ }
220
+ );
221
+ };
222
+ DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
223
+ var ITEM_SIZE_CLASSES = {
224
+ small: "text-sm",
225
+ medium: "text-md"
226
+ };
227
+ var SIDE_CLASSES = {
228
+ top: "bottom-full",
229
+ right: "top-full",
230
+ bottom: "top-full",
231
+ left: "top-full"
232
+ };
233
+ var ALIGN_CLASSES = {
234
+ start: "left-0",
235
+ center: "left-1/2 -translate-x-1/2",
236
+ end: "right-0"
237
+ };
238
+ var MENUCONTENT_VARIANT_CLASSES = {
239
+ menu: "p-1",
240
+ profile: "p-6"
241
+ };
242
+ var MenuLabel = (0, import_react.forwardRef)(({ className, inset, store: _store, ...props }, ref) => {
243
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
244
+ "div",
245
+ {
246
+ ref,
247
+ className: cn("text-sm w-full", inset ? "pl-8" : "", className),
248
+ ...props
249
+ }
250
+ );
251
+ });
252
+ MenuLabel.displayName = "MenuLabel";
253
+ var DropdownMenuContent = (0, import_react.forwardRef)(
254
+ ({
255
+ className,
256
+ align = "start",
257
+ side = "bottom",
258
+ variant = "menu",
259
+ sideOffset = 4,
260
+ children,
261
+ store: externalStore,
262
+ ...props
263
+ }, ref) => {
264
+ const store = useDropdownStore(externalStore);
265
+ const open = (0, import_zustand.useStore)(store, (s) => s.open);
266
+ const [isVisible, setIsVisible] = (0, import_react.useState)(open);
267
+ (0, import_react.useEffect)(() => {
268
+ if (open) {
269
+ setIsVisible(true);
270
+ } else {
271
+ const timer = setTimeout(() => setIsVisible(false), 200);
272
+ return () => clearTimeout(timer);
273
+ }
274
+ }, [open]);
275
+ if (!isVisible) return null;
276
+ const getPositionClasses = () => {
277
+ const vertical = SIDE_CLASSES[side];
278
+ const horizontal = ALIGN_CLASSES[align];
279
+ return `absolute ${vertical} ${horizontal}`;
280
+ };
281
+ const variantClasses = MENUCONTENT_VARIANT_CLASSES[variant];
282
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
283
+ "div",
284
+ {
285
+ ref,
286
+ role: "menu",
287
+ className: `
288
+ bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md border-border-100
289
+ ${open ? "animate-in fade-in-0 zoom-in-95" : "animate-out fade-out-0 zoom-out-95"}
290
+ ${getPositionClasses()}
291
+ ${variantClasses}
292
+ ${className}
293
+ `,
294
+ style: {
295
+ marginTop: side === "bottom" ? sideOffset : void 0,
296
+ marginBottom: side === "top" ? sideOffset : void 0,
297
+ marginLeft: side === "right" ? sideOffset : void 0,
298
+ marginRight: side === "left" ? sideOffset : void 0
299
+ },
300
+ ...props,
301
+ children
302
+ }
303
+ );
304
+ }
305
+ );
306
+ DropdownMenuContent.displayName = "DropdownMenuContent";
307
+ var DropdownMenuItem = (0, import_react.forwardRef)(
308
+ ({
309
+ className,
310
+ size = "small",
311
+ children,
312
+ iconRight,
313
+ iconLeft,
314
+ disabled = false,
315
+ onClick,
316
+ variant = "menu",
317
+ store: externalStore,
318
+ ...props
319
+ }, ref) => {
320
+ const store = useDropdownStore(externalStore);
321
+ const setOpen = (0, import_zustand.useStore)(store, (s) => s.setOpen);
322
+ const sizeClasses = ITEM_SIZE_CLASSES[size];
323
+ const handleClick = (e) => {
324
+ if (disabled) {
325
+ e.preventDefault();
326
+ e.stopPropagation();
327
+ return;
328
+ }
329
+ onClick?.(e);
330
+ setOpen(false);
331
+ };
332
+ const getVariantClasses = () => {
333
+ if (variant === "profile") {
334
+ return "relative flex flex-row justify-between select-none items-center gap-2 rounded-sm p-4 text-sm outline-none transition-colors [&>svg]:size-6 [&>svg]:shrink-0";
335
+ }
336
+ return "relative flex select-none items-center gap-2 rounded-sm p-3 text-sm outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0";
337
+ };
338
+ const getVariantProps = () => {
339
+ return variant === "profile" ? { "data-variant": "profile" } : {};
340
+ };
341
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
342
+ "div",
343
+ {
344
+ ref,
345
+ role: "menuitem",
346
+ ...getVariantProps(),
347
+ "aria-disabled": disabled,
348
+ className: `
349
+ focus-visible:bg-background-50
350
+ ${getVariantClasses()}
351
+ ${sizeClasses}
352
+ ${className}
353
+ ${disabled ? "cursor-not-allowed text-text-400" : "cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground"}
354
+ `,
355
+ onClick: handleClick,
356
+ onKeyDown: (e) => {
357
+ if (e.key === "Enter" || e.key === " ") handleClick(e);
358
+ },
359
+ tabIndex: disabled ? -1 : 0,
360
+ ...props,
361
+ children: [
362
+ iconLeft,
363
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-full text-md", children }),
364
+ iconRight
365
+ ]
366
+ }
367
+ );
368
+ }
369
+ );
370
+ DropdownMenuItem.displayName = "DropdownMenuItem";
371
+ var DropdownMenuSeparator = (0, import_react.forwardRef)(({ className, store: _store, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
372
+ "div",
373
+ {
374
+ ref,
375
+ className: cn("my-1 h-px bg-border-200", className),
376
+ ...props
377
+ }
378
+ ));
379
+ DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
380
+ var ProfileMenuTrigger = (0, import_react.forwardRef)(({ className, onClick, store: externalStore, ...props }, ref) => {
381
+ const store = useDropdownStore(externalStore);
382
+ const open = (0, import_zustand.useStore)(store, (s) => s.open);
383
+ const toggleOpen = () => store.setState({ open: !open });
384
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
385
+ "button",
386
+ {
387
+ ref,
388
+ className: cn(
389
+ "rounded-lg size-10 bg-primary-50 flex items-center justify-center cursor-pointer",
390
+ className
391
+ ),
392
+ onClick: (e) => {
393
+ e.stopPropagation();
394
+ toggleOpen();
395
+ onClick?.(e);
396
+ },
397
+ "aria-expanded": open,
398
+ ...props,
399
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "size-6 rounded-full bg-primary-100 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_phosphor_react.User, { className: "text-primary-950", size: 18 }) })
400
+ }
401
+ );
402
+ });
403
+ ProfileMenuTrigger.displayName = "ProfileMenuTrigger";
404
+ var ProfileMenuHeader = (0, import_react.forwardRef)(({ className, name, email, store: _store, ...props }, ref) => {
405
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
406
+ "div",
407
+ {
408
+ ref,
409
+ "data-component": "ProfileMenuHeader",
410
+ className: cn("flex flex-row gap-4 items-center", className),
411
+ ...props,
412
+ children: [
413
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "size-16 bg-primary-100 rounded-full flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_phosphor_react.User, { size: 34, className: "text-primary-950" }) }),
414
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col ", children: [
415
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xl font-bold text-text-950", children: name }),
416
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-md text-text-600", children: email })
417
+ ] })
418
+ ]
419
+ }
420
+ );
421
+ });
422
+ ProfileMenuHeader.displayName = "ProfileMenuHeader";
423
+ var ProfileMenuSection = (0, import_react.forwardRef)(({ className, children, store: _store, ...props }, ref) => {
424
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn("flex flex-col p-2", className), ...props, children });
425
+ });
426
+ ProfileMenuSection.displayName = "ProfileMenuSection";
427
+ var ProfileMenuFooter = ({
428
+ className,
429
+ disabled = false,
430
+ onClick,
431
+ store: externalStore,
432
+ ...props
433
+ }) => {
434
+ const store = useDropdownStore(externalStore);
435
+ const setOpen = (0, import_zustand.useStore)(store, (s) => s.setOpen);
436
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
437
+ Button_default,
438
+ {
439
+ variant: "outline",
440
+ className: cn("w-full", className),
441
+ disabled,
442
+ onClick: (e) => {
443
+ setOpen(false);
444
+ onClick?.(e);
445
+ },
446
+ ...props,
447
+ children: [
448
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "mr-2 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_phosphor_react.SignOut, {}) }),
449
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Sair" })
450
+ ]
451
+ }
452
+ );
453
+ };
454
+ ProfileMenuFooter.displayName = "ProfileMenuFooter";
455
+ var DropdownMenu_default = DropdownMenu;
456
+
457
+ // src/components/Search/Search.tsx
458
+ var import_jsx_runtime3 = require("react/jsx-runtime");
459
+ var filterOptions = (options, query) => {
460
+ if (!query || query.length < 1) return [];
461
+ return options.filter(
462
+ (option) => option.toLowerCase().includes(query.toLowerCase())
463
+ );
464
+ };
465
+ var updateInputValue = (value, ref, onChange) => {
466
+ if (!onChange) return;
467
+ if (ref && "current" in ref && ref.current) {
468
+ ref.current.value = value;
469
+ const event = new Event("input", { bubbles: true });
470
+ Object.defineProperty(event, "target", {
471
+ writable: false,
472
+ value: ref.current
473
+ });
474
+ onChange(event);
475
+ } else {
476
+ const event = {
477
+ target: { value },
478
+ currentTarget: { value }
479
+ };
480
+ onChange(event);
481
+ }
482
+ };
483
+ var Search = (0, import_react2.forwardRef)(
484
+ ({
485
+ options = [],
486
+ onSelect,
487
+ onSearch,
488
+ showDropdown: controlledShowDropdown,
489
+ onDropdownChange,
490
+ dropdownMaxHeight = 240,
491
+ noResultsText = "Nenhum resultado encontrado",
492
+ className = "",
493
+ containerClassName = "",
494
+ disabled,
495
+ readOnly,
496
+ id,
497
+ onClear,
498
+ value,
499
+ onChange,
500
+ placeholder = "Buscar...",
501
+ ...props
502
+ }, ref) => {
503
+ const [dropdownOpen, setDropdownOpen] = (0, import_react2.useState)(false);
504
+ const dropdownStore = (0, import_react2.useRef)(createDropdownStore()).current;
505
+ const dropdownRef = (0, import_react2.useRef)(null);
506
+ const filteredOptions = (0, import_react2.useMemo)(() => {
507
+ if (!options.length) {
508
+ return [];
509
+ }
510
+ const filtered = filterOptions(options, value || "");
511
+ return filtered;
512
+ }, [options, value]);
513
+ const showDropdown = controlledShowDropdown ?? (dropdownOpen && value && String(value).length > 0);
514
+ (0, import_react2.useEffect)(() => {
515
+ const shouldShow = Boolean(value && String(value).length > 0);
516
+ setDropdownOpen(shouldShow);
517
+ dropdownStore.setState({ open: shouldShow });
518
+ onDropdownChange?.(shouldShow);
519
+ }, [value, onDropdownChange, dropdownStore]);
520
+ const handleSelectOption = (option) => {
521
+ onSelect?.(option);
522
+ setDropdownOpen(false);
523
+ dropdownStore.setState({ open: false });
524
+ updateInputValue(option, ref, onChange);
525
+ };
526
+ (0, import_react2.useEffect)(() => {
527
+ const handleClickOutside = (event) => {
528
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
529
+ setDropdownOpen(false);
530
+ dropdownStore.setState({ open: false });
531
+ }
532
+ };
533
+ if (showDropdown) {
534
+ document.addEventListener("mousedown", handleClickOutside);
535
+ }
536
+ return () => {
537
+ document.removeEventListener("mousedown", handleClickOutside);
538
+ };
539
+ }, [showDropdown, dropdownStore]);
540
+ const generatedId = (0, import_react2.useId)();
541
+ const inputId = id ?? `search-${generatedId}`;
542
+ const handleClear = () => {
543
+ if (onClear) {
544
+ onClear();
545
+ } else {
546
+ updateInputValue("", ref, onChange);
547
+ }
548
+ };
549
+ const handleClearClick = (e) => {
550
+ e.preventDefault();
551
+ e.stopPropagation();
552
+ handleClear();
553
+ };
554
+ const handleLeftIconClick = () => {
555
+ if (ref && "current" in ref && ref.current) {
556
+ ref.current.blur();
557
+ }
558
+ };
559
+ const handleInputChange = (e) => {
560
+ onChange?.(e);
561
+ onSearch?.(e.target.value);
562
+ };
563
+ const getInputStateClasses = (disabled2, readOnly2) => {
564
+ if (disabled2) return "cursor-not-allowed opacity-40";
565
+ if (readOnly2) return "cursor-default focus:outline-none !text-text-900";
566
+ return "hover:border-border-400";
567
+ };
568
+ const showClearButton = value && !disabled && !readOnly;
569
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
570
+ "div",
571
+ {
572
+ ref: dropdownRef,
573
+ className: `w-full max-w-lg md:w-[488px] ${containerClassName}`,
574
+ children: [
575
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative flex items-center", children: [
576
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
577
+ "button",
578
+ {
579
+ type: "button",
580
+ className: "w-6 h-6 text-text-800 flex items-center justify-center bg-transparent border-0 p-0 cursor-pointer hover:text-text-600 transition-colors",
581
+ onClick: handleLeftIconClick,
582
+ "aria-label": "Voltar",
583
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react2.CaretLeft, {})
584
+ }
585
+ ) }),
586
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
587
+ "input",
588
+ {
589
+ ref,
590
+ id: inputId,
591
+ type: "text",
592
+ className: `w-full py-0 px-4 pl-10 ${showClearButton ? "pr-10" : "pr-4"} font-normal text-text-900 focus:outline-primary-950 border rounded-full bg-primary border-border-300 focus:border-2 focus:border-primary-950 h-10 placeholder:text-text-600 ${getInputStateClasses(disabled, readOnly)} ${className}`,
593
+ value,
594
+ onChange: handleInputChange,
595
+ disabled,
596
+ readOnly,
597
+ placeholder,
598
+ "aria-expanded": showDropdown ? "true" : void 0,
599
+ "aria-haspopup": options.length > 0 ? "listbox" : void 0,
600
+ role: options.length > 0 ? "combobox" : void 0,
601
+ ...props
602
+ }
603
+ ),
604
+ showClearButton && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
605
+ "button",
606
+ {
607
+ type: "button",
608
+ className: "p-0 border-0 bg-transparent cursor-pointer",
609
+ onMouseDown: handleClearClick,
610
+ "aria-label": "Limpar busca",
611
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "w-6 h-6 text-text-800 flex items-center justify-center hover:text-text-600 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react2.X, {}) })
612
+ }
613
+ ) })
614
+ ] }),
615
+ showDropdown && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DropdownMenu_default, { open: showDropdown, onOpenChange: setDropdownOpen, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
616
+ DropdownMenuContent,
617
+ {
618
+ className: "w-full mt-1",
619
+ style: { maxHeight: dropdownMaxHeight },
620
+ align: "start",
621
+ children: filteredOptions.length > 0 ? filteredOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
622
+ DropdownMenuItem,
623
+ {
624
+ onClick: () => handleSelectOption(option),
625
+ className: "text-text-700 text-base leading-6 cursor-pointer",
626
+ children: option
627
+ },
628
+ option
629
+ )) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "px-3 py-3 text-text-700 text-base", children: noResultsText })
630
+ }
631
+ ) })
632
+ ]
633
+ }
634
+ );
635
+ }
636
+ );
637
+ Search.displayName = "Search";
638
+ var Search_default = Search;
639
+ //# sourceMappingURL=index.js.map