@fayz-ai/ui 0.8.3 → 0.8.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.
Files changed (88) hide show
  1. package/dist/ChartWidgetInner-GDE5PBTR.js +46 -0
  2. package/dist/ChartWidgetInner-GDE5PBTR.js.map +1 -0
  3. package/dist/{chunk-BVF2KPTT.js → chunk-G6OKZ7WL.js} +30 -3
  4. package/dist/chunk-G6OKZ7WL.js.map +1 -0
  5. package/dist/{chunk-ID2HQK2Q.js → chunk-KV3MHB6N.js} +116 -213
  6. package/dist/chunk-KV3MHB6N.js.map +1 -0
  7. package/dist/{chunk-A7O7KGNL.js → chunk-OUPJDGKE.js} +27 -43
  8. package/dist/chunk-OUPJDGKE.js.map +1 -0
  9. package/dist/chunk-PVIB724L.js +161 -0
  10. package/dist/chunk-PVIB724L.js.map +1 -0
  11. package/dist/{chunk-O5F4LLSL.js → chunk-VDAYIQX4.js} +208 -8
  12. package/dist/chunk-VDAYIQX4.js.map +1 -0
  13. package/dist/{chunk-2GDQUARM.js → chunk-YLQGUJAQ.js} +24 -42
  14. package/dist/chunk-YLQGUJAQ.js.map +1 -0
  15. package/dist/dashboard/ChartWidget.d.ts.map +1 -1
  16. package/dist/dashboard/ChartWidgetInner.d.ts +11 -0
  17. package/dist/dashboard/ChartWidgetInner.d.ts.map +1 -0
  18. package/dist/dashboard/OnboardingWidget.d.ts.map +1 -1
  19. package/dist/dashboard/index.js +3 -2
  20. package/dist/icons.d.ts +8 -0
  21. package/dist/icons.d.ts.map +1 -0
  22. package/dist/icons.js +3 -0
  23. package/dist/icons.js.map +1 -0
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +6 -6
  27. package/dist/layout/Sidebar.d.ts +5 -2
  28. package/dist/layout/Sidebar.d.ts.map +1 -1
  29. package/dist/layout/index.js +2 -1
  30. package/dist/preset.cjs +201 -11
  31. package/dist/preset.cjs.map +1 -1
  32. package/dist/preset.js +201 -1
  33. package/dist/preset.js.map +1 -1
  34. package/dist/primitives/date-picker.d.ts +7 -1
  35. package/dist/primitives/date-picker.d.ts.map +1 -1
  36. package/dist/primitives/index.js +2 -2
  37. package/dist/primitives/search-select.d.ts +3 -1
  38. package/dist/primitives/search-select.d.ts.map +1 -1
  39. package/dist/tailwind.cjs +199 -2
  40. package/dist/tailwind.cjs.map +1 -1
  41. package/dist/tailwind.js +198 -1
  42. package/dist/tailwind.js.map +1 -1
  43. package/dist/theme/index.d.ts.map +1 -1
  44. package/dist/theme/index.js +1 -2
  45. package/package.json +24 -22
  46. package/src/dashboard/ChartWidget.tsx +8 -65
  47. package/src/dashboard/ChartWidgetInner.tsx +83 -0
  48. package/src/dashboard/OnboardingWidget.tsx +32 -1
  49. package/src/dashboard/icon.ts +2 -2
  50. package/src/icons.ts +66 -0
  51. package/src/index.ts +4 -0
  52. package/src/layout/Sidebar.tsx +70 -136
  53. package/src/primitives/date-picker.tsx +30 -4
  54. package/src/primitives/search-select.tsx +12 -4
  55. package/src/theme/index.ts +9 -6
  56. package/dist/chunk-2GDQUARM.js.map +0 -1
  57. package/dist/chunk-2P7T6QQK.cjs +0 -206
  58. package/dist/chunk-2P7T6QQK.cjs.map +0 -1
  59. package/dist/chunk-A7O7KGNL.js.map +0 -1
  60. package/dist/chunk-BVF2KPTT.js.map +0 -1
  61. package/dist/chunk-H6OULCHF.cjs +0 -81
  62. package/dist/chunk-H6OULCHF.cjs.map +0 -1
  63. package/dist/chunk-ID2HQK2Q.js.map +0 -1
  64. package/dist/chunk-IWBXYV4U.js +0 -203
  65. package/dist/chunk-IWBXYV4U.js.map +0 -1
  66. package/dist/chunk-MI6FOB4O.cjs +0 -351
  67. package/dist/chunk-MI6FOB4O.cjs.map +0 -1
  68. package/dist/chunk-O5F4LLSL.js.map +0 -1
  69. package/dist/chunk-OW73RZOU.cjs +0 -313
  70. package/dist/chunk-OW73RZOU.cjs.map +0 -1
  71. package/dist/chunk-SVVKUMSL.cjs +0 -1733
  72. package/dist/chunk-SVVKUMSL.cjs.map +0 -1
  73. package/dist/chunk-TDGSY5W6.cjs +0 -474
  74. package/dist/chunk-TDGSY5W6.cjs.map +0 -1
  75. package/dist/chunk-WF3STNDX.cjs +0 -682
  76. package/dist/chunk-WF3STNDX.cjs.map +0 -1
  77. package/dist/chunk-XIRJGVDK.cjs +0 -1826
  78. package/dist/chunk-XIRJGVDK.cjs.map +0 -1
  79. package/dist/dashboard/index.cjs +0 -106
  80. package/dist/dashboard/index.cjs.map +0 -1
  81. package/dist/index.cjs +0 -650
  82. package/dist/index.cjs.map +0 -1
  83. package/dist/layout/index.cjs +0 -98
  84. package/dist/layout/index.cjs.map +0 -1
  85. package/dist/primitives/index.cjs +0 -363
  86. package/dist/primitives/index.cjs.map +0 -1
  87. package/dist/theme/index.cjs +0 -41
  88. package/dist/theme/index.cjs.map +0 -1
@@ -1,1733 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkOW73RZOU_cjs = require('./chunk-OW73RZOU.cjs');
4
- var chunkMI6FOB4O_cjs = require('./chunk-MI6FOB4O.cjs');
5
- var chunkH6OULCHF_cjs = require('./chunk-H6OULCHF.cjs');
6
- var React10 = require('react');
7
- var jsxRuntime = require('react/jsx-runtime');
8
- var classVarianceAuthority = require('class-variance-authority');
9
- var DialogPrimitive = require('@radix-ui/react-dialog');
10
- var lucideReact = require('lucide-react');
11
- var SelectPrimitive = require('@radix-ui/react-select');
12
- var sonner = require('sonner');
13
- var TabsPrimitive = require('@radix-ui/react-tabs');
14
- var SeparatorPrimitive = require('@radix-ui/react-separator');
15
- var TooltipPrimitive = require('@radix-ui/react-tooltip');
16
- var reactDom = require('react-dom');
17
- var core = require('@fayz-ai/core');
18
- var PopoverPrimitive = require('@radix-ui/react-popover');
19
-
20
- function _interopNamespace(e) {
21
- if (e && e.__esModule) return e;
22
- var n = Object.create(null);
23
- if (e) {
24
- Object.keys(e).forEach(function (k) {
25
- if (k !== 'default') {
26
- var d = Object.getOwnPropertyDescriptor(e, k);
27
- Object.defineProperty(n, k, d.get ? d : {
28
- enumerable: true,
29
- get: function () { return e[k]; }
30
- });
31
- }
32
- });
33
- }
34
- n.default = e;
35
- return Object.freeze(n);
36
- }
37
-
38
- var React10__namespace = /*#__PURE__*/_interopNamespace(React10);
39
- var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
40
- var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
41
- var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
42
- var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
43
- var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
44
- var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
45
-
46
- var Input = React10__namespace.forwardRef(
47
- ({ className, type, error, description, id, ...props }, ref) => {
48
- const inputId = id ?? React10__namespace.useId();
49
- const descriptionId = description ? `${inputId}-description` : void 0;
50
- const errorId = error ? `${inputId}-error` : void 0;
51
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
52
- /* @__PURE__ */ jsxRuntime.jsx(
53
- "input",
54
- {
55
- type,
56
- id: inputId,
57
- className: chunkH6OULCHF_cjs.cn(
58
- "flex h-8 w-full rounded-input border border-input bg-card px-2 py-1 text-sm text-foreground shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
59
- error && "border-destructive focus-visible:ring-destructive",
60
- className
61
- ),
62
- ref,
63
- "aria-invalid": error ? true : void 0,
64
- "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || void 0,
65
- ...props
66
- }
67
- ),
68
- description && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: descriptionId, className: "mt-1.5 text-xs text-muted-foreground", children: description }),
69
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "mt-1.5 text-xs text-destructive", children: error })
70
- ] });
71
- }
72
- );
73
- Input.displayName = "Input";
74
- var badgeVariants = classVarianceAuthority.cva(
75
- "inline-flex items-center gap-1.5 rounded px-2 py-0.5 text-xs font-medium leading-[18px] transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
76
- {
77
- variants: {
78
- variant: {
79
- default: "bg-muted text-muted-foreground",
80
- secondary: "bg-muted text-muted-foreground",
81
- info: "bg-info-soft text-info-soft-foreground",
82
- success: "bg-success-soft text-success-soft-foreground",
83
- warning: "bg-warning-soft text-warning-soft-foreground",
84
- destructive: "bg-destructive-soft text-destructive-soft-foreground",
85
- magic: "bg-magic-soft text-magic-soft-foreground",
86
- strong: "bg-primary text-primary-foreground",
87
- outline: "border border-border text-foreground"
88
- }
89
- },
90
- defaultVariants: {
91
- variant: "default"
92
- }
93
- }
94
- );
95
- var VARIANTS_WITH_DOT = /* @__PURE__ */ new Set([
96
- "info",
97
- "success",
98
- "warning",
99
- "destructive",
100
- "magic"
101
- ]);
102
- var DOT_COLOR = {
103
- info: "hsl(var(--info))",
104
- success: "hsl(var(--success))",
105
- warning: "hsl(var(--warning))",
106
- destructive: "hsl(var(--destructive))",
107
- magic: "hsl(var(--magic))"
108
- };
109
- function Badge({ className, variant, dot, children, ...props }) {
110
- const v = variant ?? "default";
111
- const showDot = dot ?? VARIANTS_WITH_DOT.has(v);
112
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn(badgeVariants({ variant }), className), ...props, children: [
113
- showDot && /* @__PURE__ */ jsxRuntime.jsx(
114
- "span",
115
- {
116
- className: "inline-block size-1.5 rounded-full",
117
- style: { background: DOT_COLOR[v] ?? "currentColor" }
118
- }
119
- ),
120
- children
121
- ] });
122
- }
123
- var SIZE_MAP = {
124
- sm: "sm:max-w-sm",
125
- md: "sm:max-w-md",
126
- lg: "sm:max-w-lg",
127
- xl: "sm:max-w-xl",
128
- "2xl": "sm:max-w-2xl",
129
- "3xl": "sm:max-w-3xl",
130
- full: "sm:max-w-[calc(100vw-4rem)]"
131
- };
132
- var Modal = DialogPrimitive__namespace.Root;
133
- var ModalTrigger = DialogPrimitive__namespace.Trigger;
134
- var ModalClose = DialogPrimitive__namespace.Close;
135
- var ModalPortal = DialogPrimitive__namespace.Portal;
136
- var ModalOverlay = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
137
- DialogPrimitive__namespace.Overlay,
138
- {
139
- ref,
140
- className: chunkH6OULCHF_cjs.cn(
141
- "fayz-modal-overlay saas-mdl-ov fixed inset-0 z-50",
142
- "flex items-center justify-center p-0 sm:p-6",
143
- className
144
- ),
145
- ...props
146
- }
147
- ));
148
- ModalOverlay.displayName = "ModalOverlay";
149
- var ModalContent = React10__namespace.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(ModalPortal, { children: /* @__PURE__ */ jsxRuntime.jsx(ModalOverlay, { children: /* @__PURE__ */ jsxRuntime.jsxs(
150
- DialogPrimitive__namespace.Content,
151
- {
152
- ref,
153
- onCloseAutoFocus: (e) => {
154
- e.preventDefault();
155
- onCloseAutoFocus?.(e);
156
- },
157
- onPointerDownOutside: (e) => {
158
- const target = e.target;
159
- if (target.closest("[data-modal-passthrough]") || target.closest("[data-radix-popper-content-wrapper]")) {
160
- e.preventDefault();
161
- }
162
- onPointerDownOutside?.(e);
163
- },
164
- onInteractOutside: (e) => {
165
- const target = e.target;
166
- if (target.closest("[data-modal-passthrough]") || target.closest("[data-radix-popper-content-wrapper]")) {
167
- e.preventDefault();
168
- }
169
- onInteractOutside?.(e);
170
- },
171
- className: chunkH6OULCHF_cjs.cn(
172
- "fayz-glass-surface fayz-modal-content saas-mdl-ct relative z-50 flex flex-col w-full outline-none",
173
- // Mobile fullscreen
174
- "h-full rounded-none border-0",
175
- // Desktop centered card
176
- "sm:h-auto sm:max-h-[85vh] sm:rounded-2xl sm:border",
177
- SIZE_MAP[size],
178
- noPadding ? "" : "p-6 gap-4",
179
- className
180
- ),
181
- ...props,
182
- children: [
183
- children,
184
- !hideClose && /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 z-10 flex h-7 w-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring", children: [
185
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
186
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
187
- ] })
188
- ]
189
- }
190
- ) }) }));
191
- ModalContent.displayName = "ModalContent";
192
- function ModalHeader({ className, ...props }) {
193
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("flex flex-col space-y-1.5 text-center sm:text-left shrink-0", className), ...props });
194
- }
195
- function ModalBody({ className, ...props }) {
196
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("flex-1 overflow-y-auto min-h-0", className), ...props });
197
- }
198
- function ModalFooter({ className, ...props }) {
199
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 shrink-0", className), ...props });
200
- }
201
- var ModalTitle = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Title, { ref, className: chunkH6OULCHF_cjs.cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
202
- ModalTitle.displayName = "ModalTitle";
203
- var ModalDescription = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: chunkH6OULCHF_cjs.cn("text-sm text-muted-foreground", className), ...props }));
204
- ModalDescription.displayName = "ModalDescription";
205
- var COLOR_CLASSES = {
206
- primary: "border-primary bg-primary text-primary-foreground",
207
- success: "border-success bg-success text-white dark:border-success dark:bg-success",
208
- warning: "border-warning bg-warning text-white",
209
- destructive: "border-destructive bg-destructive text-destructive-foreground"
210
- };
211
- var Checkbox = React10__namespace.forwardRef(
212
- ({ checked = false, onChange, disabled, className, color = "primary", id, ...props }, ref) => {
213
- return /* @__PURE__ */ jsxRuntime.jsx(
214
- "button",
215
- {
216
- ref,
217
- id,
218
- type: "button",
219
- role: "checkbox",
220
- "aria-checked": checked,
221
- disabled,
222
- onClick: () => onChange?.(!checked),
223
- className: chunkH6OULCHF_cjs.cn(
224
- "peer inline-flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border-2 transition-all duration-150",
225
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
226
- "disabled:cursor-not-allowed disabled:opacity-50",
227
- checked ? `${COLOR_CLASSES[color]} shadow-sm` : "border-muted-foreground/40 bg-background hover:border-muted-foreground/60",
228
- className
229
- ),
230
- ...props,
231
- children: checked && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5", strokeWidth: 3 })
232
- }
233
- );
234
- }
235
- );
236
- Checkbox.displayName = "Checkbox";
237
- var Select = SelectPrimitive__namespace.Root;
238
- var SelectGroup = SelectPrimitive__namespace.Group;
239
- var SelectValue = SelectPrimitive__namespace.Value;
240
- var SelectTrigger = React10__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
241
- SelectPrimitive__namespace.Trigger,
242
- {
243
- ref,
244
- className: chunkH6OULCHF_cjs.cn(
245
- "flex h-10 w-full items-center justify-between rounded-input border border-input bg-background px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
246
- className
247
- ),
248
- ...props,
249
- children: [
250
- children,
251
- /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Icon, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-4 w-4 opacity-50" }) })
252
- ]
253
- }
254
- ));
255
- SelectTrigger.displayName = SelectPrimitive__namespace.Trigger.displayName;
256
- var SelectScrollUpButton = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
257
- SelectPrimitive__namespace.ScrollUpButton,
258
- {
259
- ref,
260
- className: chunkH6OULCHF_cjs.cn(
261
- "flex cursor-default items-center justify-center py-1",
262
- className
263
- ),
264
- ...props,
265
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "h-4 w-4" })
266
- }
267
- ));
268
- SelectScrollUpButton.displayName = SelectPrimitive__namespace.ScrollUpButton.displayName;
269
- var SelectScrollDownButton = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
270
- SelectPrimitive__namespace.ScrollDownButton,
271
- {
272
- ref,
273
- className: chunkH6OULCHF_cjs.cn(
274
- "flex cursor-default items-center justify-center py-1",
275
- className
276
- ),
277
- ...props,
278
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-4 w-4" })
279
- }
280
- ));
281
- SelectScrollDownButton.displayName = SelectPrimitive__namespace.ScrollDownButton.displayName;
282
- var SelectContent = React10__namespace.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
283
- SelectPrimitive__namespace.Content,
284
- {
285
- ref,
286
- className: chunkH6OULCHF_cjs.cn(
287
- "fayz-glass-surface relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-card border bg-popover text-popover-foreground shadow-md",
288
- 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",
289
- className
290
- ),
291
- position,
292
- ...props,
293
- children: [
294
- /* @__PURE__ */ jsxRuntime.jsx(SelectScrollUpButton, {}),
295
- /* @__PURE__ */ jsxRuntime.jsx(
296
- SelectPrimitive__namespace.Viewport,
297
- {
298
- className: chunkH6OULCHF_cjs.cn(
299
- "p-1",
300
- position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
301
- ),
302
- children
303
- }
304
- ),
305
- /* @__PURE__ */ jsxRuntime.jsx(SelectScrollDownButton, {})
306
- ]
307
- }
308
- ) }));
309
- SelectContent.displayName = SelectPrimitive__namespace.Content.displayName;
310
- var SelectLabel = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
311
- SelectPrimitive__namespace.Label,
312
- {
313
- ref,
314
- className: chunkH6OULCHF_cjs.cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className),
315
- ...props
316
- }
317
- ));
318
- SelectLabel.displayName = SelectPrimitive__namespace.Label.displayName;
319
- var SelectItem = React10__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
320
- SelectPrimitive__namespace.Item,
321
- {
322
- ref,
323
- className: chunkH6OULCHF_cjs.cn(
324
- "relative flex w-full cursor-default select-none items-center rounded-button py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-muted focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
325
- className
326
- ),
327
- ...props,
328
- children: [
329
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4" }) }) }),
330
- /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemText, { children })
331
- ]
332
- }
333
- ));
334
- SelectItem.displayName = SelectPrimitive__namespace.Item.displayName;
335
- var SelectSeparator = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
336
- SelectPrimitive__namespace.Separator,
337
- {
338
- ref,
339
- className: chunkH6OULCHF_cjs.cn("-mx-1 my-1 h-px bg-muted", className),
340
- ...props
341
- }
342
- ));
343
- SelectSeparator.displayName = SelectPrimitive__namespace.Separator.displayName;
344
- function ToastProvider({
345
- position = "bottom-center",
346
- theme = "system"
347
- }) {
348
- const saveBarVisible = chunkOW73RZOU_cjs.useSaveBarVisible();
349
- const bottomOffset = position.startsWith("bottom") && saveBarVisible ? 84 : 24;
350
- return /* @__PURE__ */ jsxRuntime.jsx(
351
- sonner.Toaster,
352
- {
353
- position,
354
- theme,
355
- offset: bottomOffset,
356
- closeButton: true,
357
- richColors: true,
358
- toastOptions: {
359
- classNames: {
360
- // Format harmonized with the SaveBar island: soft ring + xl shadow,
361
- // generous rounded-2xl radius (full-pill looks wrong on multi-line
362
- // toasts). Colors stay semantic (richColors).
363
- toast: "group !gap-3 !rounded-3xl !border !px-4 !py-3 !shadow-xl !ring-1 !ring-black/5",
364
- title: "!text-sm !font-semibold",
365
- description: "!text-xs !mt-0.5",
366
- closeButton: "!opacity-0 group-hover:!opacity-60 hover:!opacity-100 !transition-opacity"
367
- }
368
- }
369
- }
370
- );
371
- }
372
- var Tabs = TabsPrimitive__namespace.Root;
373
- var TabsList = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
374
- TabsPrimitive__namespace.List,
375
- {
376
- ref,
377
- className: chunkH6OULCHF_cjs.cn(
378
- "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
379
- className
380
- ),
381
- ...props
382
- }
383
- ));
384
- TabsList.displayName = TabsPrimitive__namespace.List.displayName;
385
- var TabsTrigger = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
386
- TabsPrimitive__namespace.Trigger,
387
- {
388
- ref,
389
- className: chunkH6OULCHF_cjs.cn(
390
- "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
391
- className
392
- ),
393
- ...props
394
- }
395
- ));
396
- TabsTrigger.displayName = TabsPrimitive__namespace.Trigger.displayName;
397
- var TabsContent = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
398
- TabsPrimitive__namespace.Content,
399
- {
400
- ref,
401
- className: chunkH6OULCHF_cjs.cn(
402
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
403
- className
404
- ),
405
- ...props
406
- }
407
- ));
408
- TabsContent.displayName = TabsPrimitive__namespace.Content.displayName;
409
- var Separator2 = React10__namespace.forwardRef(
410
- ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
411
- SeparatorPrimitive__namespace.Root,
412
- {
413
- ref,
414
- decorative,
415
- orientation,
416
- className: chunkH6OULCHF_cjs.cn(
417
- "shrink-0 bg-border",
418
- orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
419
- className
420
- ),
421
- ...props
422
- }
423
- )
424
- );
425
- Separator2.displayName = SeparatorPrimitive__namespace.Root.displayName;
426
- function Breadcrumb({ parent, current, onBack }) {
427
- const { onBack: effectiveOnBack, parentLabel: effectiveParent } = chunkOW73RZOU_cjs.useCrossModuleBack(onBack, parent);
428
- chunkOW73RZOU_cjs.useBackHandler(effectiveOnBack);
429
- return /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "flex items-center gap-1.5 text-sm text-muted-foreground", children: [
430
- /* @__PURE__ */ jsxRuntime.jsxs(
431
- "button",
432
- {
433
- type: "button",
434
- onClick: effectiveOnBack,
435
- className: "inline-flex items-center gap-1 hover:text-foreground transition-colors",
436
- children: [
437
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-3.5 w-3.5" }),
438
- effectiveParent
439
- ]
440
- }
441
- ),
442
- current !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
443
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "/" }),
444
- current ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-medium truncate max-w-[200px]", children: current }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block h-4 w-24 rounded bg-muted animate-pulse align-middle" })
445
- ] })
446
- ] });
447
- }
448
- var TooltipProvider = TooltipPrimitive__namespace.Provider;
449
- var Tooltip = TooltipPrimitive__namespace.Root;
450
- var TooltipTrigger = TooltipPrimitive__namespace.Trigger;
451
- var TooltipContent = React10__namespace.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
452
- TooltipPrimitive__namespace.Content,
453
- {
454
- ref,
455
- sideOffset,
456
- className: chunkH6OULCHF_cjs.cn(
457
- "fayz-glass-surface z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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",
458
- className
459
- ),
460
- ...props
461
- }
462
- ));
463
- TooltipContent.displayName = TooltipPrimitive__namespace.Content.displayName;
464
- function formatTime12(h, m) {
465
- const period = h >= 12 ? "pm" : "am";
466
- const h12 = h % 12 || 12;
467
- return `${h12}:${String(m).padStart(2, "0")}${period}`;
468
- }
469
- function formatTime24(h, m) {
470
- return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
471
- }
472
- function TimePicker({ value, onChange, interval = 15, min = "00:00", max = "23:45", use12h = false, readOnly, className, defaultOpen, onOpenChange }) {
473
- const [open, setOpen] = React10.useState(defaultOpen ?? false);
474
- const ref = React10.useRef(null);
475
- const triggerRef = React10.useRef(null);
476
- const listRef = React10.useRef(null);
477
- const [pos, setPos] = React10.useState({ top: 0, left: 0, width: 0 });
478
- React10.useEffect(() => {
479
- if (!open || !triggerRef.current) return;
480
- const rect = triggerRef.current.getBoundingClientRect();
481
- setPos({ top: rect.bottom + 4, left: rect.left, width: Math.max(rect.width, 120) });
482
- }, [open]);
483
- React10.useEffect(() => {
484
- if (!open) return;
485
- const handler = (e) => {
486
- const target = e.target;
487
- if (ref.current?.contains(target)) return;
488
- if (listRef.current?.contains(target)) return;
489
- setOpen(false);
490
- onOpenChange?.(false);
491
- };
492
- document.addEventListener("mousedown", handler);
493
- return () => document.removeEventListener("mousedown", handler);
494
- }, [open]);
495
- React10.useEffect(() => {
496
- if (!open || !listRef.current || !value) return;
497
- const el = listRef.current.querySelector('[data-selected="true"]');
498
- if (el) el.scrollIntoView({ block: "center" });
499
- }, [open, value]);
500
- const slots = React10.useMemo(() => {
501
- const [minH, minM] = min.split(":").map(Number);
502
- const [maxH, maxM] = max.split(":").map(Number);
503
- const minTotal = minH * 60 + minM;
504
- const maxTotal = maxH * 60 + maxM;
505
- const result = [];
506
- for (let t = minTotal; t <= maxTotal; t += interval) {
507
- const h = Math.floor(t / 60);
508
- const m = t % 60;
509
- result.push({
510
- value: formatTime24(h, m),
511
- label: use12h ? formatTime12(h, m) : formatTime24(h, m)
512
- });
513
- }
514
- return result;
515
- }, [interval, min, max, use12h]);
516
- const displayValue = React10.useMemo(() => {
517
- if (!value) return "";
518
- const [h, m] = value.split(":").map(Number);
519
- return use12h ? formatTime12(h, m) : formatTime24(h, m);
520
- }, [value, use12h]);
521
- function handleKeyDown(e) {
522
- if (readOnly) return;
523
- if (e.key === "ArrowDown" || e.key === "ArrowUp") {
524
- e.preventDefault();
525
- const idx = slots.findIndex((s) => s.value === value);
526
- const next = e.key === "ArrowDown" ? Math.min(idx + 1, slots.length - 1) : Math.max(idx - 1, 0);
527
- if (slots[next]) onChange(slots[next].value);
528
- } else if (e.key === "Enter" || e.key === "Escape") {
529
- setOpen(false);
530
- }
531
- }
532
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: `relative ${className ?? ""}`, children: [
533
- /* @__PURE__ */ jsxRuntime.jsxs(
534
- "button",
535
- {
536
- ref: triggerRef,
537
- type: "button",
538
- onClick: () => !readOnly && setOpen((p) => !p),
539
- onKeyDown: handleKeyDown,
540
- disabled: readOnly,
541
- className: `flex items-center gap-2 rounded-lg border px-3 py-2 text-sm w-full text-left transition-colors ${readOnly ? "bg-muted/40 text-muted-foreground cursor-default" : "bg-background hover:bg-muted/30"}`,
542
- children: [
543
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" }),
544
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: displayValue || "--:--" })
545
- ]
546
- }
547
- ),
548
- open && !readOnly && reactDom.createPortal(
549
- /* @__PURE__ */ jsxRuntime.jsx(
550
- "div",
551
- {
552
- ref: listRef,
553
- "data-modal-passthrough": true,
554
- style: { position: "fixed", top: pos.top, left: pos.left, width: pos.width, zIndex: 9999, pointerEvents: "auto" },
555
- className: "fayz-glass-surface min-w-[120px] max-h-48 overflow-y-auto rounded-xl border bg-popover shadow-xl py-1",
556
- children: slots.map((slot) => {
557
- const selected = slot.value === value;
558
- return /* @__PURE__ */ jsxRuntime.jsx(
559
- "button",
560
- {
561
- type: "button",
562
- "data-selected": selected,
563
- onClick: () => {
564
- onChange(slot.value);
565
- setOpen(false);
566
- },
567
- className: `block w-full px-3 py-1.5 text-sm text-left transition-colors ${selected ? "bg-primary/10 text-primary font-medium" : "hover:bg-muted/50"}`,
568
- children: slot.label
569
- },
570
- slot.value
571
- );
572
- })
573
- }
574
- ),
575
- document.body
576
- )
577
- ] });
578
- }
579
- function Skeleton({
580
- className,
581
- ...props
582
- }) {
583
- return /* @__PURE__ */ jsxRuntime.jsx(
584
- "div",
585
- {
586
- className: chunkH6OULCHF_cjs.cn("animate-pulse rounded-md bg-muted", className),
587
- ...props
588
- }
589
- );
590
- }
591
- function TableSkeleton({ columns = 4, rows = 2 }) {
592
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border overflow-hidden", children: [
593
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b bg-muted/30 flex gap-4 px-4 py-2.5", children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 flex-1 rounded bg-muted-foreground/10" }, i)) }),
594
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y", children: Array.from({ length: rows }).map((_, r) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4 px-4 py-3.5", children: Array.from({ length: columns }).map((_2, c) => /* @__PURE__ */ jsxRuntime.jsx(
595
- Skeleton,
596
- {
597
- className: chunkH6OULCHF_cjs.cn(
598
- "h-3 rounded",
599
- c === 0 ? "flex-[2]" : "flex-1"
600
- )
601
- },
602
- c
603
- )) }, r)) })
604
- ] });
605
- }
606
- function ListView({
607
- columns,
608
- data,
609
- loading = false,
610
- searchPlaceholder = "Search...",
611
- search: controlledSearch,
612
- onSearchChange,
613
- searchDebounce = 300,
614
- tags,
615
- allTagLabel = "All",
616
- activeTag,
617
- onTagChange,
618
- newLabel,
619
- onNew,
620
- onRowClick,
621
- emptyIcon: EmptyIcon,
622
- emptyMessage = "No results found.",
623
- emptyActionLabel,
624
- onEmptyAction,
625
- total,
626
- page = 1,
627
- pageSize = 25,
628
- onPageChange,
629
- toolbar,
630
- className
631
- }) {
632
- const [internalSearch, setInternalSearch] = React10.useState(controlledSearch ?? "");
633
- const debounceRef = React10.useRef();
634
- React10.useEffect(() => {
635
- if (controlledSearch !== void 0) setInternalSearch(controlledSearch);
636
- }, [controlledSearch]);
637
- const handleSearchChange = React10.useCallback((value) => {
638
- setInternalSearch(value);
639
- if (searchDebounce === 0) {
640
- onSearchChange?.(value);
641
- } else {
642
- if (debounceRef.current) clearTimeout(debounceRef.current);
643
- debounceRef.current = setTimeout(() => onSearchChange?.(value), searchDebounce);
644
- }
645
- }, [onSearchChange, searchDebounce]);
646
- const totalItems = total ?? data.length;
647
- const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
648
- const showPagination = onPageChange && totalItems > pageSize;
649
- const showSearch = !!onSearchChange;
650
- const showTags = tags && tags.length > 0 && onTagChange;
651
- const showToolbar = showSearch || onNew || showTags;
652
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn("space-y-4", className), children: [
653
- showToolbar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row gap-3 sm:items-center sm:justify-between", children: [
654
- showSearch && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 max-w-sm", children: [
655
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" }),
656
- /* @__PURE__ */ jsxRuntime.jsx(
657
- "input",
658
- {
659
- type: "text",
660
- placeholder: searchPlaceholder,
661
- value: internalSearch,
662
- onChange: (e) => handleSearchChange(e.target.value),
663
- className: "w-full rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] pl-8 pr-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring"
664
- }
665
- )
666
- ] }),
667
- onNew && newLabel && /* @__PURE__ */ jsxRuntime.jsxs(chunkH6OULCHF_cjs.Button, { variant: "default", size: "default", onClick: onNew, className: "shrink-0", children: [
668
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
669
- newLabel
670
- ] })
671
- ] }),
672
- showTags && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 flex-wrap", children: [
673
- /* @__PURE__ */ jsxRuntime.jsx(
674
- "button",
675
- {
676
- onClick: () => onTagChange(void 0),
677
- className: chunkH6OULCHF_cjs.cn(
678
- "rounded-full px-2.5 py-1 text-xs font-medium transition-colors",
679
- !activeTag ? "bg-primary text-primary-foreground" : "bg-muted/50 text-muted-foreground hover:bg-muted"
680
- ),
681
- children: allTagLabel
682
- }
683
- ),
684
- tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(
685
- "button",
686
- {
687
- onClick: () => onTagChange(tag.value),
688
- className: chunkH6OULCHF_cjs.cn(
689
- "rounded-full px-2.5 py-1 text-xs font-medium transition-colors",
690
- activeTag === tag.value ? "bg-primary text-primary-foreground" : "bg-muted/50 text-muted-foreground hover:bg-muted"
691
- ),
692
- children: tag.label
693
- },
694
- tag.value
695
- ))
696
- ] }),
697
- toolbar,
698
- loading ? /* @__PURE__ */ jsxRuntime.jsx(chunkMI6FOB4O_cjs.DataTable, { columns, data: [], loading: true, variant: "card" }) : data.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center rounded-lg border-2 border-dashed border-muted", children: [
699
- EmptyIcon && /* @__PURE__ */ jsxRuntime.jsx(EmptyIcon, { className: "h-8 w-8 text-muted-foreground/30 mb-2" }),
700
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: emptyMessage }),
701
- emptyActionLabel && onEmptyAction && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onEmptyAction, className: "text-xs text-primary hover:underline mt-1", children: emptyActionLabel })
702
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
703
- chunkMI6FOB4O_cjs.DataTable,
704
- {
705
- columns,
706
- data,
707
- onRowClick,
708
- variant: "card"
709
- }
710
- ),
711
- showPagination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-1", children: [
712
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
713
- (page - 1) * pageSize + 1,
714
- "\u2013",
715
- Math.min(page * pageSize, totalItems),
716
- " of ",
717
- totalItems
718
- ] }),
719
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
720
- /* @__PURE__ */ jsxRuntime.jsx(
721
- "button",
722
- {
723
- onClick: () => onPageChange(page - 1),
724
- disabled: page <= 1,
725
- className: "flex h-7 w-7 items-center justify-center rounded-md border hover:bg-muted bg-card shadow-button active:shadow-button-inset transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
726
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-3.5 w-3.5" })
727
- }
728
- ),
729
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground px-2", children: [
730
- page,
731
- " / ",
732
- totalPages
733
- ] }),
734
- /* @__PURE__ */ jsxRuntime.jsx(
735
- "button",
736
- {
737
- onClick: () => onPageChange(page + 1),
738
- disabled: page >= totalPages,
739
- className: "flex h-7 w-7 items-center justify-center rounded-md border hover:bg-muted bg-card shadow-button active:shadow-button-inset transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
740
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-3.5 w-3.5" })
741
- }
742
- )
743
- ] })
744
- ] })
745
- ] });
746
- }
747
- var DAY_LABELS = {
748
- en: ["S", "M", "T", "W", "T", "F", "S"],
749
- "pt-BR": ["D", "S", "T", "Q", "Q", "S", "S"]
750
- };
751
- function toDateLocale(locale) {
752
- if (locale === "pt-BR") return "pt-BR";
753
- return "en-US";
754
- }
755
- function isSameDay(a, b) {
756
- return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
757
- }
758
- function isToday(d) {
759
- return isSameDay(d, /* @__PURE__ */ new Date());
760
- }
761
- function formatDate(date, locale) {
762
- return date.toLocaleDateString(toDateLocale(locale), { month: "short", day: "numeric", year: "numeric" });
763
- }
764
- function toDateStr(d) {
765
- return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
766
- }
767
- function parseDate(s) {
768
- const [y, m, d] = s.split("-").map(Number);
769
- return new Date(y, m - 1, d);
770
- }
771
- function DatePicker({ value, onChange, className, defaultOpen, onOpenChange }) {
772
- const t = core.useTranslation();
773
- const locale = core.getCurrentLocale();
774
- const [open, setOpen] = React10.useState(defaultOpen ?? false);
775
- const ref = React10.useRef(null);
776
- const triggerRef = React10.useRef(null);
777
- const dropdownRef = React10.useRef(null);
778
- const selectedDate = value ? parseDate(value) : /* @__PURE__ */ new Date();
779
- const [viewMonth, setViewMonth] = React10.useState(new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
780
- const [pos, setPos] = React10.useState({ top: 0, left: 0 });
781
- const dayLabels = DAY_LABELS[locale] ?? DAY_LABELS.en;
782
- const dateLocale = toDateLocale(locale);
783
- React10.useEffect(() => {
784
- if (!open || !triggerRef.current) return;
785
- const rect = triggerRef.current.getBoundingClientRect();
786
- const dropW = 260;
787
- let left = rect.left;
788
- if (left + dropW > window.innerWidth - 12) left = window.innerWidth - dropW - 12;
789
- if (left < 8) left = 8;
790
- setPos({ top: rect.bottom + 4, left });
791
- }, [open]);
792
- React10.useEffect(() => {
793
- if (!open) return;
794
- const handler = (e) => {
795
- const target = e.target;
796
- if (ref.current?.contains(target)) return;
797
- if (dropdownRef.current?.contains(target)) return;
798
- setOpen(false);
799
- onOpenChange?.(false);
800
- };
801
- document.addEventListener("mousedown", handler);
802
- return () => document.removeEventListener("mousedown", handler);
803
- }, [open, onOpenChange]);
804
- React10.useEffect(() => {
805
- if (value) {
806
- const d = parseDate(value);
807
- setViewMonth(new Date(d.getFullYear(), d.getMonth(), 1));
808
- }
809
- }, [value]);
810
- const monthLabel = viewMonth.toLocaleDateString(dateLocale, { month: "long", year: "numeric" });
811
- const weeks = React10.useMemo(() => {
812
- const year = viewMonth.getFullYear();
813
- const month = viewMonth.getMonth();
814
- const firstDay = new Date(year, month, 1);
815
- const startOffset = firstDay.getDay();
816
- const daysInMonth = new Date(year, month + 1, 0).getDate();
817
- const prevMonthDays = new Date(year, month, 0).getDate();
818
- const cells = [];
819
- for (let i = startOffset - 1; i >= 0; i--) {
820
- cells.push({ date: new Date(year, month - 1, prevMonthDays - i), inMonth: false });
821
- }
822
- for (let d = 1; d <= daysInMonth; d++) {
823
- cells.push({ date: new Date(year, month, d), inMonth: true });
824
- }
825
- while (cells.length % 7 !== 0) {
826
- cells.push({ date: new Date(year, month + 1, cells.length - startOffset - daysInMonth + 1), inMonth: false });
827
- }
828
- const rows = [];
829
- for (let i = 0; i < cells.length; i += 7) rows.push(cells.slice(i, i + 7));
830
- return rows;
831
- }, [viewMonth]);
832
- function handleSelect(date) {
833
- onChange(toDateStr(date));
834
- setOpen(false);
835
- }
836
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: `relative ${className ?? ""}`, children: [
837
- /* @__PURE__ */ jsxRuntime.jsxs(
838
- "button",
839
- {
840
- ref: triggerRef,
841
- type: "button",
842
- onClick: () => setOpen((p) => !p),
843
- className: "flex items-center gap-2 rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] px-3 py-2 text-sm hover:bg-muted/30 transition-colors w-full text-left",
844
- children: [
845
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" }),
846
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: value ? formatDate(selectedDate, locale) : t("common.selectDate") })
847
- ]
848
- }
849
- ),
850
- open && reactDom.createPortal(
851
- /* @__PURE__ */ jsxRuntime.jsxs(
852
- "div",
853
- {
854
- ref: dropdownRef,
855
- "data-modal-passthrough": true,
856
- style: { position: "fixed", top: pos.top, left: pos.left, zIndex: 9999, pointerEvents: "auto" },
857
- className: "fayz-glass-surface rounded-xl border bg-popover shadow-xl p-3 w-[260px]",
858
- children: [
859
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
860
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium capitalize", children: monthLabel }),
861
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
862
- /* @__PURE__ */ jsxRuntime.jsx(
863
- "button",
864
- {
865
- type: "button",
866
- onClick: () => setViewMonth(new Date(viewMonth.getFullYear(), viewMonth.getMonth() - 1, 1)),
867
- className: "flex h-7 w-7 items-center justify-center rounded-full hover:bg-muted transition-colors",
868
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" })
869
- }
870
- ),
871
- /* @__PURE__ */ jsxRuntime.jsx(
872
- "button",
873
- {
874
- type: "button",
875
- onClick: () => setViewMonth(new Date(viewMonth.getFullYear(), viewMonth.getMonth() + 1, 1)),
876
- className: "flex h-7 w-7 items-center justify-center rounded-full hover:bg-muted transition-colors",
877
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
878
- }
879
- )
880
- ] })
881
- ] }),
882
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 mb-1", children: dayLabels.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-8 items-center justify-center text-[11px] font-medium text-muted-foreground", children: l }, i)) }),
883
- weeks.map((week, wi) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7", children: week.map(({ date, inMonth }, di) => {
884
- const sel = value && isSameDay(date, selectedDate);
885
- const today = isToday(date);
886
- return /* @__PURE__ */ jsxRuntime.jsx(
887
- "button",
888
- {
889
- type: "button",
890
- onClick: () => handleSelect(date),
891
- className: `flex h-8 w-8 items-center justify-center rounded-full text-xs mx-auto transition-colors ${sel ? "bg-primary text-primary-foreground font-semibold" : today ? "bg-primary/10 text-primary font-semibold" : inMonth ? "hover:bg-muted text-foreground" : "text-muted-foreground/40 hover:bg-muted/50"}`,
892
- children: date.getDate()
893
- },
894
- di
895
- );
896
- }) }, wi)),
897
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 pt-2 border-t", children: /* @__PURE__ */ jsxRuntime.jsx(
898
- "button",
899
- {
900
- type: "button",
901
- onClick: () => {
902
- handleSelect(/* @__PURE__ */ new Date());
903
- },
904
- className: "text-xs text-primary font-medium hover:underline",
905
- children: t("agenda.calendar.today")
906
- }
907
- ) })
908
- ]
909
- }
910
- ),
911
- document.body
912
- )
913
- ] });
914
- }
915
- function SearchSelect({
916
- value,
917
- displayValue,
918
- onChange,
919
- onSearch,
920
- placeholder = "Search...",
921
- label,
922
- required,
923
- debounce = 250,
924
- minChars = 1,
925
- allowCreate,
926
- createLabel = "Add",
927
- onCreate,
928
- renderOption,
929
- loadOnOpen,
930
- className,
931
- disabled
932
- }) {
933
- const [open, setOpen] = React10__namespace.useState(false);
934
- const [query, setQuery] = React10__namespace.useState("");
935
- const [results, setResults] = React10__namespace.useState([]);
936
- const [loading, setLoading] = React10__namespace.useState(false);
937
- const [creating, setCreating] = React10__namespace.useState(false);
938
- const [selectedLabel, setSelectedLabel] = React10__namespace.useState(displayValue ?? "");
939
- const containerRef = React10__namespace.useRef(null);
940
- const inputRef = React10__namespace.useRef(null);
941
- const timerRef = React10__namespace.useRef();
942
- React10__namespace.useEffect(() => {
943
- function handler(e) {
944
- if (containerRef.current && !containerRef.current.contains(e.target)) {
945
- setOpen(false);
946
- }
947
- }
948
- document.addEventListener("mousedown", handler);
949
- return () => document.removeEventListener("mousedown", handler);
950
- }, []);
951
- React10__namespace.useEffect(() => {
952
- if (displayValue !== void 0) setSelectedLabel(displayValue);
953
- }, [displayValue]);
954
- React10__namespace.useEffect(() => {
955
- if (open && loadOnOpen && query.length === 0 && results.length === 0 && !loading) {
956
- setLoading(true);
957
- Promise.resolve(onSearch("")).then(setResults).catch(() => setResults([])).finally(() => setLoading(false));
958
- }
959
- }, [open, loadOnOpen]);
960
- function handleQueryChange(q) {
961
- setQuery(q);
962
- if (timerRef.current) clearTimeout(timerRef.current);
963
- if (q.length < minChars && !(loadOnOpen && q.length === 0)) {
964
- setResults([]);
965
- setLoading(false);
966
- return;
967
- }
968
- setLoading(true);
969
- timerRef.current = setTimeout(async () => {
970
- try {
971
- const res = await onSearch(q);
972
- setResults(res);
973
- } catch {
974
- setResults([]);
975
- }
976
- setLoading(false);
977
- }, debounce);
978
- }
979
- function handleSelect(option) {
980
- onChange(option.id, option);
981
- setSelectedLabel(option.label);
982
- setOpen(false);
983
- setQuery("");
984
- setResults([]);
985
- }
986
- function handleClear() {
987
- onChange("", null);
988
- setSelectedLabel("");
989
- setQuery("");
990
- setResults([]);
991
- }
992
- async function handleCreate(name) {
993
- if (!onCreate) return;
994
- setCreating(true);
995
- setSelectedLabel(name);
996
- setOpen(false);
997
- setQuery("");
998
- setResults([]);
999
- try {
1000
- await onCreate(name);
1001
- } finally {
1002
- setCreating(false);
1003
- }
1004
- }
1005
- function handleOpen() {
1006
- if (disabled || creating) return;
1007
- setOpen(true);
1008
- setQuery("");
1009
- setTimeout(() => inputRef.current?.focus(), 0);
1010
- }
1011
- const groups = React10__namespace.useMemo(() => {
1012
- const map = /* @__PURE__ */ new Map();
1013
- for (const opt of results) {
1014
- const group = opt.group ?? "";
1015
- if (!map.has(group)) map.set(group, []);
1016
- map.get(group).push(opt);
1017
- }
1018
- return map;
1019
- }, [results]);
1020
- const hasValue = !!value && !!selectedLabel;
1021
- const showDropdown = open && query.length >= minChars;
1022
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: chunkH6OULCHF_cjs.cn("relative", className), children: [
1023
- label && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "text-xs font-medium text-muted-foreground", children: [
1024
- label,
1025
- required && " *"
1026
- ] }),
1027
- /* @__PURE__ */ jsxRuntime.jsxs(
1028
- "div",
1029
- {
1030
- className: chunkH6OULCHF_cjs.cn(
1031
- "mt-1 flex items-center gap-2 rounded-lg border bg-background transition-colors",
1032
- open ? "ring-2 ring-primary/20" : "hover:bg-muted/30",
1033
- disabled && "opacity-50 cursor-not-allowed"
1034
- ),
1035
- children: [
1036
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "h-3.5 w-3.5 text-muted-foreground ml-3 shrink-0" }),
1037
- open ? /* @__PURE__ */ jsxRuntime.jsx(
1038
- "input",
1039
- {
1040
- ref: inputRef,
1041
- type: "text",
1042
- value: query,
1043
- onChange: (e) => handleQueryChange(e.target.value),
1044
- placeholder,
1045
- className: "flex-1 bg-transparent py-2 pr-3 text-sm outline-none",
1046
- onKeyDown: (e) => {
1047
- if (e.key === "Escape") setOpen(false);
1048
- }
1049
- }
1050
- ) : /* @__PURE__ */ jsxRuntime.jsx(
1051
- "button",
1052
- {
1053
- type: "button",
1054
- onClick: handleOpen,
1055
- className: "flex-1 text-left py-2 pr-3 text-sm outline-none",
1056
- disabled: disabled || creating,
1057
- children: creating ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
1058
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3 w-3 animate-spin" }),
1059
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: selectedLabel })
1060
- ] }) : hasValue ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: selectedLabel }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: placeholder })
1061
- }
1062
- ),
1063
- hasValue && !open && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleClear, className: "pr-3 text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" }) }),
1064
- !hasValue && !open && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3 text-muted-foreground mr-3 shrink-0" })
1065
- ]
1066
- }
1067
- ),
1068
- showDropdown && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fayz-glass-surface absolute top-full left-0 right-0 z-50 mt-1 rounded-lg border bg-popover shadow-lg overflow-hidden", children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 px-4 py-6 text-xs text-muted-foreground", children: [
1069
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
1070
- " Searching..."
1071
- ] }) : results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-4 text-center", children: [
1072
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
1073
- 'No results for "',
1074
- query,
1075
- '"'
1076
- ] }),
1077
- allowCreate && onCreate && /* @__PURE__ */ jsxRuntime.jsxs(
1078
- "button",
1079
- {
1080
- onClick: () => handleCreate(query),
1081
- className: "mt-2 text-xs text-primary hover:underline",
1082
- children: [
1083
- "+ ",
1084
- createLabel,
1085
- ' "',
1086
- query,
1087
- '"'
1088
- ]
1089
- }
1090
- )
1091
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-64 overflow-auto py-1", children: [
1092
- [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxRuntime.jsxs(React10__namespace.Fragment, { children: [
1093
- group && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 bg-muted/50 px-3 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
1094
- options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
1095
- "button",
1096
- {
1097
- onClick: () => handleSelect(opt),
1098
- disabled: opt.disabled,
1099
- className: chunkH6OULCHF_cjs.cn(
1100
- "w-full text-left px-3 py-2 hover:bg-muted/50 transition-colors flex items-center gap-2.5",
1101
- opt.disabled && "opacity-40 cursor-not-allowed",
1102
- opt.id === value && "bg-muted/30"
1103
- ),
1104
- children: renderOption ? renderOption(opt) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1105
- opt.icon,
1106
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
1107
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm truncate", children: opt.label }),
1108
- opt.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground truncate", children: opt.subtitle })
1109
- ] })
1110
- ] })
1111
- },
1112
- opt.id
1113
- ))
1114
- ] }, group)),
1115
- allowCreate && onCreate && /* @__PURE__ */ jsxRuntime.jsxs(
1116
- "button",
1117
- {
1118
- onClick: () => handleCreate(query),
1119
- className: "w-full text-left px-3 py-2 text-xs text-primary hover:bg-muted/50 transition-colors border-t",
1120
- children: [
1121
- "+ ",
1122
- createLabel,
1123
- ' "',
1124
- query,
1125
- '"'
1126
- ]
1127
- }
1128
- )
1129
- ] }) })
1130
- ] });
1131
- }
1132
- function CurrencyInput({
1133
- value,
1134
- onChange,
1135
- symbol = "R$",
1136
- locale = "pt-BR",
1137
- currencyCode = "BRL",
1138
- label,
1139
- placeholder,
1140
- className,
1141
- disabled
1142
- }) {
1143
- const inputRef = React10__namespace.useRef(null);
1144
- const [focused, setFocused] = React10__namespace.useState(false);
1145
- const format = React10__namespace.useCallback((v) => {
1146
- return new Intl.NumberFormat(locale, {
1147
- minimumFractionDigits: 2,
1148
- maximumFractionDigits: 2
1149
- }).format(v);
1150
- }, [locale]);
1151
- const displayValue = format(value);
1152
- function handleKeyDown(e) {
1153
- if (disabled) return;
1154
- if (["Tab", "Escape", "ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key)) return;
1155
- e.preventDefault();
1156
- if (e.key === "Backspace" || e.key === "Delete") {
1157
- const cents = Math.floor(Math.round(value * 100) / 10);
1158
- onChange(cents / 100);
1159
- return;
1160
- }
1161
- if (!/^\d$/.test(e.key)) return;
1162
- const currentCents = Math.round(value * 100);
1163
- const newCents = currentCents * 10 + parseInt(e.key, 10);
1164
- if (newCents > 99999999999) return;
1165
- onChange(newCents / 100);
1166
- }
1167
- function handlePaste(e) {
1168
- e.preventDefault();
1169
- const text = e.clipboardData.getData("text");
1170
- const cleaned = text.replace(/[^\d.,]/g, "");
1171
- const normalized = cleaned.replace(",", ".");
1172
- const parsed = parseFloat(normalized);
1173
- if (!isNaN(parsed)) {
1174
- onChange(Math.round(parsed * 100) / 100);
1175
- }
1176
- }
1177
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
1178
- label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-xs font-medium text-muted-foreground", children: label }),
1179
- /* @__PURE__ */ jsxRuntime.jsxs(
1180
- "div",
1181
- {
1182
- className: chunkH6OULCHF_cjs.cn(
1183
- "flex items-center rounded-lg border border-input bg-background ring-offset-background transition-colors cursor-text",
1184
- label && "mt-1",
1185
- focused && "border-ring ring-2 ring-ring ring-offset-2",
1186
- disabled && "opacity-50 cursor-not-allowed"
1187
- ),
1188
- onClick: () => inputRef.current?.focus(),
1189
- children: [
1190
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pl-3 pr-1 text-sm font-medium text-muted-foreground select-none", children: symbol }),
1191
- /* @__PURE__ */ jsxRuntime.jsx(
1192
- "input",
1193
- {
1194
- ref: inputRef,
1195
- type: "text",
1196
- inputMode: "numeric",
1197
- value: displayValue,
1198
- onKeyDown: handleKeyDown,
1199
- onPaste: handlePaste,
1200
- onFocus: () => setFocused(true),
1201
- onBlur: () => setFocused(false),
1202
- placeholder: placeholder ?? format(0),
1203
- disabled,
1204
- readOnly: false,
1205
- className: "flex-1 bg-transparent px-2 py-2 text-sm outline-none text-right tabular-nums caret-primary selection:bg-primary/20",
1206
- onChange: () => {
1207
- }
1208
- }
1209
- )
1210
- ]
1211
- }
1212
- )
1213
- ] });
1214
- }
1215
- var VARIANT_CONFIG = {
1216
- default: {
1217
- icon: lucideReact.Info,
1218
- iconBg: "bg-info/10",
1219
- iconColor: "text-info",
1220
- buttonVariant: "default"
1221
- },
1222
- destructive: {
1223
- icon: lucideReact.XCircle,
1224
- iconBg: "bg-destructive/10",
1225
- iconColor: "text-destructive",
1226
- buttonVariant: "destructive"
1227
- },
1228
- warning: {
1229
- icon: lucideReact.AlertTriangle,
1230
- iconBg: "bg-warning/10",
1231
- iconColor: "text-warning",
1232
- buttonVariant: "destructive"
1233
- },
1234
- success: {
1235
- icon: lucideReact.CheckCircle2,
1236
- iconBg: "bg-success/10",
1237
- iconColor: "text-success",
1238
- buttonVariant: "default"
1239
- }
1240
- };
1241
- function ConfirmDialog({
1242
- open,
1243
- onConfirm,
1244
- onCancel,
1245
- title,
1246
- description,
1247
- confirmLabel = "Confirm",
1248
- cancelLabel = "Cancel",
1249
- variant = "default",
1250
- loading = false
1251
- }) {
1252
- const config = VARIANT_CONFIG[variant];
1253
- const Icon2 = config.icon;
1254
- React10__namespace.useEffect(() => {
1255
- if (!open) return;
1256
- function handleKey(e) {
1257
- if (e.key === "Escape") onCancel();
1258
- }
1259
- document.addEventListener("keydown", handleKey);
1260
- return () => document.removeEventListener("keydown", handleKey);
1261
- }, [open, onCancel]);
1262
- if (!open) return null;
1263
- return reactDom.createPortal(
1264
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed inset-0 z-[60] flex items-center justify-center", children: [
1265
- /* @__PURE__ */ jsxRuntime.jsx(
1266
- "div",
1267
- {
1268
- className: "absolute inset-0 bg-black/50 backdrop-blur-[2px] animate-fade-in",
1269
- onClick: onCancel
1270
- }
1271
- ),
1272
- /* @__PURE__ */ jsxRuntime.jsx(
1273
- "div",
1274
- {
1275
- className: "relative z-10 w-full max-w-sm mx-4 rounded-modal border border-border bg-card shadow-lg animate-zoom-in",
1276
- role: "alertdialog",
1277
- "aria-modal": "true",
1278
- "aria-labelledby": "confirm-title",
1279
- "aria-describedby": description ? "confirm-desc" : void 0,
1280
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6", children: [
1281
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4", children: [
1282
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("flex h-10 w-10 items-center justify-center rounded-full shrink-0", config.iconBg), children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: chunkH6OULCHF_cjs.cn("h-5 w-5", config.iconColor) }) }),
1283
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 pt-0.5", children: [
1284
- /* @__PURE__ */ jsxRuntime.jsx("h3", { id: "confirm-title", className: "text-sm font-semibold text-foreground", children: title }),
1285
- description && /* @__PURE__ */ jsxRuntime.jsx("p", { id: "confirm-desc", className: "text-xs text-muted-foreground mt-1 leading-relaxed", children: description })
1286
- ] })
1287
- ] }),
1288
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 mt-5", children: [
1289
- /* @__PURE__ */ jsxRuntime.jsx(chunkH6OULCHF_cjs.Button, { variant: "outline", size: "sm", onClick: onCancel, disabled: loading, children: cancelLabel }),
1290
- /* @__PURE__ */ jsxRuntime.jsx(chunkH6OULCHF_cjs.Button, { variant: config.buttonVariant, size: "sm", onClick: onConfirm, disabled: loading, children: loading ? "Processing..." : confirmLabel })
1291
- ] })
1292
- ] })
1293
- }
1294
- )
1295
- ] }),
1296
- document.body
1297
- );
1298
- }
1299
- var Popover = PopoverPrimitive__namespace.Root;
1300
- var PopoverTrigger = PopoverPrimitive__namespace.Trigger;
1301
- var PopoverContent = React10__namespace.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
1302
- PopoverPrimitive__namespace.Content,
1303
- {
1304
- ref,
1305
- align,
1306
- sideOffset,
1307
- className: chunkH6OULCHF_cjs.cn(
1308
- "fayz-glass-surface z-[110] w-72 rounded-xl border bg-popover p-0 text-popover-foreground shadow-lg outline-none",
1309
- "data-[state=open]:animate-zoom-in data-[state=closed]:animate-zoom-out",
1310
- className
1311
- ),
1312
- ...props
1313
- }
1314
- ) }));
1315
- PopoverContent.displayName = PopoverPrimitive__namespace.Content.displayName;
1316
- var INLINE_TOKEN = /(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`)/g;
1317
- function renderInline(text, keyPrefix) {
1318
- return text.split(INLINE_TOKEN).map((part, i) => {
1319
- const key = `${keyPrefix}-${i}`;
1320
- if (part.startsWith("**") && part.endsWith("**") && part.length > 4) {
1321
- return /* @__PURE__ */ jsxRuntime.jsx("strong", { children: part.slice(2, -2) }, key);
1322
- }
1323
- if (part.startsWith("*") && part.endsWith("*") && part.length > 2) {
1324
- return /* @__PURE__ */ jsxRuntime.jsx("em", { children: part.slice(1, -1) }, key);
1325
- }
1326
- if (part.startsWith("`") && part.endsWith("`") && part.length > 2) {
1327
- return /* @__PURE__ */ jsxRuntime.jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]", children: part.slice(1, -1) }, key);
1328
- }
1329
- return part === "" ? null : /* @__PURE__ */ jsxRuntime.jsx(React10__namespace.Fragment, { children: part }, key);
1330
- });
1331
- }
1332
- function parseBlocks(source) {
1333
- const lines = source.replace(/\r\n/g, "\n").split("\n");
1334
- const blocks = [];
1335
- let i = 0;
1336
- while (i < lines.length) {
1337
- const line = lines[i];
1338
- const trimmed = line.trim();
1339
- if (trimmed === "") {
1340
- i++;
1341
- continue;
1342
- }
1343
- const heading = /^(#{1,3})\s+(.*)$/.exec(trimmed);
1344
- if (heading) {
1345
- blocks.push({ type: "heading", level: heading[1].length, text: heading[2] });
1346
- i++;
1347
- continue;
1348
- }
1349
- if (/^(-{3,}|\*{3,})$/.test(trimmed)) {
1350
- blocks.push({ type: "hr" });
1351
- i++;
1352
- continue;
1353
- }
1354
- if (trimmed.startsWith(">")) {
1355
- const quote = [];
1356
- while (i < lines.length && lines[i].trim().startsWith(">")) {
1357
- quote.push(lines[i].trim().replace(/^>\s?/, ""));
1358
- i++;
1359
- }
1360
- blocks.push({ type: "blockquote", lines: quote });
1361
- continue;
1362
- }
1363
- if (/^[-*]\s+/.test(trimmed)) {
1364
- const items = [];
1365
- while (i < lines.length && /^[-*]\s+/.test(lines[i].trim())) {
1366
- items.push(lines[i].trim().replace(/^[-*]\s+/, ""));
1367
- i++;
1368
- }
1369
- blocks.push({ type: "ul", items });
1370
- continue;
1371
- }
1372
- if (/^\d+[.)]\s+/.test(trimmed)) {
1373
- const items = [];
1374
- while (i < lines.length && /^\d+[.)]\s+/.test(lines[i].trim())) {
1375
- items.push(lines[i].trim().replace(/^\d+[.)]\s+/, ""));
1376
- i++;
1377
- }
1378
- blocks.push({ type: "ol", items });
1379
- continue;
1380
- }
1381
- const para = [];
1382
- while (i < lines.length && lines[i].trim() !== "" && !/^(#{1,3}\s|>|[-*]\s|\d+[.)]\s|-{3,}$|\*{3,}$)/.test(lines[i].trim())) {
1383
- para.push(lines[i].trim());
1384
- i++;
1385
- }
1386
- blocks.push({ type: "p", lines: para });
1387
- }
1388
- return blocks;
1389
- }
1390
- var HEADING_CLASS = {
1391
- 1: "text-xl font-semibold tracking-tight",
1392
- 2: "text-base font-semibold tracking-tight",
1393
- 3: "text-sm font-semibold"
1394
- };
1395
- function renderMarkdown(source) {
1396
- const blocks = parseBlocks(source);
1397
- return blocks.map((block, bi) => {
1398
- const key = `md-${bi}`;
1399
- switch (block.type) {
1400
- case "heading": {
1401
- const Tag = `h${block.level}`;
1402
- return /* @__PURE__ */ jsxRuntime.jsx(Tag, { className: HEADING_CLASS[block.level], children: renderInline(block.text, key) }, key);
1403
- }
1404
- case "hr":
1405
- return /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-border" }, key);
1406
- case "blockquote":
1407
- return /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: "border-l-2 border-border pl-3 text-muted-foreground", children: block.lines.map((l, li) => /* @__PURE__ */ jsxRuntime.jsx("p", { children: renderInline(l, `${key}-${li}`) }, `${key}-${li}`)) }, key);
1408
- case "ul":
1409
- return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc space-y-1 pl-5", children: block.items.map((item, li) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: renderInline(item, `${key}-${li}`) }, `${key}-${li}`)) }, key);
1410
- case "ol":
1411
- return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "list-decimal space-y-1 pl-5", children: block.items.map((item, li) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: renderInline(item, `${key}-${li}`) }, `${key}-${li}`)) }, key);
1412
- case "p":
1413
- return /* @__PURE__ */ jsxRuntime.jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxRuntime.jsxs(React10__namespace.Fragment, { children: [
1414
- li > 0 && /* @__PURE__ */ jsxRuntime.jsx("br", {}),
1415
- renderInline(l, `${key}-${li}`)
1416
- ] }, `${key}-${li}`)) }, key);
1417
- }
1418
- });
1419
- }
1420
- function Markdown({ source, className }) {
1421
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("space-y-3 text-sm leading-relaxed text-foreground", className), children: renderMarkdown(source) });
1422
- }
1423
- function MarkdownEditor({
1424
- value,
1425
- onChange,
1426
- placeholder,
1427
- minRows = 16,
1428
- defaultMode = "preview",
1429
- editLabel = "Edit",
1430
- previewLabel = "Preview",
1431
- renderPreview,
1432
- className
1433
- }) {
1434
- const [mode, setMode] = React10__namespace.useState(
1435
- defaultMode === "preview" && value.trim() === "" ? "edit" : defaultMode
1436
- );
1437
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn("flex flex-col gap-2", className), children: [
1438
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1439
- chunkMI6FOB4O_cjs.SegmentedControl,
1440
- {
1441
- "aria-label": "Markdown mode",
1442
- options: [
1443
- { value: "edit", label: editLabel },
1444
- { value: "preview", label: previewLabel }
1445
- ],
1446
- value: mode,
1447
- onChange: (m) => setMode(m)
1448
- }
1449
- ) }),
1450
- mode === "edit" ? /* @__PURE__ */ jsxRuntime.jsx(
1451
- "textarea",
1452
- {
1453
- value,
1454
- onChange: (e) => onChange(e.target.value),
1455
- placeholder,
1456
- rows: Math.max(minRows, value.split("\n").length + 1),
1457
- className: chunkH6OULCHF_cjs.cn(
1458
- "w-full resize-y rounded-md border border-border bg-card p-3",
1459
- "font-mono text-[13px] leading-relaxed text-foreground",
1460
- "placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring"
1461
- )
1462
- }
1463
- ) : renderPreview ? renderPreview(value) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-border bg-card p-4", children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { source: value }) })
1464
- ] });
1465
- }
1466
- function SearchCombobox({
1467
- value,
1468
- onChange,
1469
- onSelect,
1470
- options,
1471
- placeholder,
1472
- autoFocus,
1473
- onBlurEmpty,
1474
- renderRight,
1475
- allowCreate,
1476
- onCreateNew,
1477
- createLabel = "Create",
1478
- className,
1479
- minimal,
1480
- inlineLabel,
1481
- inlineIcon = "search",
1482
- loading,
1483
- onFocus: onFocusProp
1484
- }) {
1485
- const [open, setOpen] = React10.useState(false);
1486
- const [activeIndex, setActiveIndex] = React10.useState(-1);
1487
- const [expanded, setExpanded] = React10.useState(!inlineLabel);
1488
- const [dropRect, setDropRect] = React10.useState(null);
1489
- const inputRef = React10.useRef(null);
1490
- const wrapperRef = React10.useRef(null);
1491
- const listRef = React10.useRef(null);
1492
- React10.useEffect(() => {
1493
- if (value && inlineLabel) setExpanded(true);
1494
- if (!value && inlineLabel && !open) setExpanded(false);
1495
- }, [value, open]);
1496
- function updateRect() {
1497
- if (wrapperRef.current) setDropRect(wrapperRef.current.getBoundingClientRect());
1498
- }
1499
- const showCreate = open && allowCreate && onCreateNew && value.trim().length > 0 && !options.some((o) => o.label.toLowerCase() === value.trim().toLowerCase());
1500
- const totalItems = options.length + (showCreate ? 1 : 0);
1501
- React10.useEffect(() => {
1502
- setActiveIndex(-1);
1503
- }, [options]);
1504
- React10.useEffect(() => {
1505
- if ((options.length > 0 || showCreate || loading) && document.activeElement === inputRef.current) setOpen(true);
1506
- }, [options, showCreate, loading]);
1507
- const handleKeyDown = React10.useCallback((e) => {
1508
- if (!open || totalItems === 0) {
1509
- if (e.key === "ArrowDown" && totalItems > 0) {
1510
- e.preventDefault();
1511
- setOpen(true);
1512
- setActiveIndex(0);
1513
- }
1514
- return;
1515
- }
1516
- switch (e.key) {
1517
- case "ArrowDown":
1518
- e.preventDefault();
1519
- setActiveIndex((prev) => (prev + 1) % totalItems);
1520
- break;
1521
- case "ArrowUp":
1522
- e.preventDefault();
1523
- setActiveIndex((prev) => prev <= 0 ? totalItems - 1 : prev - 1);
1524
- break;
1525
- case "Enter":
1526
- e.preventDefault();
1527
- if (activeIndex >= 0 && activeIndex < options.length) {
1528
- onSelect(options[activeIndex]);
1529
- setOpen(false);
1530
- setActiveIndex(-1);
1531
- } else if (showCreate && activeIndex === options.length) {
1532
- onCreateNew?.(value.trim());
1533
- setOpen(false);
1534
- setActiveIndex(-1);
1535
- }
1536
- break;
1537
- case "Escape":
1538
- e.preventDefault();
1539
- setOpen(false);
1540
- setActiveIndex(-1);
1541
- break;
1542
- }
1543
- }, [open, options, totalItems, activeIndex, onSelect, showCreate, onCreateNew, value]);
1544
- React10.useEffect(() => {
1545
- if (activeIndex < 0 || !listRef.current) return;
1546
- const items = listRef.current.children;
1547
- if (items[activeIndex]) items[activeIndex].scrollIntoView({ block: "nearest" });
1548
- }, [activeIndex]);
1549
- function handleBlur() {
1550
- setTimeout(() => {
1551
- setOpen(false);
1552
- setActiveIndex(-1);
1553
- if (!value && onBlurEmpty) onBlurEmpty();
1554
- if (!value && inlineLabel) setExpanded(false);
1555
- }, 200);
1556
- }
1557
- const hasDropdown = open && (options.length > 0 || showCreate || loading);
1558
- if (!expanded && inlineLabel) {
1559
- const isPlus = inlineIcon === "plus";
1560
- return /* @__PURE__ */ jsxRuntime.jsxs(
1561
- "button",
1562
- {
1563
- type: "button",
1564
- onClick: () => {
1565
- setExpanded(true);
1566
- setTimeout(() => inputRef.current?.focus(), 50);
1567
- },
1568
- className: `flex items-center gap-1.5 w-full text-left text-sm py-1.5 pl-2 transition-colors ${isPlus ? "text-primary hover:text-primary/80" : "text-muted-foreground hover:text-foreground"} ${className ?? ""}`,
1569
- children: [
1570
- isPlus && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5 shrink-0" }),
1571
- inlineLabel
1572
- ]
1573
- }
1574
- );
1575
- }
1576
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: wrapperRef, className: `relative ${className ?? ""}`, children: [
1577
- !minimal && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground pointer-events-none" }),
1578
- /* @__PURE__ */ jsxRuntime.jsx(
1579
- "input",
1580
- {
1581
- ref: inputRef,
1582
- type: "text",
1583
- value,
1584
- onChange: (e) => {
1585
- onChange(e.target.value);
1586
- updateRect();
1587
- setOpen(true);
1588
- },
1589
- onFocus: () => {
1590
- updateRect();
1591
- onFocusProp?.();
1592
- if (options.length > 0 || showCreate || loading) setOpen(true);
1593
- },
1594
- onBlur: handleBlur,
1595
- onKeyDown: handleKeyDown,
1596
- placeholder,
1597
- autoFocus,
1598
- className: minimal ? "w-full bg-transparent pl-2 pr-3 py-1.5 text-sm placeholder:text-muted-foreground focus:outline-none border-b border-transparent hover:border-border focus:border-foreground transition-colors" : "w-full rounded-lg border bg-background pl-8 pr-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring",
1599
- role: "combobox",
1600
- "aria-expanded": hasDropdown,
1601
- "aria-autocomplete": "list",
1602
- "aria-activedescendant": activeIndex >= 0 ? `combobox-opt-${activeIndex}` : void 0
1603
- }
1604
- ),
1605
- hasDropdown && dropRect && reactDom.createPortal(
1606
- /* @__PURE__ */ jsxRuntime.jsxs(
1607
- "div",
1608
- {
1609
- ref: listRef,
1610
- role: "listbox",
1611
- "data-modal-passthrough": true,
1612
- style: { position: "fixed", left: dropRect.left, top: dropRect.bottom + 4, width: dropRect.width, zIndex: 9999, pointerEvents: "auto" },
1613
- className: "fayz-glass-surface max-h-52 overflow-y-auto rounded-lg border bg-popover shadow-lg py-0.5 animate-in fade-in zoom-in-95 duration-100",
1614
- children: [
1615
- loading && options.length === 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground", children: [
1616
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "h-3.5 w-3.5 animate-spin shrink-0", viewBox: "0 0 16 16", fill: "none", children: [
1617
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "6.5", stroke: "currentColor", strokeWidth: "1.5", opacity: "0.25" }),
1618
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14.5 8a6.5 6.5 0 00-6.5-6.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
1619
- ] }),
1620
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Buscando\u2026" })
1621
- ] }),
1622
- options.map((opt, i) => /* @__PURE__ */ jsxRuntime.jsxs(
1623
- "div",
1624
- {
1625
- id: `combobox-opt-${i}`,
1626
- role: "option",
1627
- "aria-selected": i === activeIndex,
1628
- onMouseDown: (e) => {
1629
- e.preventDefault();
1630
- onSelect(opt);
1631
- setOpen(false);
1632
- },
1633
- onMouseEnter: () => setActiveIndex(i),
1634
- className: `flex w-full items-center gap-2 px-3 py-2 text-sm cursor-pointer transition-colors ${i === activeIndex ? "bg-primary/10 text-primary" : "hover:bg-muted/50"}`,
1635
- children: [
1636
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
1637
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate font-medium", children: opt.label }),
1638
- opt.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-[11px] text-muted-foreground", children: opt.subtitle })
1639
- ] }),
1640
- renderRight && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: renderRight(opt) })
1641
- ]
1642
- },
1643
- opt.id
1644
- )),
1645
- showCreate && /* @__PURE__ */ jsxRuntime.jsxs(
1646
- "div",
1647
- {
1648
- id: `combobox-opt-${options.length}`,
1649
- role: "option",
1650
- "aria-selected": activeIndex === options.length,
1651
- onMouseDown: (e) => {
1652
- e.preventDefault();
1653
- onCreateNew?.(value.trim());
1654
- setOpen(false);
1655
- },
1656
- onMouseEnter: () => setActiveIndex(options.length),
1657
- className: `flex w-full items-center gap-2 px-3 py-2 text-sm cursor-pointer transition-colors border-t ${activeIndex === options.length ? "bg-primary/10 text-primary" : "hover:bg-muted/50"}`,
1658
- children: [
1659
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5 shrink-0" }),
1660
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1661
- createLabel,
1662
- " \u201C",
1663
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: value.trim() }),
1664
- "\u201D"
1665
- ] })
1666
- ]
1667
- }
1668
- )
1669
- ]
1670
- }
1671
- ),
1672
- document.body
1673
- )
1674
- ] });
1675
- }
1676
-
1677
- Object.defineProperty(exports, "toast", {
1678
- enumerable: true,
1679
- get: function () { return sonner.toast; }
1680
- });
1681
- exports.Badge = Badge;
1682
- exports.Breadcrumb = Breadcrumb;
1683
- exports.Checkbox = Checkbox;
1684
- exports.ConfirmDialog = ConfirmDialog;
1685
- exports.CurrencyInput = CurrencyInput;
1686
- exports.DatePicker = DatePicker;
1687
- exports.Input = Input;
1688
- exports.ListView = ListView;
1689
- exports.Markdown = Markdown;
1690
- exports.MarkdownEditor = MarkdownEditor;
1691
- exports.Modal = Modal;
1692
- exports.ModalBody = ModalBody;
1693
- exports.ModalClose = ModalClose;
1694
- exports.ModalContent = ModalContent;
1695
- exports.ModalDescription = ModalDescription;
1696
- exports.ModalFooter = ModalFooter;
1697
- exports.ModalHeader = ModalHeader;
1698
- exports.ModalOverlay = ModalOverlay;
1699
- exports.ModalPortal = ModalPortal;
1700
- exports.ModalTitle = ModalTitle;
1701
- exports.ModalTrigger = ModalTrigger;
1702
- exports.Popover = Popover;
1703
- exports.PopoverContent = PopoverContent;
1704
- exports.PopoverTrigger = PopoverTrigger;
1705
- exports.SearchCombobox = SearchCombobox;
1706
- exports.SearchSelect = SearchSelect;
1707
- exports.Select = Select;
1708
- exports.SelectContent = SelectContent;
1709
- exports.SelectGroup = SelectGroup;
1710
- exports.SelectItem = SelectItem;
1711
- exports.SelectLabel = SelectLabel;
1712
- exports.SelectScrollDownButton = SelectScrollDownButton;
1713
- exports.SelectScrollUpButton = SelectScrollUpButton;
1714
- exports.SelectSeparator = SelectSeparator;
1715
- exports.SelectTrigger = SelectTrigger;
1716
- exports.SelectValue = SelectValue;
1717
- exports.Separator = Separator2;
1718
- exports.Skeleton = Skeleton;
1719
- exports.TableSkeleton = TableSkeleton;
1720
- exports.Tabs = Tabs;
1721
- exports.TabsContent = TabsContent;
1722
- exports.TabsList = TabsList;
1723
- exports.TabsTrigger = TabsTrigger;
1724
- exports.TimePicker = TimePicker;
1725
- exports.ToastProvider = ToastProvider;
1726
- exports.Tooltip = Tooltip;
1727
- exports.TooltipContent = TooltipContent;
1728
- exports.TooltipProvider = TooltipProvider;
1729
- exports.TooltipTrigger = TooltipTrigger;
1730
- exports.badgeVariants = badgeVariants;
1731
- exports.renderMarkdown = renderMarkdown;
1732
- //# sourceMappingURL=chunk-SVVKUMSL.cjs.map
1733
- //# sourceMappingURL=chunk-SVVKUMSL.cjs.map