@pollinations/ui 0.0.1

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 (61) hide show
  1. package/README.md +219 -0
  2. package/dist/Button-CNzpisJf.d.cts +26 -0
  3. package/dist/Button-DMJ2K6Gr.d.ts +26 -0
  4. package/dist/Chip-BS8ronOu.d.ts +20 -0
  5. package/dist/Chip-DyqWrq0r.d.cts +20 -0
  6. package/dist/app.css +87 -0
  7. package/dist/assets/logo-wordmark.svg +1 -0
  8. package/dist/assets/logo.svg +4 -0
  9. package/dist/auth/index.cjs +225 -0
  10. package/dist/auth/index.cjs.map +1 -0
  11. package/dist/auth/index.d.cts +28 -0
  12. package/dist/auth/index.d.ts +28 -0
  13. package/dist/auth/index.js +194 -0
  14. package/dist/auth/index.js.map +1 -0
  15. package/dist/auth/sdk.cjs +220 -0
  16. package/dist/auth/sdk.cjs.map +1 -0
  17. package/dist/auth/sdk.d.cts +53 -0
  18. package/dist/auth/sdk.d.ts +53 -0
  19. package/dist/auth/sdk.js +187 -0
  20. package/dist/auth/sdk.js.map +1 -0
  21. package/dist/fonts/fraunces-soft-bold.woff2 +0 -0
  22. package/dist/fonts/lct-mogi-a.woff2 +0 -0
  23. package/dist/fonts/uncut-sans-variable.woff2 +0 -0
  24. package/dist/index.cjs +1771 -0
  25. package/dist/index.cjs.map +1 -0
  26. package/dist/index.d.cts +340 -0
  27. package/dist/index.d.ts +340 -0
  28. package/dist/index.js +1706 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/licenses/Fraunces-OFL.txt +93 -0
  31. package/dist/licenses/LCT-Mogi-OFL.txt +93 -0
  32. package/dist/licenses/UncutSans-OFL.txt +94 -0
  33. package/dist/modality/index.cjs +115 -0
  34. package/dist/modality/index.cjs.map +1 -0
  35. package/dist/modality/index.d.cts +45 -0
  36. package/dist/modality/index.d.ts +45 -0
  37. package/dist/modality/index.js +87 -0
  38. package/dist/modality/index.js.map +1 -0
  39. package/dist/showcase/index.cjs +2851 -0
  40. package/dist/showcase/index.cjs.map +1 -0
  41. package/dist/showcase/index.d.cts +19 -0
  42. package/dist/showcase/index.d.ts +19 -0
  43. package/dist/showcase/index.js +2839 -0
  44. package/dist/showcase/index.js.map +1 -0
  45. package/dist/styles.css +2 -0
  46. package/dist/theme-DfHMjWB7.d.cts +16 -0
  47. package/dist/theme-DfHMjWB7.d.ts +16 -0
  48. package/dist/wallet/index.cjs +190 -0
  49. package/dist/wallet/index.cjs.map +1 -0
  50. package/dist/wallet/index.d.cts +30 -0
  51. package/dist/wallet/index.d.ts +30 -0
  52. package/dist/wallet/index.js +157 -0
  53. package/dist/wallet/index.js.map +1 -0
  54. package/dist/wallet/sdk.cjs +203 -0
  55. package/dist/wallet/sdk.cjs.map +1 -0
  56. package/dist/wallet/sdk.d.cts +33 -0
  57. package/dist/wallet/sdk.d.ts +33 -0
  58. package/dist/wallet/sdk.js +172 -0
  59. package/dist/wallet/sdk.js.map +1 -0
  60. package/dist/wallet.css +73 -0
  61. package/package.json +105 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,1771 @@
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/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ AppIcon: () => AppIcon,
24
+ BeakerIcon: () => BeakerIcon,
25
+ BookIcon: () => BookIcon,
26
+ Button: () => Button,
27
+ CheckIcon: () => CheckIcon,
28
+ ChevronIcon: () => ChevronIcon,
29
+ Chip: () => Chip,
30
+ ClipboardIcon: () => ClipboardIcon,
31
+ ClockIcon: () => ClockIcon,
32
+ Collapsible: () => Collapsible,
33
+ CopyButton: () => CopyButton,
34
+ Dialog: () => Dialog,
35
+ DialogTitle: () => DialogTitle,
36
+ DiscordIcon: () => DiscordIcon,
37
+ DownloadIcon: () => DownloadIcon,
38
+ Dropdown: () => Dropdown,
39
+ ExternalLinkButton: () => ExternalLinkButton,
40
+ ExternalLinkIcon: () => ExternalLinkIcon,
41
+ Field: () => import_field.Field,
42
+ GenApiIcon: () => GenApiIcon,
43
+ GitHubIcon: () => GitHubIcon,
44
+ IconButton: () => IconButton,
45
+ ImageIcon: () => ImageIcon,
46
+ InfoTip: () => InfoTip,
47
+ Input: () => Input,
48
+ LockIcon: () => LockIcon,
49
+ MailIcon: () => MailIcon,
50
+ McpIcon: () => McpIcon,
51
+ MenuIcon: () => MenuIcon,
52
+ MultiSelect: () => MultiSelect,
53
+ PeriodPicker: () => PeriodPicker,
54
+ ScrollArea: () => ScrollArea,
55
+ Section: () => Section,
56
+ Slider: () => Slider,
57
+ StatCard: () => StatCard,
58
+ Surface: () => Surface,
59
+ Switch: () => Switch,
60
+ TabButton: () => TabButton,
61
+ TerminalIcon: () => TerminalIcon,
62
+ TokensIcon: () => TokensIcon,
63
+ Tooltip: () => Tooltip,
64
+ TrendUpIcon: () => TrendUpIcon,
65
+ WalletIcon: () => WalletIcon,
66
+ XIcon: () => XIcon,
67
+ cn: () => cn,
68
+ currentPeriod: () => currentPeriod,
69
+ getPeriodBucketKeys: () => getPeriodBucketKeys,
70
+ periodBucketKeyToDate: () => periodBucketKeyToDate,
71
+ themeColors: () => themeColors,
72
+ themes: () => themes,
73
+ useScrollLock: () => useScrollLock
74
+ });
75
+ module.exports = __toCommonJS(src_exports);
76
+
77
+ // src/lib/cn-app.ts
78
+ var import_clsx = require("clsx");
79
+ var import_tailwind_merge = require("tailwind-merge");
80
+ function cn(...inputs) {
81
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(...inputs));
82
+ }
83
+
84
+ // src/lib/period.ts
85
+ var MS_PER_DAY = 864e5;
86
+ function startOfUtcDay(date = /* @__PURE__ */ new Date()) {
87
+ return new Date(
88
+ Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())
89
+ );
90
+ }
91
+ function addUtcDays(date, days) {
92
+ const next = new Date(date);
93
+ next.setUTCDate(next.getUTCDate() + days);
94
+ return next;
95
+ }
96
+ function startOfUtcMonth(date) {
97
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
98
+ }
99
+ function addUtcMonths(date, months) {
100
+ return new Date(
101
+ Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1)
102
+ );
103
+ }
104
+ function startOfUtcIsoWeek(date) {
105
+ const day = date.getUTCDay() || 7;
106
+ return addUtcDays(startOfUtcDay(date), 1 - day);
107
+ }
108
+ function getUtcIsoWeekPeriod(date) {
109
+ const day = date.getUTCDay() || 7;
110
+ const thursday = addUtcDays(startOfUtcDay(date), 4 - day);
111
+ const isoYear = thursday.getUTCFullYear();
112
+ const yearStart = new Date(Date.UTC(isoYear, 0, 1));
113
+ const isoWeek = Math.ceil(
114
+ ((thursday.getTime() - yearStart.getTime()) / MS_PER_DAY + 1) / 7
115
+ );
116
+ return `${isoYear}-W${String(isoWeek).padStart(2, "0")}`;
117
+ }
118
+ function formatUtcDatePeriod(date) {
119
+ return date.toISOString().slice(0, 10);
120
+ }
121
+ function formatUtcHourPeriod(date) {
122
+ return date.toISOString().slice(0, 13).replace("T", " ");
123
+ }
124
+ function formatUtcMonthPeriod(date) {
125
+ return date.toISOString().slice(0, 7);
126
+ }
127
+ function periodFromDate(granularity, date = /* @__PURE__ */ new Date()) {
128
+ if (granularity === "day") {
129
+ return {
130
+ granularity,
131
+ period: formatUtcDatePeriod(startOfUtcDay(date))
132
+ };
133
+ }
134
+ if (granularity === "week") {
135
+ return { granularity, period: getUtcIsoWeekPeriod(date) };
136
+ }
137
+ return { granularity, period: formatUtcMonthPeriod(startOfUtcMonth(date)) };
138
+ }
139
+ function currentPeriod() {
140
+ return periodFromDate("day");
141
+ }
142
+ function periodToWindow(selection) {
143
+ if (selection.granularity === "day") {
144
+ const start2 = /* @__PURE__ */ new Date(`${selection.period}T00:00:00.000Z`);
145
+ return { start: start2, end: addUtcDays(start2, 1) };
146
+ }
147
+ if (selection.granularity === "week") {
148
+ const [yearText2, weekText] = selection.period.split("-W");
149
+ const isoYear = Number(yearText2);
150
+ const isoWeek = Number(weekText);
151
+ const jan4 = new Date(Date.UTC(isoYear, 0, 4));
152
+ const start2 = addUtcDays(startOfUtcIsoWeek(jan4), (isoWeek - 1) * 7);
153
+ return { start: start2, end: addUtcDays(start2, 7) };
154
+ }
155
+ const [yearText, monthText] = selection.period.split("-");
156
+ const start = new Date(
157
+ Date.UTC(Number(yearText), Number(monthText) - 1, 1)
158
+ );
159
+ return { start, end: addUtcMonths(start, 1) };
160
+ }
161
+ function formatPeriodLabel(selection) {
162
+ const { start, end } = periodToWindow(selection);
163
+ if (selection.granularity === "day") {
164
+ const today = startOfUtcDay();
165
+ const yesterday = addUtcDays(today, -1);
166
+ if (start.getTime() === today.getTime()) return "Today";
167
+ if (start.getTime() === yesterday.getTime()) return "Yesterday";
168
+ return start.toLocaleDateString("en-US", {
169
+ timeZone: "UTC",
170
+ month: "short",
171
+ day: "numeric",
172
+ year: "numeric"
173
+ });
174
+ }
175
+ if (selection.granularity === "week") {
176
+ const weekEnd = addUtcDays(end, -1);
177
+ return `${start.toLocaleDateString("en-US", {
178
+ timeZone: "UTC",
179
+ month: "short",
180
+ day: "numeric"
181
+ })} - ${weekEnd.toLocaleDateString("en-US", {
182
+ timeZone: "UTC",
183
+ month: "short",
184
+ day: "numeric",
185
+ year: "numeric"
186
+ })}`;
187
+ }
188
+ return start.toLocaleDateString("en-US", {
189
+ timeZone: "UTC",
190
+ month: "long",
191
+ year: "numeric"
192
+ });
193
+ }
194
+ function getPeriodBucketKeys(selection) {
195
+ const { start, end } = periodToWindow(selection);
196
+ const bucketKeys = [];
197
+ const cursor = new Date(start);
198
+ if (selection.granularity === "day") {
199
+ while (cursor < end) {
200
+ bucketKeys.push(`${formatUtcHourPeriod(cursor)}:00:00`);
201
+ cursor.setUTCHours(cursor.getUTCHours() + 1);
202
+ }
203
+ return bucketKeys;
204
+ }
205
+ while (cursor < end) {
206
+ bucketKeys.push(formatUtcDatePeriod(cursor));
207
+ cursor.setUTCDate(cursor.getUTCDate() + 1);
208
+ }
209
+ return bucketKeys;
210
+ }
211
+ function periodBucketKeyToDate(bucketKey, granularity) {
212
+ if (granularity === "day") {
213
+ return /* @__PURE__ */ new Date(`${bucketKey.replace(" ", "T")}.000Z`);
214
+ }
215
+ return /* @__PURE__ */ new Date(`${bucketKey}T00:00:00.000Z`);
216
+ }
217
+ function isPeriodSelectable(selection, minDate = /* @__PURE__ */ new Date(0), maxDate = startOfUtcDay()) {
218
+ const { start, end } = periodToWindow(selection);
219
+ return end > minDate && start <= maxDate;
220
+ }
221
+
222
+ // src/lib/use-scroll-lock.ts
223
+ var import_react = require("react");
224
+ function useScrollLock(enabled = true) {
225
+ (0, import_react.useEffect)(() => {
226
+ if (!enabled) return;
227
+ const originalBody = document.body.style.overflow;
228
+ const originalHtml = document.documentElement.style.overflow;
229
+ document.body.style.overflow = "hidden";
230
+ document.documentElement.style.overflow = "hidden";
231
+ return () => {
232
+ document.body.style.overflow = originalBody;
233
+ document.documentElement.style.overflow = originalHtml;
234
+ };
235
+ }, [enabled]);
236
+ }
237
+
238
+ // src/lib/cn.ts
239
+ var import_clsx2 = require("clsx");
240
+ var import_tailwind_merge2 = require("tailwind-merge");
241
+ var twMerge2 = (0, import_tailwind_merge2.extendTailwindMerge)({ prefix: "polli" });
242
+ function cn2(...inputs) {
243
+ return twMerge2((0, import_clsx2.clsx)(...inputs));
244
+ }
245
+
246
+ // src/primitives/Button.tsx
247
+ var import_jsx_runtime = require("react/jsx-runtime");
248
+ var sizes = {
249
+ small: "polli:px-2 polli:pt-0.5 polli:pb-1",
250
+ medium: "polli:px-4 polli:pt-1.5 polli:pb-2",
251
+ large: "polli:px-6 polli:py-3"
252
+ };
253
+ var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:transition-colors";
254
+ var intentClasses = {
255
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-[oklch(0.88_0.075_25)] polli:transition-colors"
256
+ };
257
+ var buttonClasses = ({
258
+ theme: _theme,
259
+ intent,
260
+ size,
261
+ className,
262
+ disabled
263
+ }) => {
264
+ const colorClasses = intent ? intentClasses[intent] : themeClasses;
265
+ return cn2(
266
+ "polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:placeholder-green-950 polli:font-medium polli:leading-normal polli:box-border",
267
+ disabled ? "polli:opacity-50 polli:cursor-not-allowed" : "polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer",
268
+ colorClasses,
269
+ sizes[size || "medium"],
270
+ className
271
+ );
272
+ };
273
+ function Button({
274
+ as,
275
+ children,
276
+ theme,
277
+ intent,
278
+ size,
279
+ className,
280
+ disabled,
281
+ ...buttonProps
282
+ }) {
283
+ const Component = as || "button";
284
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
285
+ Component,
286
+ {
287
+ "data-theme": intent ? void 0 : theme,
288
+ className: buttonClasses({
289
+ theme,
290
+ intent,
291
+ size,
292
+ className,
293
+ disabled
294
+ }),
295
+ disabled,
296
+ ...buttonProps,
297
+ children
298
+ }
299
+ );
300
+ }
301
+
302
+ // src/primitives/ChevronIcon.tsx
303
+ var import_jsx_runtime2 = require("react/jsx-runtime");
304
+ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
305
+ "svg",
306
+ {
307
+ "aria-hidden": "true",
308
+ width: "12",
309
+ height: "12",
310
+ viewBox: "0 0 12 12",
311
+ className: cn2(
312
+ "polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out",
313
+ expanded && "polli:rotate-180",
314
+ className
315
+ ),
316
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
317
+ "path",
318
+ {
319
+ d: "M3 4.5 6 7.5l3-3",
320
+ fill: "none",
321
+ stroke: "currentColor",
322
+ strokeLinecap: "round",
323
+ strokeLinejoin: "round",
324
+ strokeWidth: "1.5"
325
+ }
326
+ )
327
+ }
328
+ );
329
+
330
+ // src/primitives/Chip.tsx
331
+ var import_jsx_runtime3 = require("react/jsx-runtime");
332
+ var chipSizes = {
333
+ sm: "polli:px-2 polli:py-0.5 polli:text-xs",
334
+ md: "polli:px-2.5 polli:py-0.5 polli:text-sm",
335
+ lg: "polli:px-3 polli:py-1 polli:text-sm"
336
+ };
337
+ var intentClasses2 = {
338
+ news: "polli:bg-[oklch(0.935_0.06_158)] polli:text-[oklch(0.46_0.13_158)]",
339
+ alpha: "polli:bg-[oklch(0.93_0.06_300)] polli:text-[oklch(0.42_0.18_300)]",
340
+ neutral: "polli:border polli:border-gray-400/70 polli:bg-gray-100/80 polli:text-gray-900"
341
+ };
342
+ var Chip = ({
343
+ theme,
344
+ intent,
345
+ size = "md",
346
+ className,
347
+ children,
348
+ ...rest
349
+ }) => {
350
+ const intentClass = intent ? intentClasses2[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
351
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
352
+ "span",
353
+ {
354
+ ...rest,
355
+ "data-theme": theme,
356
+ className: cn2(
357
+ "polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal",
358
+ chipSizes[size],
359
+ intentClass,
360
+ className
361
+ ),
362
+ children
363
+ }
364
+ );
365
+ };
366
+
367
+ // src/primitives/Collapsible.tsx
368
+ var import_jsx_runtime4 = require("react/jsx-runtime");
369
+ var Collapsible = ({
370
+ label,
371
+ expanded,
372
+ onToggle,
373
+ children,
374
+ disabled = false,
375
+ wrapperClassName,
376
+ hoverClassName = "polli:hover:bg-theme-bg-active",
377
+ focusClassName,
378
+ panelClassName = "polli:border-t polli:border-theme-border polli:px-3 polli:pt-3 polli:pb-3",
379
+ ariaLabel
380
+ }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
381
+ "div",
382
+ {
383
+ className: cn2(
384
+ "polli:rounded-lg polli:border polli:transition-all",
385
+ wrapperClassName,
386
+ disabled && "polli:opacity-50"
387
+ ),
388
+ children: [
389
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
390
+ "button",
391
+ {
392
+ type: "button",
393
+ "aria-expanded": expanded,
394
+ "aria-label": ariaLabel,
395
+ disabled,
396
+ onClick: onToggle,
397
+ className: cn2(
398
+ "polli:w-full polli:flex polli:items-center polli:gap-3 polli:px-3 polli:py-2 polli:text-left polli:transition-colors",
399
+ expanded ? "polli:rounded-t-lg" : "polli:rounded-lg",
400
+ !disabled && hoverClassName,
401
+ focusClassName,
402
+ disabled ? "polli:cursor-not-allowed" : "polli:cursor-pointer"
403
+ ),
404
+ children: [
405
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "polli:flex-1 polli:min-w-0", children: label }),
406
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
407
+ ChevronIcon,
408
+ {
409
+ expanded,
410
+ className: "polli:text-theme-text-soft"
411
+ }
412
+ )
413
+ ]
414
+ }
415
+ ),
416
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: panelClassName, children })
417
+ ]
418
+ }
419
+ );
420
+
421
+ // src/primitives/CopyButton.tsx
422
+ var import_react3 = require("react");
423
+
424
+ // src/primitives/Tooltip.tsx
425
+ var import_react2 = require("react");
426
+ var import_jsx_runtime5 = require("react/jsx-runtime");
427
+ var TOOLTIP_MAX_WIDTH = 288;
428
+ var TOOLTIP_VIEWPORT_MARGIN = 12;
429
+ var Tooltip = ({
430
+ children,
431
+ content,
432
+ ariaLabel,
433
+ className,
434
+ onClick,
435
+ style,
436
+ triggerAs = "button",
437
+ displayContents = false
438
+ }) => {
439
+ const [showTooltip, setShowTooltip] = (0, import_react2.useState)(false);
440
+ const [tooltipPosition, setTooltipPosition] = (0, import_react2.useState)({
441
+ top: 0,
442
+ left: 0,
443
+ maxWidth: TOOLTIP_MAX_WIDTH
444
+ });
445
+ const triggerRef = (0, import_react2.useRef)(null);
446
+ const updateTooltipPosition = () => {
447
+ if (triggerRef.current) {
448
+ const rect = triggerRef.current.getBoundingClientRect();
449
+ const maxWidth = Math.min(
450
+ TOOLTIP_MAX_WIDTH,
451
+ window.innerWidth - TOOLTIP_VIEWPORT_MARGIN * 2
452
+ );
453
+ const left = Math.min(
454
+ Math.max(rect.left, TOOLTIP_VIEWPORT_MARGIN),
455
+ Math.max(
456
+ TOOLTIP_VIEWPORT_MARGIN,
457
+ window.innerWidth - maxWidth - TOOLTIP_VIEWPORT_MARGIN
458
+ )
459
+ );
460
+ setTooltipPosition({
461
+ top: rect.bottom + 4,
462
+ left,
463
+ maxWidth
464
+ });
465
+ }
466
+ };
467
+ const triggerClassName = cn2(
468
+ "polli:relative polli:cursor-help polli:text-left polli:inline-flex polli:items-center",
469
+ className
470
+ );
471
+ const cursorClass = displayContents ? "polli:contents" : "polli:cursor-help";
472
+ const popupClasses = "polli:fixed polli:w-max polli:px-2 polli:py-1 polli:bg-theme-bg-pale polli:text-theme-text-strong polli:border polli:border-theme-border polli:text-xs polli:rounded-md polli:shadow-sm polli:z-50 polli:pointer-events-none polli:transition-opacity polli:whitespace-pre-line polli:break-words";
473
+ const contentNode = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
474
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: cursorClass, children }),
475
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
476
+ "span",
477
+ {
478
+ style: {
479
+ top: tooltipPosition.top,
480
+ left: tooltipPosition.left,
481
+ maxWidth: tooltipPosition.maxWidth
482
+ },
483
+ className: `${showTooltip ? "polli:visible polli:opacity-100" : "polli:invisible polli:opacity-0"} ${popupClasses}`,
484
+ children: content
485
+ }
486
+ )
487
+ ] });
488
+ const sharedProps = {
489
+ "aria-label": ariaLabel,
490
+ className: triggerClassName,
491
+ onMouseEnter: () => {
492
+ updateTooltipPosition();
493
+ setShowTooltip(true);
494
+ },
495
+ onMouseLeave: () => setShowTooltip(false),
496
+ onClick: (e) => {
497
+ e.stopPropagation();
498
+ if (onClick) {
499
+ onClick();
500
+ }
501
+ if (triggerAs === "span") {
502
+ return;
503
+ }
504
+ updateTooltipPosition();
505
+ setShowTooltip((prev) => !prev);
506
+ },
507
+ style
508
+ };
509
+ if (triggerAs === "span") {
510
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
511
+ "span",
512
+ {
513
+ ref: (node) => {
514
+ triggerRef.current = node;
515
+ },
516
+ ...sharedProps,
517
+ children: contentNode
518
+ }
519
+ );
520
+ }
521
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
522
+ "button",
523
+ {
524
+ ref: (node) => {
525
+ triggerRef.current = node;
526
+ },
527
+ type: "button",
528
+ "aria-label": ariaLabel,
529
+ className: triggerClassName,
530
+ onMouseEnter: sharedProps.onMouseEnter,
531
+ onMouseLeave: sharedProps.onMouseLeave,
532
+ onClick: sharedProps.onClick,
533
+ style,
534
+ children: contentNode
535
+ }
536
+ );
537
+ };
538
+
539
+ // src/primitives/CopyButton.tsx
540
+ var import_jsx_runtime6 = require("react/jsx-runtime");
541
+ function CopyButton({
542
+ value,
543
+ children,
544
+ copiedTimeoutMs = 2e3,
545
+ tooltip = "Click to copy",
546
+ copiedTooltip = "Copied!",
547
+ tooltipClassName,
548
+ className,
549
+ onCopied,
550
+ onCopyError,
551
+ ...buttonProps
552
+ }) {
553
+ const [copied, setCopied] = (0, import_react3.useState)(false);
554
+ const timeoutRef = (0, import_react3.useRef)(null);
555
+ (0, import_react3.useEffect)(
556
+ () => () => {
557
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
558
+ },
559
+ []
560
+ );
561
+ async function handleCopy(event) {
562
+ event.stopPropagation();
563
+ try {
564
+ const text = typeof value === "function" ? await value() : value;
565
+ await navigator.clipboard.writeText(text);
566
+ setCopied(true);
567
+ onCopied?.();
568
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
569
+ timeoutRef.current = setTimeout(
570
+ () => setCopied(false),
571
+ copiedTimeoutMs
572
+ );
573
+ } catch (error) {
574
+ onCopyError?.(error);
575
+ }
576
+ }
577
+ const button = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
578
+ "button",
579
+ {
580
+ ...buttonProps,
581
+ type: "button",
582
+ onClick: handleCopy,
583
+ className: cn2(
584
+ typeof className === "function" ? className(copied) : className
585
+ ),
586
+ children: typeof children === "function" ? children(copied) : children
587
+ }
588
+ );
589
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
590
+ Tooltip,
591
+ {
592
+ triggerAs: "span",
593
+ content: copied ? copiedTooltip : tooltip,
594
+ className: tooltipClassName,
595
+ children: button
596
+ }
597
+ );
598
+ }
599
+
600
+ // src/primitives/Dialog.tsx
601
+ var import_dialog = require("@ark-ui/react/dialog");
602
+ var import_portal = require("@ark-ui/react/portal");
603
+ var import_jsx_runtime7 = require("react/jsx-runtime");
604
+ var sizeClasses = {
605
+ sm: "polli:max-w-md",
606
+ md: "polli:max-w-xl",
607
+ lg: "polli:max-w-2xl"
608
+ };
609
+ var Dialog = ({
610
+ open,
611
+ onOpenChange,
612
+ trigger,
613
+ triggerAsChild = false,
614
+ triggerClassName,
615
+ title,
616
+ titleClassName,
617
+ ariaLabel,
618
+ labelledBy,
619
+ theme = "blue",
620
+ size = "md",
621
+ showBackdrop = true,
622
+ backdropClassName,
623
+ positionerClassName,
624
+ contentClassName,
625
+ children
626
+ }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
627
+ import_dialog.Dialog.Root,
628
+ {
629
+ open,
630
+ onOpenChange: (details) => onOpenChange?.(details.open),
631
+ children: [
632
+ trigger && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
633
+ import_dialog.Dialog.Trigger,
634
+ {
635
+ asChild: triggerAsChild,
636
+ className: triggerClassName,
637
+ children: trigger
638
+ }
639
+ ),
640
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_portal.Portal, { children: [
641
+ showBackdrop && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
642
+ import_dialog.Dialog.Backdrop,
643
+ {
644
+ className: cn2(
645
+ "polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50",
646
+ backdropClassName
647
+ )
648
+ }
649
+ ),
650
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
651
+ import_dialog.Dialog.Positioner,
652
+ {
653
+ className: cn2(
654
+ "polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4",
655
+ positionerClassName
656
+ ),
657
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
658
+ import_dialog.Dialog.Content,
659
+ {
660
+ "data-theme": theme,
661
+ "aria-label": ariaLabel,
662
+ "aria-labelledby": labelledBy,
663
+ className: cn2(
664
+ "polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg",
665
+ sizeClasses[size],
666
+ contentClassName
667
+ ),
668
+ children: [
669
+ title && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
670
+ DialogTitle,
671
+ {
672
+ className: cn2(
673
+ "polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong",
674
+ titleClassName
675
+ ),
676
+ children: title
677
+ }
678
+ ),
679
+ children
680
+ ]
681
+ }
682
+ )
683
+ }
684
+ )
685
+ ] })
686
+ ]
687
+ }
688
+ );
689
+ var DialogTitle = import_dialog.Dialog.Title;
690
+
691
+ // src/primitives/Dropdown.tsx
692
+ var import_popover = require("@ark-ui/react/popover");
693
+ var import_portal2 = require("@ark-ui/react/portal");
694
+ var import_react4 = require("react");
695
+ var import_jsx_runtime8 = require("react/jsx-runtime");
696
+ var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-surface-white polli:shadow-lg";
697
+ var Dropdown = ({
698
+ theme,
699
+ trigger,
700
+ children,
701
+ align = "start",
702
+ open: openProp,
703
+ onOpenChange,
704
+ panelClassName,
705
+ className
706
+ }) => {
707
+ const [internalOpen, setInternalOpen] = (0, import_react4.useState)(false);
708
+ const isControlled = openProp !== void 0;
709
+ const open = isControlled ? openProp : internalOpen;
710
+ const setOpen = (next) => {
711
+ if (!isControlled) setInternalOpen(next);
712
+ onOpenChange?.(next);
713
+ };
714
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
715
+ import_popover.Popover.Root,
716
+ {
717
+ open,
718
+ onOpenChange: (details) => setOpen(details.open),
719
+ positioning: {
720
+ placement: align === "end" ? "bottom-end" : "bottom-start"
721
+ },
722
+ children: [
723
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_popover.Popover.Trigger, { asChild: true, children: trigger(open) }),
724
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_portal2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_popover.Popover.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
725
+ import_popover.Popover.Content,
726
+ {
727
+ "data-theme": theme,
728
+ className: cn2(
729
+ "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
730
+ panelClassName ?? DEFAULT_PANEL,
731
+ className
732
+ ),
733
+ children: typeof children === "function" ? children(() => setOpen(false)) : children
734
+ }
735
+ ) }) })
736
+ ]
737
+ }
738
+ );
739
+ };
740
+
741
+ // src/primitives/icons/index.tsx
742
+ var import_jsx_runtime9 = require("react/jsx-runtime");
743
+ var strokeProps = {
744
+ fill: "none",
745
+ stroke: "currentColor",
746
+ strokeWidth: 2,
747
+ strokeLinecap: "round",
748
+ strokeLinejoin: "round"
749
+ };
750
+ function AppIcon(props) {
751
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
752
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "2", y: "4", width: "20", height: "14", rx: "2" }),
753
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M2 20h20" })
754
+ ] });
755
+ }
756
+ function BeakerIcon(props) {
757
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
758
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M9 3h6" }),
759
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M10 3v6.5L4.5 18a2 2 0 0 0 1.7 3h11.6a2 2 0 0 0 1.7-3L14 9.5V3" }),
760
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M7 14h10" })
761
+ ] });
762
+ }
763
+ function BookIcon(props) {
764
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
765
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M4 4h5a3 3 0 0 1 3 3v13a2 2 0 0 0-2-2H4z" }),
766
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M20 4h-5a3 3 0 0 0-3 3v13a2 2 0 0 1 2-2h6z" })
767
+ ] });
768
+ }
769
+ function CheckIcon(props) {
770
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
771
+ "svg",
772
+ {
773
+ "aria-hidden": "true",
774
+ viewBox: "0 0 24 24",
775
+ ...strokeProps,
776
+ strokeWidth: 2.5,
777
+ ...props,
778
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "20 6 9 17 4 12" })
779
+ }
780
+ );
781
+ }
782
+ function ClipboardIcon(props) {
783
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
784
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
785
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
786
+ ] });
787
+ }
788
+ function ClockIcon(props) {
789
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
790
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
791
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M12 7v5l3 2" })
792
+ ] });
793
+ }
794
+ function DiscordIcon(props) {
795
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
796
+ "path",
797
+ {
798
+ fill: "currentColor",
799
+ d: "M20.32 4.37A19.8 19.8 0 0 0 15.36 2.83a.07.07 0 0 0-.08.04c-.21.38-.45.88-.62 1.27a18.27 18.27 0 0 0-5.52 0 12.84 12.84 0 0 0-.63-1.27.08.08 0 0 0-.08-.04A19.74 19.74 0 0 0 3.47 4.37a.07.07 0 0 0-.03.03C.31 9.07-.55 13.61-.13 18.1a.08.08 0 0 0 .03.06 19.9 19.9 0 0 0 6.08 3.07.08.08 0 0 0 .09-.03c.47-.64.88-1.31 1.24-2.02a.08.08 0 0 0-.04-.1 13.08 13.08 0 0 1-1.9-.91.08.08 0 0 1-.01-.13c.13-.1.25-.2.37-.29a.07.07 0 0 1 .08-.01 14.24 14.24 0 0 0 12.38 0 .07.07 0 0 1 .08.01c.12.1.25.2.38.3a.08.08 0 0 1-.01.12 12.22 12.22 0 0 1-1.9.9.08.08 0 0 0-.04.11c.36.7.77 1.38 1.23 2.02a.08.08 0 0 0 .1.03 19.84 19.84 0 0 0 6.08-3.07.08.08 0 0 0 .03-.05c.5-5.2-.84-9.7-3.77-13.71a.06.06 0 0 0-.03-.03ZM8.02 15.37c-1.18 0-2.16-1.08-2.16-2.4 0-1.32.96-2.4 2.16-2.4 1.2 0 2.18 1.09 2.16 2.4 0 1.32-.96 2.4-2.16 2.4Zm7.96 0c-1.18 0-2.16-1.08-2.16-2.4 0-1.32.96-2.4 2.16-2.4 1.2 0 2.18 1.09 2.16 2.4 0 1.32-.95 2.4-2.16 2.4Z"
800
+ }
801
+ ) });
802
+ }
803
+ function DownloadIcon(props) {
804
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
805
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
806
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "7 10 12 15 17 10" }),
807
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
808
+ ] });
809
+ }
810
+ function ExternalLinkIcon(props) {
811
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M7 17 17 7M9 7h8v8" }) });
812
+ }
813
+ function GenApiIcon(props) {
814
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
815
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "m8 3 4 1.5L16 3v18l-4-1.5L8 21z" }),
816
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M8 3v18M16 3v18" })
817
+ ] });
818
+ }
819
+ function GitHubIcon(props) {
820
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
821
+ "path",
822
+ {
823
+ fill: "currentColor",
824
+ d: "M12 .5A11.5 11.5 0 0 0 8.36 22.9c.58.11.79-.25.79-.56v-2.16c-3.21.7-3.89-1.38-3.89-1.38-.53-1.34-1.29-1.7-1.29-1.7-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.04 1.76 2.71 1.25 3.37.96.11-.75.4-1.25.74-1.54-2.56-.29-5.26-1.28-5.26-5.7 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.46.11-3.06 0 0 .97-.31 3.16 1.18a10.88 10.88 0 0 1 5.76 0c2.19-1.49 3.15-1.18 3.15-1.18.63 1.6.23 2.77.11 3.06.74.81 1.19 1.84 1.19 3.1 0 4.43-2.7 5.4-5.27 5.69.41.36.78 1.06.78 2.14v3.19c0 .31.21.68.8.56A11.5 11.5 0 0 0 12 .5Z"
825
+ }
826
+ ) });
827
+ }
828
+ function ImageIcon(props) {
829
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
830
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
831
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
832
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "m21 15-5-5L5 21" })
833
+ ] });
834
+ }
835
+ function LockIcon(props) {
836
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
837
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
838
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
839
+ ] });
840
+ }
841
+ function MailIcon(props) {
842
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
843
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
844
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "m3 7 9 7 9-7" })
845
+ ] });
846
+ }
847
+ function McpIcon(props) {
848
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
849
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "2", y: "7", width: "8", height: "10", rx: "1.5" }),
850
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "14", y: "7", width: "8", height: "10", rx: "1.5" }),
851
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M10 12h4" })
852
+ ] });
853
+ }
854
+ function MenuIcon(props) {
855
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M4 7h16M4 12h16M4 17h16" }) });
856
+ }
857
+ function TerminalIcon(props) {
858
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
859
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "4 8 8 12 4 16" }),
860
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "12", y1: "20", x2: "20", y2: "20" })
861
+ ] });
862
+ }
863
+ function TokensIcon(props) {
864
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M4 9h16M4 15h16M10 3 8 21M16 3l-2 18" }) });
865
+ }
866
+ function TrendUpIcon(props) {
867
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
868
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "3 17 9 11 13 15 21 7" }),
869
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "15 7 21 7 21 13" })
870
+ ] });
871
+ }
872
+ function WalletIcon(props) {
873
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
874
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M3 7a2 2 0 0 1 2-2h13a2 2 0 0 1 2 2v2H5a2 2 0 0 0-2 2V7Z" }),
875
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M3 11a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-6Z" }),
876
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "17", cy: "14", r: "1.25", fill: "currentColor" })
877
+ ] });
878
+ }
879
+ function XIcon(props) {
880
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }) });
881
+ }
882
+
883
+ // src/primitives/ExternalLinkButton.tsx
884
+ var import_jsx_runtime10 = require("react/jsx-runtime");
885
+ var ExternalLinkButton = ({
886
+ theme,
887
+ href,
888
+ size = "medium",
889
+ className,
890
+ children
891
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
892
+ Button,
893
+ {
894
+ as: "a",
895
+ href,
896
+ target: "_blank",
897
+ rel: "noopener noreferrer",
898
+ theme,
899
+ size,
900
+ className: cn2("polli:gap-2", className),
901
+ children: [
902
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children }),
903
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
904
+ ExternalLinkIcon,
905
+ {
906
+ className: "polli:h-4 polli:w-4 polli:shrink-0 polli:opacity-60",
907
+ "aria-hidden": "true"
908
+ }
909
+ )
910
+ ]
911
+ }
912
+ );
913
+
914
+ // src/primitives/Field.tsx
915
+ var import_field = require("@ark-ui/react/field");
916
+
917
+ // src/primitives/IconButton.tsx
918
+ var import_jsx_runtime11 = require("react/jsx-runtime");
919
+ var intentClasses3 = {
920
+ danger: "polli:bg-intent-danger-bg-light polli:hover:bg-[oklch(0.88_0.075_25)] polli:text-intent-danger-text"
921
+ };
922
+ var defaultClasses = "polli:bg-theme-bg-active polli:hover:bg-theme-bg-hover polli:text-theme-text-soft polli:hover:text-theme-text-strong";
923
+ var IconButton = ({
924
+ intent,
925
+ title,
926
+ onClick,
927
+ children,
928
+ className
929
+ }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
930
+ "button",
931
+ {
932
+ type: "button",
933
+ onClick,
934
+ title,
935
+ "aria-label": title,
936
+ className: cn2(
937
+ "polli:inline-flex polli:h-6 polli:w-6 polli:cursor-pointer polli:items-center polli:justify-center polli:rounded polli:transition-colors",
938
+ intent ? intentClasses3[intent] : defaultClasses,
939
+ className
940
+ ),
941
+ children
942
+ }
943
+ );
944
+
945
+ // src/primitives/InfoTip.tsx
946
+ var import_jsx_runtime12 = require("react/jsx-runtime");
947
+ var InfoTip = ({
948
+ text,
949
+ content,
950
+ label = "More info"
951
+ }) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tooltip, { content: content ?? text, ariaLabel: label, className: "polli:ml-1", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "polli:inline-flex polli:h-3.5 polli:w-3.5 polli:items-center polli:justify-center polli:rounded-full polli:border polli:border-theme-border polli:bg-theme-bg-active polli:font-bold polli:text-micro polli:text-theme-text-strong polli:transition-colors", children: "i" }) });
952
+
953
+ // src/primitives/Input.tsx
954
+ var import_react5 = require("react");
955
+ var import_jsx_runtime13 = require("react/jsx-runtime");
956
+ var Input = (0, import_react5.forwardRef)(
957
+ ({ className, error, hideNumberSteppers, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
958
+ "input",
959
+ {
960
+ ref,
961
+ className: cn2(
962
+ "polli:px-3 polli:py-2 polli:border polli:rounded-lg",
963
+ "polli:disabled:opacity-50 polli:disabled:cursor-not-allowed",
964
+ error ? "polli:border-red-400" : "polli:border-gray-300",
965
+ hideNumberSteppers && "polli-input-number-clean",
966
+ className
967
+ ),
968
+ ...props
969
+ }
970
+ )
971
+ );
972
+
973
+ // src/primitives/ScrollArea.tsx
974
+ var import_react6 = require("react");
975
+ var import_jsx_runtime14 = require("react/jsx-runtime");
976
+ var axisClasses = {
977
+ y: "polli:overflow-y-auto polli:overflow-x-hidden",
978
+ x: "polli:overflow-x-auto polli:overflow-y-hidden",
979
+ both: "polli:overflow-auto"
980
+ };
981
+ function assignRef(ref, value) {
982
+ if (typeof ref === "function") ref(value);
983
+ else if (ref) ref.current = value;
984
+ }
985
+ var ScrollArea = (0, import_react6.forwardRef)(
986
+ ({ theme, axis = "y", hideDelayMs = 2e3, className, children, ...rest }, externalRef) => {
987
+ const innerRef = (0, import_react6.useRef)(null);
988
+ const setRef = (0, import_react6.useCallback)(
989
+ (node) => {
990
+ innerRef.current = node;
991
+ assignRef(externalRef, node);
992
+ },
993
+ [externalRef]
994
+ );
995
+ (0, import_react6.useEffect)(() => {
996
+ const element = innerRef.current;
997
+ if (!element) return;
998
+ let hideTimer = null;
999
+ const clearHideTimer = () => {
1000
+ if (hideTimer !== null) {
1001
+ window.clearTimeout(hideTimer);
1002
+ hideTimer = null;
1003
+ }
1004
+ };
1005
+ const show = () => {
1006
+ element.dataset.scrollbarActive = "true";
1007
+ clearHideTimer();
1008
+ };
1009
+ const hide = () => {
1010
+ element.dataset.scrollbarActive = "false";
1011
+ clearHideTimer();
1012
+ };
1013
+ const scheduleHide = () => {
1014
+ clearHideTimer();
1015
+ hideTimer = window.setTimeout(hide, hideDelayMs);
1016
+ };
1017
+ const handleInteraction = () => {
1018
+ show();
1019
+ scheduleHide();
1020
+ };
1021
+ hide();
1022
+ element.addEventListener("scroll", handleInteraction, {
1023
+ passive: true
1024
+ });
1025
+ element.addEventListener("wheel", handleInteraction, {
1026
+ passive: true
1027
+ });
1028
+ element.addEventListener("touchstart", handleInteraction, {
1029
+ passive: true
1030
+ });
1031
+ element.addEventListener("pointerdown", handleInteraction);
1032
+ element.addEventListener("keydown", handleInteraction);
1033
+ element.addEventListener("focusin", handleInteraction);
1034
+ element.addEventListener("focusout", scheduleHide);
1035
+ return () => {
1036
+ clearHideTimer();
1037
+ element.removeEventListener("scroll", handleInteraction);
1038
+ element.removeEventListener("wheel", handleInteraction);
1039
+ element.removeEventListener("touchstart", handleInteraction);
1040
+ element.removeEventListener("pointerdown", handleInteraction);
1041
+ element.removeEventListener("keydown", handleInteraction);
1042
+ element.removeEventListener("focusin", handleInteraction);
1043
+ element.removeEventListener("focusout", scheduleHide);
1044
+ };
1045
+ }, [hideDelayMs]);
1046
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1047
+ "div",
1048
+ {
1049
+ ...rest,
1050
+ ref: setRef,
1051
+ "data-theme": theme,
1052
+ className: cn2(
1053
+ "polli-scrollbar-subtle",
1054
+ axisClasses[axis],
1055
+ className
1056
+ ),
1057
+ children
1058
+ }
1059
+ );
1060
+ }
1061
+ );
1062
+ ScrollArea.displayName = "ScrollArea";
1063
+
1064
+ // src/primitives/MultiSelect.tsx
1065
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1066
+ var TRIGGER_BASE = "polli:inline-flex polli:min-h-8 polli:min-w-[140px] polli:items-center polli:gap-2 polli:rounded-full polli:border polli:px-3 polli:py-1.5 polli:text-xs polli:font-medium polli:transition-all polli:duration-200";
1067
+ var ROW_BASE = "polli:flex polli:w-full polli:items-center polli:gap-3 polli:px-3 polli:py-2 polli:text-left polli:text-xs polli:transition-colors";
1068
+ var CHECK_BASE = "polli:flex polli:h-4 polli:w-4 polli:flex-shrink-0 polli:items-center polli:justify-center polli:rounded polli:border polli:border-theme-border polli:text-xs";
1069
+ var MultiSelect = ({
1070
+ options,
1071
+ selected,
1072
+ onChange,
1073
+ placeholder,
1074
+ disabled,
1075
+ disabledText,
1076
+ align = "start",
1077
+ label,
1078
+ theme
1079
+ }) => {
1080
+ const isAllSelected = selected.length === 0;
1081
+ const toggleItem = (itemId) => {
1082
+ if (selected.includes(itemId)) {
1083
+ onChange(selected.filter((m) => m !== itemId));
1084
+ } else {
1085
+ onChange([...selected, itemId]);
1086
+ }
1087
+ };
1088
+ const selectAll = () => onChange([]);
1089
+ const displayText = disabled ? disabledText : isAllSelected ? "All" : `${selected.length} selected`;
1090
+ const labelNode = label ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "polli:text-xs polli:font-medium polli:text-theme-text-soft", children: label }) : null;
1091
+ if (disabled) {
1092
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1093
+ "div",
1094
+ {
1095
+ "data-theme": theme,
1096
+ className: "polli:group polli:relative polli:flex polli:items-center polli:gap-2",
1097
+ children: [
1098
+ labelNode,
1099
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1100
+ "button",
1101
+ {
1102
+ type: "button",
1103
+ disabled: true,
1104
+ className: cn2(
1105
+ TRIGGER_BASE,
1106
+ "polli:cursor-not-allowed polli:border-theme-border polli:bg-theme-bg-subtle polli:opacity-60"
1107
+ ),
1108
+ children: [
1109
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "polli:flex-1 polli:truncate polli:text-left polli:text-theme-text-soft/60", children: displayText }),
1110
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1111
+ ChevronIcon,
1112
+ {
1113
+ expanded: false,
1114
+ className: "polli:h-3 polli:w-3 polli:text-theme-text-soft"
1115
+ }
1116
+ )
1117
+ ]
1118
+ }
1119
+ ),
1120
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "polli:pointer-events-none polli:absolute polli:-top-8 polli:left-1/2 polli:z-[100] polli:-translate-x-1/2 polli:whitespace-nowrap polli:rounded-md polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:px-2 polli:py-1 polli:text-xs polli:text-theme-text-strong polli:opacity-0 polli:shadow-sm polli:transition-opacity polli:group-hover:opacity-100", children: "No items available" })
1121
+ ]
1122
+ }
1123
+ );
1124
+ }
1125
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1126
+ "div",
1127
+ {
1128
+ "data-theme": theme,
1129
+ className: "polli:flex polli:items-center polli:gap-2",
1130
+ children: [
1131
+ labelNode,
1132
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1133
+ Dropdown,
1134
+ {
1135
+ theme,
1136
+ align,
1137
+ className: "polli:min-w-[320px]",
1138
+ trigger: (open) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1139
+ "button",
1140
+ {
1141
+ type: "button",
1142
+ className: cn2(
1143
+ TRIGGER_BASE,
1144
+ open ? "polli:border-theme-border polli:bg-theme-bg-active" : "polli:border-theme-border polli:bg-theme-bg-subtle polli:hover:bg-theme-bg-pale"
1145
+ ),
1146
+ children: [
1147
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1148
+ "span",
1149
+ {
1150
+ className: cn2(
1151
+ "polli:flex-1 polli:truncate polli:text-left",
1152
+ open ? "polli:text-theme-text-strong" : "polli:text-theme-text-base"
1153
+ ),
1154
+ children: displayText
1155
+ }
1156
+ ),
1157
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1158
+ ChevronIcon,
1159
+ {
1160
+ expanded: open,
1161
+ className: cn2(
1162
+ "polli:h-3 polli:w-3 polli:transition-transform",
1163
+ open ? "polli:text-theme-text-strong" : "polli:text-theme-text-soft"
1164
+ )
1165
+ }
1166
+ )
1167
+ ]
1168
+ }
1169
+ ),
1170
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(ScrollArea, { theme, className: "polli:max-h-64", children: [
1171
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1172
+ "button",
1173
+ {
1174
+ type: "button",
1175
+ onClick: selectAll,
1176
+ className: cn2(
1177
+ ROW_BASE,
1178
+ isAllSelected ? "polli:bg-theme-bg-active polli:font-medium polli:text-theme-text-strong" : "polli:text-theme-text-base polli:hover:bg-theme-bg-subtle"
1179
+ ),
1180
+ children: [
1181
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1182
+ "span",
1183
+ {
1184
+ className: cn2(
1185
+ CHECK_BASE,
1186
+ isAllSelected && "polli:bg-theme-bg-active polli:text-theme-text-strong"
1187
+ ),
1188
+ children: isAllSelected && "\u2713"
1189
+ }
1190
+ ),
1191
+ placeholder
1192
+ ]
1193
+ }
1194
+ ),
1195
+ options.map((opt) => {
1196
+ const isChecked = selected.includes(opt.value);
1197
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1198
+ "button",
1199
+ {
1200
+ type: "button",
1201
+ onClick: () => toggleItem(opt.value),
1202
+ className: cn2(
1203
+ ROW_BASE,
1204
+ isChecked ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-theme-text-base polli:hover:bg-theme-bg-subtle"
1205
+ ),
1206
+ children: [
1207
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1208
+ "span",
1209
+ {
1210
+ className: cn2(
1211
+ CHECK_BASE,
1212
+ isChecked && "polli:bg-theme-bg-active polli:text-theme-text-strong"
1213
+ ),
1214
+ children: isChecked && "\u2713"
1215
+ }
1216
+ ),
1217
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "polli:whitespace-nowrap", children: opt.label })
1218
+ ]
1219
+ },
1220
+ opt.value
1221
+ );
1222
+ })
1223
+ ] })
1224
+ }
1225
+ )
1226
+ ]
1227
+ }
1228
+ );
1229
+ };
1230
+
1231
+ // src/primitives/PeriodPicker.tsx
1232
+ var import_react7 = require("react");
1233
+
1234
+ // src/primitives/TabButton.tsx
1235
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1236
+ var sizeClasses2 = {
1237
+ medium: "polli:px-4 polli:py-1.5 polli:text-base",
1238
+ small: "polli:px-3 polli:py-1.5 polli:text-sm"
1239
+ };
1240
+ var TabButton = ({
1241
+ theme,
1242
+ active,
1243
+ onClick,
1244
+ children,
1245
+ size = "medium",
1246
+ ariaLabel,
1247
+ disabled = false,
1248
+ className
1249
+ }) => {
1250
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1251
+ "button",
1252
+ {
1253
+ type: "button",
1254
+ "data-theme": theme,
1255
+ onClick,
1256
+ "aria-label": ariaLabel,
1257
+ "aria-pressed": active,
1258
+ disabled,
1259
+ className: cn2(
1260
+ "polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:border polli:font-medium polli:leading-normal polli:transition-all polli:duration-200",
1261
+ active ? "polli:bg-theme-bg-active polli:text-theme-text-strong polli:border-theme-border" : "polli:bg-theme-bg-subtle polli:text-theme-text-base polli:border-theme-border polli:hover:bg-theme-bg-active",
1262
+ disabled && "polli:cursor-not-allowed polli:opacity-50",
1263
+ sizeClasses2[size],
1264
+ className
1265
+ ),
1266
+ children
1267
+ }
1268
+ );
1269
+ };
1270
+
1271
+ // src/primitives/PeriodPicker.tsx
1272
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1273
+ var WEEKDAY_LABELS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
1274
+ var MONTH_LABELS = [
1275
+ "Jan",
1276
+ "Feb",
1277
+ "Mar",
1278
+ "Apr",
1279
+ "May",
1280
+ "Jun",
1281
+ "Jul",
1282
+ "Aug",
1283
+ "Sep",
1284
+ "Oct",
1285
+ "Nov",
1286
+ "Dec"
1287
+ ];
1288
+ var NAV_BUTTON = "polli:rounded-full polli:px-2 polli:py-1 polli:text-xs polli:font-semibold polli:text-theme-text-base polli:transition-colors polli:hover:bg-theme-bg-subtle";
1289
+ function addUtcMonths2(date, months) {
1290
+ return new Date(
1291
+ Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1)
1292
+ );
1293
+ }
1294
+ function monthGridDates(viewMonth) {
1295
+ const firstDay = new Date(
1296
+ Date.UTC(viewMonth.getUTCFullYear(), viewMonth.getUTCMonth(), 1)
1297
+ );
1298
+ const firstWeekday = firstDay.getUTCDay() || 7;
1299
+ const cursor = addUtcDays(firstDay, 1 - firstWeekday);
1300
+ return Array.from({ length: 42 }, (_, index) => addUtcDays(cursor, index));
1301
+ }
1302
+ function sameUtcDay(left, right) {
1303
+ return left.getTime() === right.getTime();
1304
+ }
1305
+ function periodDate(value) {
1306
+ return periodToWindow(value).start;
1307
+ }
1308
+ function viewBounds(viewDate, granularity) {
1309
+ if (granularity === "month") {
1310
+ const start2 = new Date(Date.UTC(viewDate.getUTCFullYear(), 0, 1));
1311
+ return { start: start2, end: addUtcMonths2(start2, 12) };
1312
+ }
1313
+ const start = new Date(
1314
+ Date.UTC(viewDate.getUTCFullYear(), viewDate.getUTCMonth(), 1)
1315
+ );
1316
+ return { start, end: addUtcMonths2(start, 1) };
1317
+ }
1318
+ var PeriodPicker = ({
1319
+ value,
1320
+ onChange,
1321
+ theme,
1322
+ minDate = /* @__PURE__ */ new Date(0),
1323
+ maxDate
1324
+ }) => {
1325
+ const [open, setOpen] = (0, import_react7.useState)(false);
1326
+ const [viewDate, setViewDate] = (0, import_react7.useState)(() => periodDate(value));
1327
+ const { granularity, period } = value;
1328
+ (0, import_react7.useEffect)(() => {
1329
+ setViewDate(periodDate({ granularity, period }));
1330
+ }, [granularity, period]);
1331
+ const dates = (0, import_react7.useMemo)(() => monthGridDates(viewDate), [viewDate]);
1332
+ const selectedWindow = periodToWindow(value);
1333
+ const today = startOfUtcDay(maxDate);
1334
+ const previousViewDate = value.granularity === "month" ? addUtcMonths2(viewDate, -12) : addUtcMonths2(viewDate, -1);
1335
+ const nextViewDate = value.granularity === "month" ? addUtcMonths2(viewDate, 12) : addUtcMonths2(viewDate, 1);
1336
+ const previousBounds = viewBounds(previousViewDate, value.granularity);
1337
+ const nextBounds = viewBounds(nextViewDate, value.granularity);
1338
+ const previousDisabled = previousBounds.end <= minDate;
1339
+ const nextDisabled = nextBounds.start > today;
1340
+ const setGranularity = (granularity2) => {
1341
+ onChange(periodFromDate(granularity2, periodDate(value)));
1342
+ };
1343
+ const selectDate = (date) => {
1344
+ onChange(periodFromDate(value.granularity, date));
1345
+ setOpen(false);
1346
+ };
1347
+ const viewLabel = value.granularity === "month" ? String(viewDate.getUTCFullYear()) : viewDate.toLocaleDateString("en-US", {
1348
+ timeZone: "UTC",
1349
+ month: "long",
1350
+ year: "numeric"
1351
+ });
1352
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1353
+ "div",
1354
+ {
1355
+ "data-theme": theme,
1356
+ className: "polli:flex polli:flex-wrap polli:items-center polli:gap-2",
1357
+ children: [
1358
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "polli:flex polli:flex-wrap polli:gap-1.5", children: ["day", "week", "month"].map(
1359
+ (granularity2) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1360
+ TabButton,
1361
+ {
1362
+ active: value.granularity === granularity2,
1363
+ onClick: () => setGranularity(granularity2),
1364
+ children: granularity2[0].toUpperCase() + granularity2.slice(1)
1365
+ },
1366
+ granularity2
1367
+ )
1368
+ ) }),
1369
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1370
+ Dropdown,
1371
+ {
1372
+ theme,
1373
+ open,
1374
+ onOpenChange: setOpen,
1375
+ className: "polli:w-[304px] polli:rounded-xl polli:p-3",
1376
+ trigger: (isOpen) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1377
+ "button",
1378
+ {
1379
+ type: "button",
1380
+ "aria-label": `Select period, current ${formatPeriodLabel(value)}`,
1381
+ className: cn2(
1382
+ "polli:inline-flex polli:min-w-[150px] polli:items-center polli:justify-between polli:gap-2 polli:rounded-full polli:border polli:px-4 polli:pt-1.5 polli:pb-2 polli:text-left polli:text-base polli:font-medium polli:leading-normal",
1383
+ "polli:border-theme-border polli:bg-theme-bg-subtle polli:text-theme-text-base",
1384
+ "polli:transition-all polli:duration-200 polli:ease-out polli:hover:bg-theme-bg-pale",
1385
+ isOpen && "polli:bg-theme-bg-active polli:text-theme-text-strong polli:shadow-sm"
1386
+ ),
1387
+ children: [
1388
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: formatPeriodLabel(value) }),
1389
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronIcon, { expanded: isOpen })
1390
+ ]
1391
+ }
1392
+ ),
1393
+ children: [
1394
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "polli:mb-3 polli:flex polli:items-center polli:justify-between", children: [
1395
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1396
+ "button",
1397
+ {
1398
+ type: "button",
1399
+ "aria-label": value.granularity === "month" ? "Previous year" : "Previous month",
1400
+ disabled: previousDisabled,
1401
+ onClick: () => setViewDate(previousViewDate),
1402
+ className: cn2(
1403
+ NAV_BUTTON,
1404
+ previousDisabled && "polli:cursor-not-allowed polli:opacity-30 polli:hover:bg-transparent"
1405
+ ),
1406
+ children: "<"
1407
+ }
1408
+ ),
1409
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "polli:text-sm polli:font-bold polli:text-theme-text-base", children: viewLabel }),
1410
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1411
+ "button",
1412
+ {
1413
+ type: "button",
1414
+ "aria-label": value.granularity === "month" ? "Next year" : "Next month",
1415
+ disabled: nextDisabled,
1416
+ onClick: () => setViewDate(nextViewDate),
1417
+ className: cn2(
1418
+ NAV_BUTTON,
1419
+ nextDisabled && "polli:cursor-not-allowed polli:opacity-30 polli:hover:bg-transparent"
1420
+ ),
1421
+ children: ">"
1422
+ }
1423
+ )
1424
+ ] }),
1425
+ value.granularity === "month" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "polli:grid polli:grid-cols-3 polli:gap-1.5", children: MONTH_LABELS.map((label, monthIndex) => {
1426
+ const date = new Date(
1427
+ Date.UTC(
1428
+ viewDate.getUTCFullYear(),
1429
+ monthIndex,
1430
+ 1
1431
+ )
1432
+ );
1433
+ const selectable = isPeriodSelectable(
1434
+ periodFromDate("month", date),
1435
+ minDate,
1436
+ today
1437
+ );
1438
+ const ariaLabel = date.toLocaleDateString("en-US", {
1439
+ timeZone: "UTC",
1440
+ month: "long",
1441
+ year: "numeric"
1442
+ });
1443
+ const selected = date.getUTCFullYear() === selectedWindow.start.getUTCFullYear() && date.getUTCMonth() === selectedWindow.start.getUTCMonth();
1444
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1445
+ "button",
1446
+ {
1447
+ type: "button",
1448
+ "aria-label": ariaLabel,
1449
+ disabled: !selectable,
1450
+ onClick: () => selectDate(date),
1451
+ className: cn2(
1452
+ "polli:rounded-lg polli:px-3 polli:py-2 polli:text-xs polli:font-medium polli:transition-colors polli:duration-150",
1453
+ selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-gray-700 polli:hover:bg-theme-bg-subtle",
1454
+ !selectable && "polli:cursor-not-allowed polli:text-gray-300 polli:hover:bg-transparent"
1455
+ ),
1456
+ children: label
1457
+ },
1458
+ label
1459
+ );
1460
+ }) }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1461
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "polli:mb-1 polli:grid polli:grid-cols-7 polli:gap-1 polli:text-center polli:text-micro polli:font-bold polli:uppercase polli:text-gray-400", children: WEEKDAY_LABELS.map((label) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { children: label }, label)) }),
1462
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "polli:grid polli:grid-cols-7 polli:gap-1", children: dates.map((date) => {
1463
+ const inCurrentMonth = date.getUTCMonth() === viewDate.getUTCMonth();
1464
+ const selectable = isPeriodSelectable(
1465
+ periodFromDate(value.granularity, date),
1466
+ minDate,
1467
+ today
1468
+ );
1469
+ const ariaLabel = value.granularity === "week" ? `Select week ${formatPeriodLabel(periodFromDate("week", date))}` : `Select ${date.toLocaleDateString(
1470
+ "en-US",
1471
+ {
1472
+ timeZone: "UTC",
1473
+ weekday: "long",
1474
+ month: "long",
1475
+ day: "numeric",
1476
+ year: "numeric"
1477
+ }
1478
+ )}`;
1479
+ const selected = value.granularity === "day" ? sameUtcDay(date, selectedWindow.start) : date >= selectedWindow.start && date < selectedWindow.end;
1480
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1481
+ "button",
1482
+ {
1483
+ type: "button",
1484
+ "aria-label": ariaLabel,
1485
+ disabled: !selectable,
1486
+ onClick: () => selectDate(date),
1487
+ className: cn2(
1488
+ "polli:aspect-square polli:rounded-lg polli:text-xs polli:font-medium polli:transition-colors polli:duration-150",
1489
+ !inCurrentMonth && "polli:text-gray-300",
1490
+ sameUtcDay(date, today) && "polli:ring-1 polli:ring-theme-border",
1491
+ selected ? "polli:bg-theme-bg-active polli:text-theme-text-strong" : "polli:text-gray-700 polli:hover:bg-theme-bg-subtle",
1492
+ !selectable && "polli:cursor-not-allowed polli:text-gray-300 polli:hover:bg-transparent"
1493
+ ),
1494
+ children: date.getUTCDate()
1495
+ },
1496
+ date.toISOString()
1497
+ );
1498
+ }) })
1499
+ ] })
1500
+ ]
1501
+ }
1502
+ )
1503
+ ]
1504
+ }
1505
+ );
1506
+ };
1507
+
1508
+ // src/primitives/Surface.tsx
1509
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1510
+ var variantClasses = {
1511
+ panel: "polli:rounded-2xl polli:border polli:border-theme-border polli:bg-theme-bg-subtle polli:p-6",
1512
+ card: "polli:rounded-xl polli:bg-surface-white polli:p-4",
1513
+ "card-themed": "polli:rounded-xl polli:bg-theme-bg-pale polli:p-4"
1514
+ };
1515
+ var Surface = ({
1516
+ theme,
1517
+ variant = "card",
1518
+ className,
1519
+ children,
1520
+ ...rest
1521
+ }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1522
+ "div",
1523
+ {
1524
+ ...rest,
1525
+ "data-theme": theme,
1526
+ className: cn2("polli:min-w-0", variantClasses[variant], className),
1527
+ children
1528
+ }
1529
+ );
1530
+
1531
+ // src/primitives/Section.tsx
1532
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1533
+ var Section = ({
1534
+ title,
1535
+ theme,
1536
+ id,
1537
+ framed = false,
1538
+ action,
1539
+ actionClassName,
1540
+ children,
1541
+ className
1542
+ }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("section", { id, className: cn2("scroll-mt-10 space-y-2", className), children: [
1543
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 px-1", children: [
1544
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1545
+ "h2",
1546
+ {
1547
+ "data-theme": theme,
1548
+ className: "text-left text-lg font-semibold sm:text-xl text-theme-text-strong",
1549
+ children: title
1550
+ }
1551
+ ),
1552
+ action && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cn2("shrink-0", actionClassName), children: action })
1553
+ ] }),
1554
+ framed ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Surface, { variant: "panel", theme, children }) : children
1555
+ ] });
1556
+
1557
+ // src/primitives/Slider.tsx
1558
+ var import_react8 = require("react");
1559
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1560
+ var toNumber = (value) => {
1561
+ if (typeof value === "number") return value;
1562
+ if (typeof value !== "string" || value.trim() === "") return void 0;
1563
+ const numericValue = Number(value);
1564
+ return Number.isFinite(numericValue) ? numericValue : void 0;
1565
+ };
1566
+ var clampPercent = (value) => Math.min(100, Math.max(0, value));
1567
+ var getProgressPercent = ({
1568
+ progress,
1569
+ value,
1570
+ defaultValue,
1571
+ min,
1572
+ max
1573
+ }) => {
1574
+ if (typeof progress === "number" && Number.isFinite(progress)) {
1575
+ return clampPercent(progress);
1576
+ }
1577
+ const numericValue = toNumber(value ?? defaultValue);
1578
+ if (numericValue === void 0) return void 0;
1579
+ const numericMin = toNumber(min) ?? 0;
1580
+ const numericMax = toNumber(max) ?? 100;
1581
+ if (numericMax <= numericMin) return 100;
1582
+ return clampPercent(
1583
+ (numericValue - numericMin) / (numericMax - numericMin) * 100
1584
+ );
1585
+ };
1586
+ var Slider = (0, import_react8.forwardRef)(
1587
+ ({ className, defaultValue, max, min, progress, style, value, ...props }, ref) => {
1588
+ const progressPercent = getProgressPercent({
1589
+ progress,
1590
+ value,
1591
+ defaultValue,
1592
+ min,
1593
+ max
1594
+ });
1595
+ const sliderStyle = {
1596
+ ...style,
1597
+ ...progressPercent === void 0 ? null : { "--polli-slider-progress": `${progressPercent}%` }
1598
+ };
1599
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1600
+ "input",
1601
+ {
1602
+ ref,
1603
+ type: "range",
1604
+ min,
1605
+ max,
1606
+ value,
1607
+ defaultValue,
1608
+ style: sliderStyle,
1609
+ className: cn2("polli-slider", className),
1610
+ ...props
1611
+ }
1612
+ );
1613
+ }
1614
+ );
1615
+
1616
+ // src/primitives/StatCard.tsx
1617
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1618
+ var StatCard = ({
1619
+ label,
1620
+ value,
1621
+ detail,
1622
+ theme,
1623
+ className,
1624
+ labelClassName,
1625
+ valueClassName,
1626
+ detailClassName
1627
+ }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { "data-theme": theme, className: cn2("polli:text-sm", className), children: [
1628
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1629
+ "div",
1630
+ {
1631
+ className: cn2(
1632
+ "polli:text-micro polli:font-bold polli:uppercase polli:tracking-wide polli:text-theme-text-strong",
1633
+ labelClassName
1634
+ ),
1635
+ children: label
1636
+ }
1637
+ ),
1638
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1639
+ "div",
1640
+ {
1641
+ className: cn2(
1642
+ "polli:mt-1 polli:min-h-8 polli:break-words polli:text-2xl polli:font-bold polli:leading-tight polli:tabular-nums polli:text-theme-text-strong",
1643
+ valueClassName
1644
+ ),
1645
+ children: value
1646
+ }
1647
+ ),
1648
+ detail && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1649
+ "div",
1650
+ {
1651
+ className: cn2(
1652
+ "polli:mt-2 polli:text-xs polli:text-theme-text-soft",
1653
+ detailClassName
1654
+ ),
1655
+ children: detail
1656
+ }
1657
+ )
1658
+ ] });
1659
+
1660
+ // src/primitives/Switch.tsx
1661
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1662
+ var trackClasses = {
1663
+ off: "polli:bg-gray-200",
1664
+ on: "polli:bg-[oklch(0.88_0.12_158)]",
1665
+ invalid: "polli:bg-[oklch(0.88_0.12_25)]"
1666
+ };
1667
+ var Switch = ({
1668
+ checked,
1669
+ onChange,
1670
+ status,
1671
+ ariaLabel,
1672
+ disabled = false,
1673
+ className
1674
+ }) => {
1675
+ const effectiveStatus = status ?? (checked ? "on" : "off");
1676
+ const resolvedAriaLabel = ariaLabel ?? (checked ? "Turn off toggle" : "Turn on toggle");
1677
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1678
+ "button",
1679
+ {
1680
+ type: "button",
1681
+ role: "switch",
1682
+ "aria-checked": checked,
1683
+ "aria-label": resolvedAriaLabel,
1684
+ onClick: () => onChange(!checked),
1685
+ disabled,
1686
+ className: cn2(
1687
+ "polli:relative polli:inline-flex polli:h-7 polli:w-12 polli:shrink-0 polli:items-center polli:rounded-full polli:transition polli:disabled:cursor-not-allowed polli:disabled:opacity-60",
1688
+ trackClasses[effectiveStatus],
1689
+ className
1690
+ ),
1691
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1692
+ "span",
1693
+ {
1694
+ className: cn2(
1695
+ "polli:inline-block polli:h-5 polli:w-5 polli:rounded-full polli:bg-white polli:shadow-sm polli:transition-transform",
1696
+ checked ? "polli:translate-x-6" : "polli:translate-x-1"
1697
+ )
1698
+ }
1699
+ )
1700
+ }
1701
+ );
1702
+ };
1703
+
1704
+ // src/theme.ts
1705
+ var themes = [
1706
+ "amber",
1707
+ "blue",
1708
+ "pink",
1709
+ "teal",
1710
+ "violet",
1711
+ "green"
1712
+ ];
1713
+ var themeColors = {
1714
+ amber: "#FEF3C7",
1715
+ blue: "#DBEAFE"
1716
+ };
1717
+ // Annotate the CommonJS export names for ESM import in node:
1718
+ 0 && (module.exports = {
1719
+ AppIcon,
1720
+ BeakerIcon,
1721
+ BookIcon,
1722
+ Button,
1723
+ CheckIcon,
1724
+ ChevronIcon,
1725
+ Chip,
1726
+ ClipboardIcon,
1727
+ ClockIcon,
1728
+ Collapsible,
1729
+ CopyButton,
1730
+ Dialog,
1731
+ DialogTitle,
1732
+ DiscordIcon,
1733
+ DownloadIcon,
1734
+ Dropdown,
1735
+ ExternalLinkButton,
1736
+ ExternalLinkIcon,
1737
+ Field,
1738
+ GenApiIcon,
1739
+ GitHubIcon,
1740
+ IconButton,
1741
+ ImageIcon,
1742
+ InfoTip,
1743
+ Input,
1744
+ LockIcon,
1745
+ MailIcon,
1746
+ McpIcon,
1747
+ MenuIcon,
1748
+ MultiSelect,
1749
+ PeriodPicker,
1750
+ ScrollArea,
1751
+ Section,
1752
+ Slider,
1753
+ StatCard,
1754
+ Surface,
1755
+ Switch,
1756
+ TabButton,
1757
+ TerminalIcon,
1758
+ TokensIcon,
1759
+ Tooltip,
1760
+ TrendUpIcon,
1761
+ WalletIcon,
1762
+ XIcon,
1763
+ cn,
1764
+ currentPeriod,
1765
+ getPeriodBucketKeys,
1766
+ periodBucketKeyToDate,
1767
+ themeColors,
1768
+ themes,
1769
+ useScrollLock
1770
+ });
1771
+ //# sourceMappingURL=index.cjs.map