@pollinations/ui 0.0.2 → 0.1.0-alpha.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 (59) hide show
  1. package/README.md +38 -71
  2. package/dist/{Chip-SM52sUbZ.d.cts → Chip-CQCq34kS.d.cts} +1 -1
  3. package/dist/{Chip-C5impfYd.d.ts → Chip-Cj4xG7Te.d.ts} +1 -1
  4. package/dist/app-user-menu/sdk.cjs +497 -0
  5. package/dist/app-user-menu/sdk.cjs.map +1 -0
  6. package/dist/app-user-menu/sdk.d.cts +18 -0
  7. package/dist/app-user-menu/sdk.d.ts +18 -0
  8. package/dist/app-user-menu/sdk.js +469 -0
  9. package/dist/app-user-menu/sdk.js.map +1 -0
  10. package/dist/app.css +94 -3
  11. package/dist/auth/index.cjs +77 -62
  12. package/dist/auth/index.cjs.map +1 -1
  13. package/dist/auth/index.js +77 -62
  14. package/dist/auth/index.js.map +1 -1
  15. package/dist/gen/index.cjs +477 -0
  16. package/dist/gen/index.cjs.map +1 -0
  17. package/dist/gen/index.d.cts +35 -0
  18. package/dist/gen/index.d.ts +35 -0
  19. package/dist/gen/index.js +451 -0
  20. package/dist/gen/index.js.map +1 -0
  21. package/dist/index.cjs +1875 -761
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +294 -109
  24. package/dist/index.d.ts +294 -109
  25. package/dist/index.js +1889 -798
  26. package/dist/index.js.map +1 -1
  27. package/dist/styles.css +1 -1
  28. package/dist/theme-jRPPBmld.d.cts +20 -0
  29. package/dist/theme-jRPPBmld.d.ts +20 -0
  30. package/dist/wallet/index.cjs +17 -8
  31. package/dist/wallet/index.cjs.map +1 -1
  32. package/dist/wallet/index.d.cts +2 -2
  33. package/dist/wallet/index.d.ts +2 -2
  34. package/dist/wallet/index.js +17 -8
  35. package/dist/wallet/index.js.map +1 -1
  36. package/package.json +15 -18
  37. package/dist/Button-Bn8pGg6N.d.ts +0 -26
  38. package/dist/Button-CWUBCiIc.d.cts +0 -26
  39. package/dist/auth/sdk.cjs +0 -220
  40. package/dist/auth/sdk.cjs.map +0 -1
  41. package/dist/auth/sdk.d.cts +0 -53
  42. package/dist/auth/sdk.d.ts +0 -53
  43. package/dist/auth/sdk.js +0 -187
  44. package/dist/auth/sdk.js.map +0 -1
  45. package/dist/modality/index.cjs +0 -83
  46. package/dist/modality/index.cjs.map +0 -1
  47. package/dist/modality/index.d.cts +0 -25
  48. package/dist/modality/index.d.ts +0 -25
  49. package/dist/modality/index.js +0 -56
  50. package/dist/modality/index.js.map +0 -1
  51. package/dist/theme-VMRlhqST.d.cts +0 -9
  52. package/dist/theme-VMRlhqST.d.ts +0 -9
  53. package/dist/wallet/sdk.cjs +0 -206
  54. package/dist/wallet/sdk.cjs.map +0 -1
  55. package/dist/wallet/sdk.d.cts +0 -33
  56. package/dist/wallet/sdk.d.ts +0 -33
  57. package/dist/wallet/sdk.js +0 -175
  58. package/dist/wallet/sdk.js.map +0 -1
  59. package/dist/wallet.css +0 -73
@@ -0,0 +1,477 @@
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/modules/gen/index.ts
21
+ var gen_exports = {};
22
+ __export(gen_exports, {
23
+ CATEGORY_LABELS: () => CATEGORY_LABELS,
24
+ ModelSelector: () => ModelSelector,
25
+ categoryLabel: () => categoryLabel,
26
+ getModalityTheme: () => getModalityTheme,
27
+ modalityTheme: () => modalityTheme
28
+ });
29
+ module.exports = __toCommonJS(gen_exports);
30
+
31
+ // src/lib/cn.ts
32
+ var import_clsx = require("clsx");
33
+ var import_tailwind_merge = require("tailwind-merge");
34
+ var twMerge = (0, import_tailwind_merge.extendTailwindMerge)({ prefix: "polli" });
35
+ function cn(...inputs) {
36
+ return twMerge((0, import_clsx.clsx)(...inputs));
37
+ }
38
+
39
+ // src/primitives/Button.tsx
40
+ var import_jsx_runtime = require("react/jsx-runtime");
41
+ var sizes = {
42
+ sm: "polli:px-2 polli:pt-0.5 polli:pb-1",
43
+ md: "polli:px-4 polli:pt-1.5 polli:pb-2",
44
+ lg: "polli:px-6 polli:py-3"
45
+ };
46
+ var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:transition-colors";
47
+ var intentClasses = {
48
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-intent-danger-bg-hover polli:transition-colors"
49
+ };
50
+ var buttonClasses = ({
51
+ theme: _theme,
52
+ intent,
53
+ size,
54
+ className,
55
+ disabled
56
+ }) => {
57
+ const colorClasses = intent ? intentClasses[intent] : themeClasses;
58
+ return cn(
59
+ "polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:font-medium polli:leading-normal polli:box-border",
60
+ disabled ? "polli:opacity-50 polli:cursor-not-allowed" : "polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer",
61
+ colorClasses,
62
+ sizes[size || "md"],
63
+ className
64
+ );
65
+ };
66
+ function Button({
67
+ as,
68
+ children,
69
+ theme,
70
+ intent,
71
+ size,
72
+ className,
73
+ disabled,
74
+ ...buttonProps
75
+ }) {
76
+ const Component = as || "button";
77
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
+ Component,
79
+ {
80
+ "data-theme": intent ? void 0 : theme,
81
+ "data-intent": intent,
82
+ className: buttonClasses({
83
+ theme,
84
+ intent,
85
+ size,
86
+ className,
87
+ disabled
88
+ }),
89
+ disabled,
90
+ ...buttonProps,
91
+ children
92
+ }
93
+ );
94
+ }
95
+
96
+ // src/primitives/ChevronIcon.tsx
97
+ var import_jsx_runtime2 = require("react/jsx-runtime");
98
+ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
99
+ "svg",
100
+ {
101
+ "aria-hidden": "true",
102
+ width: "12",
103
+ height: "12",
104
+ viewBox: "0 0 12 12",
105
+ className: cn(
106
+ "polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out",
107
+ expanded && "polli:rotate-180",
108
+ className
109
+ ),
110
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
111
+ "path",
112
+ {
113
+ d: "M3 4.5 6 7.5l3-3",
114
+ fill: "none",
115
+ stroke: "currentColor",
116
+ strokeLinecap: "round",
117
+ strokeLinejoin: "round",
118
+ strokeWidth: "1.5"
119
+ }
120
+ )
121
+ }
122
+ );
123
+
124
+ // src/primitives/Chip.tsx
125
+ var import_jsx_runtime3 = require("react/jsx-runtime");
126
+ var chipSizes = {
127
+ sm: "polli:px-2 polli:py-0.5 polli:text-xs",
128
+ md: "polli:px-2.5 polli:py-0.5 polli:text-sm",
129
+ lg: "polli:px-3 polli:py-1 polli:text-sm"
130
+ };
131
+ var intentClasses2 = {
132
+ news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
133
+ alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
134
+ neutral: "polli:bg-ink-100/80 polli:text-ink-900",
135
+ success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
136
+ warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
137
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
138
+ };
139
+ var Chip = ({
140
+ theme,
141
+ intent,
142
+ size = "md",
143
+ className,
144
+ children,
145
+ ...rest
146
+ }) => {
147
+ const intentClass = intent ? intentClasses2[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
148
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
149
+ "span",
150
+ {
151
+ ...rest,
152
+ "data-theme": theme,
153
+ className: cn(
154
+ "polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal",
155
+ chipSizes[size],
156
+ intentClass,
157
+ className
158
+ ),
159
+ children
160
+ }
161
+ );
162
+ };
163
+
164
+ // src/primitives/Dropdown.tsx
165
+ var import_popover = require("@ark-ui/react/popover");
166
+ var import_portal = require("@ark-ui/react/portal");
167
+ var import_react = require("react");
168
+ var import_jsx_runtime4 = require("react/jsx-runtime");
169
+ var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg";
170
+ var Dropdown = ({
171
+ theme,
172
+ trigger,
173
+ children,
174
+ align = "start",
175
+ open: openProp,
176
+ onOpenChange,
177
+ className
178
+ }) => {
179
+ const [internalOpen, setInternalOpen] = (0, import_react.useState)(false);
180
+ const isControlled = openProp !== void 0;
181
+ const open = isControlled ? openProp : internalOpen;
182
+ const setOpen = (next) => {
183
+ if (!isControlled) setInternalOpen(next);
184
+ onOpenChange?.(next);
185
+ };
186
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
187
+ import_popover.Popover.Root,
188
+ {
189
+ open,
190
+ onOpenChange: (details) => setOpen(details.open),
191
+ positioning: {
192
+ placement: align === "end" ? "bottom-end" : "bottom-start"
193
+ },
194
+ children: [
195
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_popover.Popover.Trigger, { asChild: true, children: trigger(open) }),
196
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_portal.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_popover.Popover.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
197
+ import_popover.Popover.Content,
198
+ {
199
+ "data-theme": theme,
200
+ className: cn(
201
+ "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
202
+ DEFAULT_PANEL,
203
+ className
204
+ ),
205
+ children: typeof children === "function" ? children(() => setOpen(false)) : children
206
+ }
207
+ ) }) })
208
+ ]
209
+ }
210
+ );
211
+ };
212
+
213
+ // src/primitives/ScrollArea.tsx
214
+ var import_react2 = require("react");
215
+ var import_jsx_runtime5 = require("react/jsx-runtime");
216
+ var axisClasses = {
217
+ y: "polli:overflow-y-auto polli:overflow-x-hidden",
218
+ x: "polli:overflow-x-auto polli:overflow-y-hidden"
219
+ };
220
+ function assignRef(ref, value) {
221
+ if (typeof ref === "function") ref(value);
222
+ else if (ref) ref.current = value;
223
+ }
224
+ var ScrollArea = (0, import_react2.forwardRef)(
225
+ ({ theme, axis = "y", className, children, ...rest }, externalRef) => {
226
+ const innerRef = (0, import_react2.useRef)(null);
227
+ const setRef = (0, import_react2.useCallback)(
228
+ (node) => {
229
+ innerRef.current = node;
230
+ assignRef(externalRef, node);
231
+ },
232
+ [externalRef]
233
+ );
234
+ (0, import_react2.useEffect)(() => {
235
+ const element = innerRef.current;
236
+ if (!element) return;
237
+ let hideTimer = null;
238
+ const clearHideTimer = () => {
239
+ if (hideTimer !== null) {
240
+ window.clearTimeout(hideTimer);
241
+ hideTimer = null;
242
+ }
243
+ };
244
+ const show = () => {
245
+ element.dataset.scrollbarActive = "true";
246
+ clearHideTimer();
247
+ };
248
+ const hide = () => {
249
+ element.dataset.scrollbarActive = "false";
250
+ clearHideTimer();
251
+ };
252
+ const scheduleHide = () => {
253
+ clearHideTimer();
254
+ hideTimer = window.setTimeout(hide, 2e3);
255
+ };
256
+ const handleInteraction = () => {
257
+ show();
258
+ scheduleHide();
259
+ };
260
+ hide();
261
+ element.addEventListener("scroll", handleInteraction, {
262
+ passive: true
263
+ });
264
+ element.addEventListener("wheel", handleInteraction, {
265
+ passive: true
266
+ });
267
+ element.addEventListener("touchstart", handleInteraction, {
268
+ passive: true
269
+ });
270
+ element.addEventListener("pointerdown", handleInteraction);
271
+ element.addEventListener("keydown", handleInteraction);
272
+ element.addEventListener("focusin", handleInteraction);
273
+ element.addEventListener("focusout", scheduleHide);
274
+ return () => {
275
+ clearHideTimer();
276
+ element.removeEventListener("scroll", handleInteraction);
277
+ element.removeEventListener("wheel", handleInteraction);
278
+ element.removeEventListener("touchstart", handleInteraction);
279
+ element.removeEventListener("pointerdown", handleInteraction);
280
+ element.removeEventListener("keydown", handleInteraction);
281
+ element.removeEventListener("focusin", handleInteraction);
282
+ element.removeEventListener("focusout", scheduleHide);
283
+ };
284
+ }, []);
285
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
286
+ "div",
287
+ {
288
+ ...rest,
289
+ ref: setRef,
290
+ "data-theme": theme,
291
+ className: cn(
292
+ "polli-scrollbar-subtle polli:min-w-0 polli:max-w-full",
293
+ axisClasses[axis],
294
+ className
295
+ ),
296
+ children
297
+ }
298
+ );
299
+ }
300
+ );
301
+ ScrollArea.displayName = "ScrollArea";
302
+
303
+ // src/primitives/TabButton.tsx
304
+ var import_jsx_runtime6 = require("react/jsx-runtime");
305
+ var sizeClasses = {
306
+ md: "polli:px-4 polli:py-1.5 polli:text-base",
307
+ sm: "polli:px-3 polli:py-1.5 polli:text-sm"
308
+ };
309
+ var variantClasses = {
310
+ default: {
311
+ base: "polli:border",
312
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong polli:border-theme-border",
313
+ inactive: "polli:bg-theme-bg-subtle polli:text-theme-text-base polli:border-theme-border polli:hover:bg-theme-bg-active"
314
+ },
315
+ ghost: {
316
+ base: "polli:border polli:border-transparent",
317
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong",
318
+ inactive: "polli:bg-transparent polli:text-theme-text-base polli:hover:bg-theme-bg-subtle polli:hover:text-theme-text-strong"
319
+ }
320
+ };
321
+ var TabButton = ({
322
+ theme,
323
+ active,
324
+ onClick,
325
+ children,
326
+ size = "md",
327
+ variant = "default",
328
+ ariaLabel,
329
+ disabled = false,
330
+ className
331
+ }) => {
332
+ const classes = variantClasses[variant];
333
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
334
+ "button",
335
+ {
336
+ type: "button",
337
+ "data-theme": theme,
338
+ onClick,
339
+ "aria-label": ariaLabel,
340
+ "aria-pressed": active,
341
+ disabled,
342
+ className: cn(
343
+ "polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:font-medium polli:leading-normal polli:transition-all polli:duration-200",
344
+ classes.base,
345
+ active ? classes.active : classes.inactive,
346
+ disabled && "polli:cursor-not-allowed polli:opacity-50",
347
+ sizeClasses[size],
348
+ className
349
+ ),
350
+ children
351
+ }
352
+ );
353
+ };
354
+
355
+ // src/modules/gen/themes.ts
356
+ var MODALITY_THEMES = {
357
+ text: "blue",
358
+ image: "pink",
359
+ video: "teal",
360
+ audio: "amber",
361
+ realtime: "coral",
362
+ embedding: "violet"
363
+ };
364
+ function modalityTheme(category) {
365
+ return MODALITY_THEMES[category];
366
+ }
367
+ function normalize(category) {
368
+ const lower = category.toLowerCase();
369
+ if (lower === "images") return "image";
370
+ if (lower === "embeddings") return "embedding";
371
+ return lower in MODALITY_THEMES ? lower : null;
372
+ }
373
+ function getModalityTheme(category) {
374
+ const key = normalize(category);
375
+ return key ? MODALITY_THEMES[key] : null;
376
+ }
377
+
378
+ // src/modules/gen/ModelSelector.tsx
379
+ var import_jsx_runtime7 = require("react/jsx-runtime");
380
+ var CATEGORY_LABELS = {
381
+ image: "Image",
382
+ video: "Video",
383
+ text: "Text",
384
+ audio: "Audio",
385
+ embedding: "Embeddings",
386
+ realtime: "Realtime"
387
+ };
388
+ function categoryLabel(category) {
389
+ return CATEGORY_LABELS[category];
390
+ }
391
+ function displayModelName(model) {
392
+ return model.title;
393
+ }
394
+ function ModelSelector({
395
+ models,
396
+ category,
397
+ value,
398
+ isLoading = false,
399
+ onChange
400
+ }) {
401
+ const filteredModels = models.filter(
402
+ (model) => model.category === category
403
+ );
404
+ const currentModel = models.find((model) => model.id === value);
405
+ const theme = modalityTheme(category);
406
+ const modelLabel = currentModel ? displayModelName(currentModel) : "Select";
407
+ const accessibleLabel = currentModel ? `${CATEGORY_LABELS[category]} model: ${modelLabel}` : `Select ${CATEGORY_LABELS[category].toLowerCase()} model`;
408
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
409
+ Dropdown,
410
+ {
411
+ theme,
412
+ align: "end",
413
+ className: "polli:w-[min(24rem,calc(100vw-2rem))] polli:p-2",
414
+ trigger: (open) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
415
+ Button,
416
+ {
417
+ type: "button",
418
+ theme,
419
+ "aria-label": accessibleLabel,
420
+ className: "polli:min-w-64 polli:max-w-full polli:self-start polli:justify-between polli:gap-2",
421
+ children: [
422
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "polli:truncate", children: modelLabel }),
423
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronIcon, { expanded: open })
424
+ ]
425
+ }
426
+ ),
427
+ children: (close) => isLoading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "polli:m-0 polli:px-2 polli:py-2 polli:text-sm polli:text-theme-text-soft", children: "Loading models..." }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
428
+ ScrollArea,
429
+ {
430
+ theme,
431
+ className: "polli:max-h-64 polli:pr-2",
432
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "polli:flex polli:flex-col polli:gap-1", children: filteredModels.map((model) => {
433
+ const isActive = value === model.id;
434
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
435
+ TabButton,
436
+ {
437
+ active: isActive,
438
+ theme: modalityTheme(model.category),
439
+ size: "sm",
440
+ variant: "ghost",
441
+ className: "polli:w-full polli:justify-between polli:text-left",
442
+ onClick: () => {
443
+ onChange(model.id);
444
+ close();
445
+ },
446
+ children: [
447
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "polli:truncate", children: displayModelName(model) }),
448
+ model.paidOnly && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
449
+ Chip,
450
+ {
451
+ size: "sm",
452
+ className: cn(
453
+ "polli:shrink-0",
454
+ isActive && "polli:bg-surface-white"
455
+ ),
456
+ children: "paid"
457
+ }
458
+ )
459
+ ]
460
+ },
461
+ model.id
462
+ );
463
+ }) })
464
+ }
465
+ )
466
+ }
467
+ );
468
+ }
469
+ // Annotate the CommonJS export names for ESM import in node:
470
+ 0 && (module.exports = {
471
+ CATEGORY_LABELS,
472
+ ModelSelector,
473
+ categoryLabel,
474
+ getModalityTheme,
475
+ modalityTheme
476
+ });
477
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/modules/gen/index.ts","../../src/lib/cn.ts","../../src/primitives/Button.tsx","../../src/primitives/ChevronIcon.tsx","../../src/primitives/Chip.tsx","../../src/primitives/Dropdown.tsx","../../src/primitives/ScrollArea.tsx","../../src/primitives/TabButton.tsx","../../src/modules/gen/themes.ts","../../src/modules/gen/ModelSelector.tsx"],"sourcesContent":["export {\n CATEGORY_LABELS,\n categoryLabel,\n ModelSelector,\n type ModelSelectorCategory,\n type ModelSelectorItem,\n type ModelSelectorProps,\n} from \"./ModelSelector.tsx\";\nexport {\n getModalityTheme,\n type Modality,\n modalityTheme,\n} from \"./themes.ts\";\n","import { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Button only supports `danger`. Label/status color recipes live on Chip. */\ntype ButtonIntent = \"danger\";\n\nconst sizes = {\n sm: \"polli:px-2 polli:pt-0.5 polli:pb-1\",\n md: \"polli:px-4 polli:pt-1.5 polli:pb-2\",\n lg: \"polli:px-6 polli:py-3\",\n} as const;\n\n// Cascade-driven base — reads [data-theme] vars.\nconst themeClasses =\n \"polli:bg-theme-bg-active polli:text-theme-text-base \" +\n \"polli:hover:bg-theme-bg-hover polli:transition-colors\";\n\n// Single intent: danger. Soft recipe — light tile + deep text, slightly\n// deeper bg on hover. No filled CTAs anywhere.\nconst intentClasses: Record<ButtonIntent, string> = {\n danger:\n \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text \" +\n \"polli:hover:bg-intent-danger-bg-hover polli:transition-colors\",\n};\n\ntype BaseButtonProps = {\n /** Override the cascade theme for this button's subtree. Ignored when `intent` is set. */\n theme?: ThemeName;\n /** Only `\"danger\"` for now. */\n intent?: ButtonIntent;\n size?: keyof typeof sizes;\n className?: string;\n disabled?: boolean;\n};\n\nconst buttonClasses = ({\n theme: _theme,\n intent,\n size,\n className,\n disabled,\n}: BaseButtonProps & { disabled?: boolean }) => {\n const colorClasses = intent ? intentClasses[intent] : themeClasses;\n return cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:font-medium polli:leading-normal polli:box-border\",\n disabled\n ? \"polli:opacity-50 polli:cursor-not-allowed\"\n : \"polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer\",\n colorClasses,\n sizes[size || \"md\"],\n className,\n );\n};\n\nexport type ButtonProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseButtonProps> & {\n as?: T;\n } & Omit<React.ComponentPropsWithoutRef<T>, keyof BaseButtonProps | \"as\">;\n\nexport function Button<T extends React.ElementType = \"button\">({\n as,\n children,\n theme,\n intent,\n size,\n className,\n disabled,\n ...buttonProps\n}: ButtonProps<T>) {\n const Component: React.ElementType = as || \"button\";\n\n return (\n <Component\n // Cascade override only applies when `intent` is unset.\n data-theme={intent ? undefined : theme}\n data-intent={intent}\n className={buttonClasses({\n theme,\n intent,\n size,\n className,\n disabled,\n })}\n disabled={disabled}\n {...buttonProps}\n >\n {children}\n </Component>\n );\n}\n","import type { FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype ChevronIconProps = {\n /** Rotate 180° when expanded/open. */\n expanded?: boolean;\n className?: string;\n};\n\n/**\n * Canonical chevron used for collapsibles, dropdown triggers, and select pills\n * across the app. One icon everywhere.\n */\nexport const ChevronIcon: FC<ChevronIconProps> = ({ expanded, className }) => (\n <svg\n aria-hidden=\"true\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n className={cn(\n \"polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out\",\n expanded && \"polli:rotate-180\",\n className,\n )}\n >\n <path\n d=\"M3 4.5 6 7.5l3-3\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n />\n </svg>\n);\n","import type { ComponentPropsWithoutRef, FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Semantic chip labels for status and metadata badges. */\ntype ChipIntent =\n | \"news\"\n | \"alpha\"\n | \"neutral\"\n | \"success\"\n | \"warning\"\n | \"danger\";\n\nconst chipSizes = {\n sm: \"polli:px-2 polli:py-0.5 polli:text-xs\",\n md: \"polli:px-2.5 polli:py-0.5 polli:text-sm\",\n lg: \"polli:px-3 polli:py-1 polli:text-sm\",\n} as const;\n\nconst intentClasses: Record<ChipIntent, string> = {\n news: \"polli:bg-intent-news-bg-light polli:text-intent-news-text\",\n alpha: \"polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text\",\n neutral: \"polli:bg-ink-100/80 polli:text-ink-900\",\n success: \"polli:bg-intent-success-bg-light polli:text-intent-success-text\",\n warning: \"polli:bg-intent-warning-bg-light polli:text-intent-warning-text\",\n danger: \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text\",\n};\n\nexport type ChipProps = ComponentPropsWithoutRef<\"span\"> & {\n /** Override the cascade theme for this chip's subtree. */\n theme?: ThemeName;\n /** Semantic intent. Wins over `theme` when set. */\n intent?: ChipIntent;\n size?: keyof typeof chipSizes;\n};\n\n// Static, rectangular colored container. Round shapes are reserved for buttons.\n// Reads `bg-theme-bg-active` / `text-theme-text-strong` from the cascade unless\n// `intent` is set (semantic, theme-independent).\nexport const Chip: FC<ChipProps> = ({\n theme,\n intent,\n size = \"md\",\n className,\n children,\n ...rest\n}) => {\n const intentClass = intent\n ? intentClasses[intent]\n : \"polli:bg-theme-bg-active polli:text-theme-text-strong\";\n return (\n <span\n {...rest}\n data-theme={theme}\n className={cn(\n \"polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal\",\n chipSizes[size],\n intentClass,\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","import { Popover } from \"@ark-ui/react/popover\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { useState } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst DEFAULT_PANEL =\n \"polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg\";\n\nexport type DropdownProps = {\n theme: ThemeName;\n /** Trigger element; receives the current open state (e.g. to rotate a chevron). */\n trigger: (open: boolean) => ReactNode;\n /** Panel content. As a function, receives `close` to dismiss after a selection. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /** Panel placement relative to the trigger. */\n align?: \"start\" | \"end\";\n /** Controlled open state. Omit to let the Dropdown manage its own. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Appended after the surface (widths, padding, max-height…). */\n className?: string;\n};\n\nexport const Dropdown: FC<DropdownProps> = ({\n theme,\n trigger,\n children,\n align = \"start\",\n open: openProp,\n onOpenChange,\n className,\n}) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = openProp !== undefined;\n const open = isControlled ? openProp : internalOpen;\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <Popover.Root\n open={open}\n onOpenChange={(details) => setOpen(details.open)}\n positioning={{\n placement: align === \"end\" ? \"bottom-end\" : \"bottom-start\",\n }}\n >\n <Popover.Trigger asChild>{trigger(open)}</Popover.Trigger>\n <Portal>\n <Popover.Positioner>\n <Popover.Content\n data-theme={theme}\n className={cn(\n \"polli:z-50 polli:overflow-hidden polli:focus:outline-none\",\n DEFAULT_PANEL,\n className,\n )}\n >\n {typeof children === \"function\"\n ? children(() => setOpen(false))\n : children}\n </Popover.Content>\n </Popover.Positioner>\n </Portal>\n </Popover.Root>\n );\n};\n","import {\n type ComponentPropsWithoutRef,\n forwardRef,\n type MutableRefObject,\n type PropsWithChildren,\n type Ref,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\ntype ScrollAxis = \"y\" | \"x\";\n\nconst axisClasses: Record<ScrollAxis, string> = {\n y: \"polli:overflow-y-auto polli:overflow-x-hidden\",\n x: \"polli:overflow-x-auto polli:overflow-y-hidden\",\n};\n\ntype ScrollAreaOwnProps = {\n /** Override the ambient cascade theme for this scroller's thumb. */\n theme?: ThemeName;\n /** Scroll direction. Default `y`. */\n axis?: ScrollAxis;\n className?: string;\n};\n\nexport type ScrollAreaProps = PropsWithChildren<\n ScrollAreaOwnProps &\n Omit<ComponentPropsWithoutRef<\"div\">, keyof ScrollAreaOwnProps>\n>;\n\nfunction assignRef<T>(ref: Ref<T> | undefined, value: T | null) {\n if (typeof ref === \"function\") ref(value);\n else if (ref) (ref as MutableRefObject<T | null>).current = value;\n}\n\n/**\n * Themed auto-hide scroll container. Thumb color follows the nearest\n * `[data-theme=\"...\"]` ancestor; pass `theme` to override locally.\n */\nexport const ScrollArea = forwardRef<HTMLDivElement, ScrollAreaProps>(\n ({ theme, axis = \"y\", className, children, ...rest }, externalRef) => {\n const innerRef = useRef<HTMLDivElement | null>(null);\n\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n innerRef.current = node;\n assignRef(externalRef, node);\n },\n [externalRef],\n );\n\n useEffect(() => {\n const element = innerRef.current;\n if (!element) return;\n\n let hideTimer: number | null = null;\n\n const clearHideTimer = () => {\n if (hideTimer !== null) {\n window.clearTimeout(hideTimer);\n hideTimer = null;\n }\n };\n\n const show = () => {\n element.dataset.scrollbarActive = \"true\";\n clearHideTimer();\n };\n\n const hide = () => {\n element.dataset.scrollbarActive = \"false\";\n clearHideTimer();\n };\n\n const scheduleHide = () => {\n clearHideTimer();\n hideTimer = window.setTimeout(hide, 2000);\n };\n\n const handleInteraction = () => {\n show();\n scheduleHide();\n };\n\n hide();\n\n element.addEventListener(\"scroll\", handleInteraction, {\n passive: true,\n });\n element.addEventListener(\"wheel\", handleInteraction, {\n passive: true,\n });\n element.addEventListener(\"touchstart\", handleInteraction, {\n passive: true,\n });\n element.addEventListener(\"pointerdown\", handleInteraction);\n element.addEventListener(\"keydown\", handleInteraction);\n element.addEventListener(\"focusin\", handleInteraction);\n element.addEventListener(\"focusout\", scheduleHide);\n\n return () => {\n clearHideTimer();\n element.removeEventListener(\"scroll\", handleInteraction);\n element.removeEventListener(\"wheel\", handleInteraction);\n element.removeEventListener(\"touchstart\", handleInteraction);\n element.removeEventListener(\"pointerdown\", handleInteraction);\n element.removeEventListener(\"keydown\", handleInteraction);\n element.removeEventListener(\"focusin\", handleInteraction);\n element.removeEventListener(\"focusout\", scheduleHide);\n };\n }, []);\n\n return (\n <div\n {...rest}\n ref={setRef}\n data-theme={theme}\n className={cn(\n \"polli-scrollbar-subtle polli:min-w-0 polli:max-w-full\",\n axisClasses[axis],\n className,\n )}\n >\n {children}\n </div>\n );\n },\n);\n\nScrollArea.displayName = \"ScrollArea\";\n","import type { FC, ReactNode } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nexport type TabButtonProps = {\n active: boolean;\n onClick: () => void;\n children: ReactNode;\n /** Optional cascade override; defaults to inherited [data-theme]. */\n theme?: ThemeName;\n size?: \"md\" | \"sm\";\n variant?: \"default\" | \"ghost\";\n ariaLabel?: string;\n disabled?: boolean;\n className?: string;\n};\n\nconst sizeClasses = {\n md: \"polli:px-4 polli:py-1.5 polli:text-base\",\n sm: \"polli:px-3 polli:py-1.5 polli:text-sm\",\n} as const;\n\nconst variantClasses = {\n default: {\n base: \"polli:border\",\n active: \"polli:bg-theme-bg-active polli:text-theme-text-strong polli:border-theme-border\",\n inactive:\n \"polli:bg-theme-bg-subtle polli:text-theme-text-base polli:border-theme-border polli:hover:bg-theme-bg-active\",\n },\n ghost: {\n base: \"polli:border polli:border-transparent\",\n active: \"polli:bg-theme-bg-active polli:text-theme-text-strong\",\n inactive:\n \"polli:bg-transparent polli:text-theme-text-base polli:hover:bg-theme-bg-subtle polli:hover:text-theme-text-strong\",\n },\n} as const;\n\nexport const TabButton: FC<TabButtonProps> = ({\n theme,\n active,\n onClick,\n children,\n size = \"md\",\n variant = \"default\",\n ariaLabel,\n disabled = false,\n className,\n}) => {\n const classes = variantClasses[variant];\n return (\n <button\n type=\"button\"\n data-theme={theme}\n onClick={onClick}\n aria-label={ariaLabel}\n aria-pressed={active}\n disabled={disabled}\n className={cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:font-medium polli:leading-normal polli:transition-all polli:duration-200\",\n classes.base,\n active ? classes.active : classes.inactive,\n disabled && \"polli:cursor-not-allowed polli:opacity-50\",\n sizeClasses[size],\n className,\n )}\n >\n {children}\n </button>\n );\n};\n","/** Pollinations model modality to package theme mapping. */\nimport type { ModelCategory } from \"@pollinations/sdk\";\nimport type { ThemeName } from \"../../theme.ts\";\n\n/** A model modality is just a model category. Single source of truth: the SDK. */\nexport type Modality = ModelCategory;\n\nexport const MODALITY_THEMES: Record<ModelCategory, ThemeName> = {\n text: \"blue\",\n image: \"pink\",\n video: \"teal\",\n audio: \"amber\",\n realtime: \"coral\",\n embedding: \"violet\",\n};\n\n/** Theme for a known model category. Total — every category has a theme. */\nexport function modalityTheme(category: ModelCategory): ThemeName {\n return MODALITY_THEMES[category];\n}\n\n/** Map a human-typed category string to the canonical `ModelCategory` key. */\nfunction normalize(category: string): ModelCategory | null {\n const lower = category.toLowerCase();\n if (lower === \"images\") return \"image\";\n if (lower === \"embeddings\") return \"embedding\";\n return lower in MODALITY_THEMES ? (lower as ModelCategory) : null;\n}\n\n/** Theme for an untrusted category string (e.g. user input); null if unknown. */\nexport function getModalityTheme(category: string): ThemeName | null {\n const key = normalize(category);\n return key ? MODALITY_THEMES[key] : null;\n}\n","import type { ModelCategory } from \"@pollinations/sdk\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { Button } from \"../../primitives/Button.tsx\";\nimport { ChevronIcon } from \"../../primitives/ChevronIcon.tsx\";\nimport { Chip } from \"../../primitives/Chip.tsx\";\nimport { Dropdown } from \"../../primitives/Dropdown.tsx\";\nimport { ScrollArea } from \"../../primitives/ScrollArea.tsx\";\nimport { TabButton } from \"../../primitives/TabButton.tsx\";\nimport { modalityTheme } from \"./themes.ts\";\n\nexport type ModelSelectorCategory = ModelCategory;\n\nexport type ModelSelectorItem = {\n id: string;\n name: string;\n title: string;\n description?: string;\n category: ModelSelectorCategory;\n paidOnly?: boolean;\n};\n\nexport type ModelSelectorProps = {\n models: readonly ModelSelectorItem[];\n category: ModelSelectorCategory;\n value: string;\n isLoading?: boolean;\n onChange: (modelId: string) => void;\n};\n\nexport const CATEGORY_LABELS: Record<ModelSelectorCategory, string> = {\n image: \"Image\",\n video: \"Video\",\n text: \"Text\",\n audio: \"Audio\",\n embedding: \"Embeddings\",\n realtime: \"Realtime\",\n};\n\n/** Human-readable label for a model category, e.g. \"embedding\" -> \"Embeddings\". */\nexport function categoryLabel(category: ModelSelectorCategory): string {\n return CATEGORY_LABELS[category];\n}\n\nfunction displayModelName(model: ModelSelectorItem): string {\n return model.title;\n}\n\nexport function ModelSelector({\n models,\n category,\n value,\n isLoading = false,\n onChange,\n}: ModelSelectorProps) {\n const filteredModels = models.filter(\n (model) => model.category === category,\n );\n const currentModel = models.find((model) => model.id === value);\n const theme = modalityTheme(category);\n const modelLabel = currentModel ? displayModelName(currentModel) : \"Select\";\n const accessibleLabel = currentModel\n ? `${CATEGORY_LABELS[category]} model: ${modelLabel}`\n : `Select ${CATEGORY_LABELS[category].toLowerCase()} model`;\n\n return (\n <Dropdown\n theme={theme}\n align=\"end\"\n className=\"polli:w-[min(24rem,calc(100vw-2rem))] polli:p-2\"\n trigger={(open) => (\n <Button\n type=\"button\"\n theme={theme}\n aria-label={accessibleLabel}\n className=\"polli:min-w-64 polli:max-w-full polli:self-start polli:justify-between polli:gap-2\"\n >\n <span className=\"polli:truncate\">{modelLabel}</span>\n <ChevronIcon expanded={open} />\n </Button>\n )}\n >\n {(close) =>\n isLoading ? (\n <p className=\"polli:m-0 polli:px-2 polli:py-2 polli:text-sm polli:text-theme-text-soft\">\n Loading models...\n </p>\n ) : (\n <ScrollArea\n theme={theme}\n className=\"polli:max-h-64 polli:pr-2\"\n >\n <div className=\"polli:flex polli:flex-col polli:gap-1\">\n {filteredModels.map((model) => {\n const isActive = value === model.id;\n return (\n <TabButton\n key={model.id}\n active={isActive}\n theme={modalityTheme(model.category)}\n size=\"sm\"\n variant=\"ghost\"\n className=\"polli:w-full polli:justify-between polli:text-left\"\n onClick={() => {\n onChange(model.id);\n close();\n }}\n >\n <span className=\"polli:truncate\">\n {displayModelName(model)}\n </span>\n {model.paidOnly && (\n <Chip\n size=\"sm\"\n className={cn(\n \"polli:shrink-0\",\n isActive &&\n \"polli:bg-surface-white\",\n )}\n >\n paid\n </Chip>\n )}\n </TabButton>\n );\n })}\n </div>\n </ScrollArea>\n )\n }\n </Dropdown>\n );\n}\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","intentClasses","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
@@ -0,0 +1,35 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ModelCategory } from '@pollinations/sdk';
3
+ import { T as ThemeName } from '../theme-jRPPBmld.cjs';
4
+
5
+ type ModelSelectorCategory = ModelCategory;
6
+ type ModelSelectorItem = {
7
+ id: string;
8
+ name: string;
9
+ title: string;
10
+ description?: string;
11
+ category: ModelSelectorCategory;
12
+ paidOnly?: boolean;
13
+ };
14
+ type ModelSelectorProps = {
15
+ models: readonly ModelSelectorItem[];
16
+ category: ModelSelectorCategory;
17
+ value: string;
18
+ isLoading?: boolean;
19
+ onChange: (modelId: string) => void;
20
+ };
21
+ declare const CATEGORY_LABELS: Record<ModelSelectorCategory, string>;
22
+ /** Human-readable label for a model category, e.g. "embedding" -> "Embeddings". */
23
+ declare function categoryLabel(category: ModelSelectorCategory): string;
24
+ declare function ModelSelector({ models, category, value, isLoading, onChange, }: ModelSelectorProps): react_jsx_runtime.JSX.Element;
25
+
26
+ /** Pollinations model modality to package theme mapping. */
27
+
28
+ /** A model modality is just a model category. Single source of truth: the SDK. */
29
+ type Modality = ModelCategory;
30
+ /** Theme for a known model category. Total — every category has a theme. */
31
+ declare function modalityTheme(category: ModelCategory): ThemeName;
32
+ /** Theme for an untrusted category string (e.g. user input); null if unknown. */
33
+ declare function getModalityTheme(category: string): ThemeName | null;
34
+
35
+ export { CATEGORY_LABELS, type Modality, ModelSelector, type ModelSelectorCategory, type ModelSelectorItem, type ModelSelectorProps, categoryLabel, getModalityTheme, modalityTheme };
@@ -0,0 +1,35 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ModelCategory } from '@pollinations/sdk';
3
+ import { T as ThemeName } from '../theme-jRPPBmld.js';
4
+
5
+ type ModelSelectorCategory = ModelCategory;
6
+ type ModelSelectorItem = {
7
+ id: string;
8
+ name: string;
9
+ title: string;
10
+ description?: string;
11
+ category: ModelSelectorCategory;
12
+ paidOnly?: boolean;
13
+ };
14
+ type ModelSelectorProps = {
15
+ models: readonly ModelSelectorItem[];
16
+ category: ModelSelectorCategory;
17
+ value: string;
18
+ isLoading?: boolean;
19
+ onChange: (modelId: string) => void;
20
+ };
21
+ declare const CATEGORY_LABELS: Record<ModelSelectorCategory, string>;
22
+ /** Human-readable label for a model category, e.g. "embedding" -> "Embeddings". */
23
+ declare function categoryLabel(category: ModelSelectorCategory): string;
24
+ declare function ModelSelector({ models, category, value, isLoading, onChange, }: ModelSelectorProps): react_jsx_runtime.JSX.Element;
25
+
26
+ /** Pollinations model modality to package theme mapping. */
27
+
28
+ /** A model modality is just a model category. Single source of truth: the SDK. */
29
+ type Modality = ModelCategory;
30
+ /** Theme for a known model category. Total — every category has a theme. */
31
+ declare function modalityTheme(category: ModelCategory): ThemeName;
32
+ /** Theme for an untrusted category string (e.g. user input); null if unknown. */
33
+ declare function getModalityTheme(category: string): ThemeName | null;
34
+
35
+ export { CATEGORY_LABELS, type Modality, ModelSelector, type ModelSelectorCategory, type ModelSelectorItem, type ModelSelectorProps, categoryLabel, getModalityTheme, modalityTheme };