@pollinations/ui 0.1.0-alpha.1 → 0.1.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +148 -36
  2. package/dist/Button-ByKwRtdw.d.cts +29 -0
  3. package/dist/Button-ByKwRtdw.d.ts +29 -0
  4. package/dist/Chip-v-ADv6cz.d.cts +18 -0
  5. package/dist/Chip-v-ADv6cz.d.ts +18 -0
  6. package/dist/Dialog-D3Nqt8cE.d.cts +66 -0
  7. package/dist/Dialog-D3Nqt8cE.d.ts +66 -0
  8. package/dist/app-user-menu/sdk.cjs +698 -242
  9. package/dist/app-user-menu/sdk.cjs.map +1 -1
  10. package/dist/app-user-menu/sdk.d.cts +22 -7
  11. package/dist/app-user-menu/sdk.d.ts +22 -7
  12. package/dist/app-user-menu/sdk.js +703 -240
  13. package/dist/app-user-menu/sdk.js.map +1 -1
  14. package/dist/app.css +12 -122
  15. package/dist/auth/index.cjs +1365 -85
  16. package/dist/auth/index.cjs.map +1 -1
  17. package/dist/auth/index.d.cts +91 -6
  18. package/dist/auth/index.d.ts +91 -6
  19. package/dist/auth/index.js +1362 -84
  20. package/dist/auth/index.js.map +1 -1
  21. package/dist/auth/sdk.cjs +244 -0
  22. package/dist/auth/sdk.cjs.map +1 -0
  23. package/dist/auth/sdk.d.cts +40 -0
  24. package/dist/auth/sdk.d.ts +40 -0
  25. package/dist/auth/sdk.js +213 -0
  26. package/dist/auth/sdk.js.map +1 -0
  27. package/dist/brand/lockup-horizontal-black.png +0 -0
  28. package/dist/brand/lockup-horizontal-black.svg +4 -0
  29. package/dist/brand/lockup-horizontal-white.png +0 -0
  30. package/dist/brand/lockup-horizontal-white.svg +4 -0
  31. package/dist/brand/lockup-horizontal.svg +4 -0
  32. package/dist/brand/lockup-stacked-black.png +0 -0
  33. package/dist/brand/lockup-stacked-black.svg +4 -0
  34. package/dist/brand/lockup-stacked-white.png +0 -0
  35. package/dist/brand/lockup-stacked-white.svg +4 -0
  36. package/dist/brand/lockup-stacked.svg +4 -0
  37. package/dist/brand/mark-black.png +0 -0
  38. package/dist/brand/mark-black.svg +1 -0
  39. package/dist/brand/mark-white.png +0 -0
  40. package/dist/brand/mark-white.svg +1 -0
  41. package/dist/brand/mark.svg +1 -0
  42. package/dist/brand/polli/polli-lockup-horizontal-black.png +0 -0
  43. package/dist/brand/polli/polli-lockup-horizontal-white.png +0 -0
  44. package/dist/brand/polli/polli-lockup-stacked-black.png +0 -0
  45. package/dist/brand/polli/polli-lockup-stacked-white.png +0 -0
  46. package/dist/brand/polli/polli.png +0 -0
  47. package/dist/brand/wordmark-black.png +0 -0
  48. package/dist/brand/wordmark-black.svg +1 -0
  49. package/dist/brand/wordmark-white.png +0 -0
  50. package/dist/brand/wordmark-white.svg +1 -0
  51. package/dist/brand/wordmark.svg +1 -0
  52. package/dist/fonts/geist-pixel-square.woff2 +0 -0
  53. package/dist/gen/index.cjs +427 -217
  54. package/dist/gen/index.cjs.map +1 -1
  55. package/dist/gen/index.d.cts +68 -19
  56. package/dist/gen/index.d.ts +68 -19
  57. package/dist/gen/index.js +421 -215
  58. package/dist/gen/index.js.map +1 -1
  59. package/dist/index.browser.min.js +2 -0
  60. package/dist/index.browser.min.js.map +1 -0
  61. package/dist/index.cjs +3711 -1590
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.cts +548 -178
  64. package/dist/index.d.ts +548 -178
  65. package/dist/index.js +3713 -1655
  66. package/dist/index.js.map +1 -1
  67. package/dist/licenses/Geist-OFL.txt +93 -0
  68. package/dist/markdown.cjs +826 -0
  69. package/dist/markdown.cjs.map +1 -0
  70. package/dist/markdown.d.cts +16 -0
  71. package/dist/markdown.d.ts +16 -0
  72. package/dist/markdown.js +797 -0
  73. package/dist/markdown.js.map +1 -0
  74. package/dist/styles.css +1 -1
  75. package/dist/theme.css +87 -0
  76. package/dist/wallet/index.cjs +291 -64
  77. package/dist/wallet/index.cjs.map +1 -1
  78. package/dist/wallet/index.d.cts +30 -7
  79. package/dist/wallet/index.d.ts +30 -7
  80. package/dist/wallet/index.js +290 -64
  81. package/dist/wallet/index.js.map +1 -1
  82. package/package.json +106 -89
  83. package/dist/Chip-CQCq34kS.d.cts +0 -20
  84. package/dist/Chip-Cj4xG7Te.d.ts +0 -20
  85. package/dist/assets/logo-wordmark.svg +0 -1
  86. package/dist/assets/logo.svg +0 -4
  87. package/dist/theme-jRPPBmld.d.cts +0 -20
  88. package/dist/theme-jRPPBmld.d.ts +0 -20
@@ -20,11 +20,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/modules/gen/index.ts
21
21
  var gen_exports = {};
22
22
  __export(gen_exports, {
23
- CATEGORY_LABELS: () => CATEGORY_LABELS,
23
+ ModalityChip: () => ModalityChip,
24
+ ModalityDot: () => ModalityDot,
25
+ ModalityTab: () => ModalityTab,
26
+ ModelAccessIcon: () => ModelAccessIcon,
24
27
  ModelSelector: () => ModelSelector,
25
28
  categoryLabel: () => categoryLabel,
26
- getModalityTheme: () => getModalityTheme,
27
- modalityTheme: () => modalityTheme
29
+ getModalityKey: () => getModalityKey,
30
+ modalityBgVar: () => modalityBgVar,
31
+ modalityTextColor: () => modalityTextColor
28
32
  });
29
33
  module.exports = __toCommonJS(gen_exports);
30
34
 
@@ -36,66 +40,379 @@ function cn(...inputs) {
36
40
  return twMerge((0, import_clsx.clsx)(...inputs));
37
41
  }
38
42
 
39
- // src/primitives/Button.tsx
43
+ // src/primitives/Chip.tsx
40
44
  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
+ var chipSizes = {
46
+ icon: "polli:h-5 polli:w-5 polli:p-0 polli:text-xs",
47
+ sm: "polli:h-5 polli:px-2 polli:text-xs",
48
+ md: "polli:h-6 polli:px-2.5 polli:text-sm",
49
+ lg: "polli:h-7 polli:px-3 polli:text-sm"
45
50
  };
46
- var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:transition-colors";
47
51
  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"
52
+ news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
53
+ new: "polli:bg-intent-new-bg-light polli:text-intent-new-text",
54
+ free: "polli:bg-intent-free-bg-light polli:text-intent-free-text",
55
+ alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
56
+ neutral: "polli:bg-ink-100/80 polli:text-ink-900",
57
+ success: "polli:bg-intent-success-bg-bright/15 polli:text-intent-success-text",
58
+ warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
59
+ info: "polli:bg-intent-info-bg-light polli:text-intent-info-text",
60
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
61
+ };
62
+ var Chip = ({
63
+ intent,
64
+ size = "md",
65
+ className,
66
+ children,
67
+ ...rest
68
+ }) => {
69
+ const intentClass = intent ? intentClasses[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
70
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
71
+ "span",
72
+ {
73
+ ...rest,
74
+ className: cn(
75
+ "polli:inline-flex polli:shrink-0 polli:items-center polli:justify-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-none",
76
+ chipSizes[size],
77
+ intentClass,
78
+ className
79
+ ),
80
+ children
81
+ }
82
+ );
83
+ };
84
+
85
+ // src/modules/gen/themes.ts
86
+ var MODALITIES = [
87
+ "text",
88
+ "image",
89
+ "video",
90
+ "audio",
91
+ "realtime",
92
+ "embedding"
93
+ ];
94
+ function getModalityKey(category) {
95
+ const lower = category.toLowerCase();
96
+ if (lower === "images") return "image";
97
+ if (lower === "embeddings") return "embedding";
98
+ return MODALITIES.includes(lower) ? lower : null;
99
+ }
100
+ var modalityColorVar = (key) => `var(--polli-color-modality-${key})`;
101
+ var modalityBgVar = (key) => `var(--polli-color-modality-${key}-bg)`;
102
+ var modalityTextColor = (key) => `color-mix(in oklab, ${modalityColorVar(key)} 72%, var(--polli-color-text-strong))`;
103
+
104
+ // src/modules/gen/ModalityChip.tsx
105
+ var import_jsx_runtime2 = require("react/jsx-runtime");
106
+ function ModalityChip({
107
+ modality,
108
+ size = "sm",
109
+ className,
110
+ children
111
+ }) {
112
+ const key = getModalityKey(modality);
113
+ if (!key) {
114
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Chip, { intent: "neutral", size, className, children });
115
+ }
116
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
117
+ Chip,
118
+ {
119
+ size,
120
+ className,
121
+ style: {
122
+ backgroundColor: modalityBgVar(key),
123
+ color: modalityTextColor(key)
124
+ },
125
+ children
126
+ }
127
+ );
128
+ }
129
+
130
+ // src/modules/gen/ModalityDot.tsx
131
+ var import_jsx_runtime3 = require("react/jsx-runtime");
132
+ function ModalityDot({
133
+ modality,
134
+ className
135
+ }) {
136
+ const key = getModalityKey(modality);
137
+ if (!key) return null;
138
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
139
+ "span",
140
+ {
141
+ "aria-hidden": "true",
142
+ className: cn(
143
+ "polli:inline-block polli:size-2 polli:shrink-0 polli:rounded-full",
144
+ className
145
+ ),
146
+ style: { backgroundColor: modalityColorVar(key) }
147
+ }
148
+ );
149
+ }
150
+
151
+ // src/primitives/TabButton.tsx
152
+ var import_jsx_runtime4 = require("react/jsx-runtime");
153
+ var tabButtonBaseClass = "polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:font-medium polli:leading-normal polli:transition-colors polli:duration-200";
154
+ var tabButtonSizeClass = {
155
+ xs: "polli:px-2.5 polli:py-1 polli:text-xs",
156
+ lg: "polli:px-5 polli:py-2 polli:text-lg",
157
+ md: "polli:px-4 polli:py-1.5 polli:text-base",
158
+ sm: "polli:px-3 polli:py-1.5 polli:text-sm"
159
+ };
160
+ var variantClasses = {
161
+ // The default tab look: borderless and monochrome. Selected uses `bg-active`
162
+ // — the same light resting fill as the site's normal buttons. Both states
163
+ // deepen to `bg-hover` and use the theme's hover label color. Non-selected
164
+ // uses the quiet `bg-subtle` token until then.
165
+ soft: {
166
+ base: "",
167
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover",
168
+ mixed: "polli:bg-theme-bg-active/45 polli:text-theme-text-strong polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover",
169
+ inactive: "polli:bg-theme-bg-subtle polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover"
170
+ },
171
+ // Transparent until hovered or selected — for multi-select toggles and
172
+ // inline rows where a filled idle pill would read as a hard selection.
173
+ ghost: {
174
+ base: "polli:border polli:border-transparent",
175
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover",
176
+ mixed: "polli:bg-theme-bg-active/45 polli:text-theme-text-strong polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover",
177
+ inactive: "polli:bg-transparent polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover"
178
+ }
179
+ };
180
+ var intentClasses2 = {
181
+ amber: {
182
+ active: "polli:bg-paid-pale polli:text-paid-deep",
183
+ inactive: "polli:bg-transparent polli:text-theme-text-base polli:hover:bg-paid-pale/60"
184
+ },
185
+ green: {
186
+ active: "polli:bg-tier-pale polli:text-tier-deep",
187
+ inactive: "polli:bg-transparent polli:text-tier-deep polli:hover:bg-tier-pale/60"
188
+ }
189
+ };
190
+ function TabButton({
191
+ as,
192
+ active,
193
+ onClick,
194
+ children,
195
+ size = "md",
196
+ variant = "soft",
197
+ intent,
198
+ detail,
199
+ ariaLabel,
200
+ disabled = false,
201
+ className,
202
+ ...rest
203
+ }) {
204
+ const Component = as || "button";
205
+ const isButton = Component === "button";
206
+ const colors = intent === "neutral" ? variantClasses.soft : intent ? {
207
+ ...intentClasses2[intent],
208
+ mixed: intentClasses2[intent].active
209
+ } : variantClasses[variant];
210
+ const handleClick = disabled ? (event) => {
211
+ event.preventDefault();
212
+ event.stopPropagation();
213
+ } : onClick;
214
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
215
+ Component,
216
+ {
217
+ ...rest,
218
+ ...isButton ? { type: "button", disabled } : {},
219
+ ...!isButton && disabled ? { "aria-disabled": true, tabIndex: -1 } : {},
220
+ ...Component === "a" && disabled ? { href: void 0 } : {},
221
+ onClick: handleClick,
222
+ ...ariaLabel !== void 0 ? { "aria-label": ariaLabel } : {},
223
+ ...isButton ? { "aria-pressed": active } : { "aria-current": active === true ? "page" : void 0 },
224
+ className: cn(
225
+ tabButtonBaseClass,
226
+ variantClasses[variant].base,
227
+ active === "mixed" ? colors.mixed : active ? colors.active : colors.inactive,
228
+ disabled && "polli:pointer-events-none polli:cursor-not-allowed polli:opacity-50",
229
+ tabButtonSizeClass[size],
230
+ className
231
+ ),
232
+ children: [
233
+ children,
234
+ detail != null && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "polli:ml-1 polli:font-normal polli:opacity-70", children: detail })
235
+ ]
236
+ }
237
+ );
238
+ }
239
+
240
+ // src/modules/gen/ModalityTab.tsx
241
+ var import_jsx_runtime5 = require("react/jsx-runtime");
242
+ function ModalityTab({
243
+ active,
244
+ onClick,
245
+ children,
246
+ size = "md",
247
+ disabled = false,
248
+ className,
249
+ ...rest
250
+ }) {
251
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
252
+ TabButton,
253
+ {
254
+ ...rest,
255
+ active,
256
+ onClick,
257
+ size,
258
+ disabled,
259
+ className,
260
+ children
261
+ }
262
+ );
263
+ }
264
+
265
+ // src/primitives/icons/index.tsx
266
+ var import_jsx_runtime6 = require("react/jsx-runtime");
267
+ var strokeProps = {
268
+ fill: "none",
269
+ stroke: "currentColor",
270
+ strokeWidth: 2,
271
+ strokeLinecap: "round",
272
+ strokeLinejoin: "round"
273
+ };
274
+ function CardIcon(props) {
275
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
276
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { x: "2", y: "5", width: "20", height: "14", rx: "2" }),
277
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M2 10h20" })
278
+ ] });
279
+ }
280
+ function SproutIcon(props) {
281
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
282
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M7 20h10" }),
283
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M10 20c5.5-2.5.8-6.4 3-10" }),
284
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M9.5 9.4c1.1.8 1.8 2.2 2.3 3.7-2 .4-3.5.4-4.8-.3-1.2-.6-2.3-1.9-3-4.2 2.8-.5 4.4 0 5.5.8z" }),
285
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M14.1 6a7 7 0 0 0-1.1 4c1.9-.1 3.3-.6 4.3-1.4 1-1 1.6-2.3 1.7-4.6-2.7.1-4 1-4.9 2z" })
286
+ ] });
287
+ }
288
+
289
+ // src/modules/gen/ModelAccessIcon.tsx
290
+ var import_jsx_runtime7 = require("react/jsx-runtime");
291
+ function ModelAccessIcon({
292
+ paidOnly = false,
293
+ className = "polli:h-3.5 polli:w-3.5"
294
+ }) {
295
+ const label = paidOnly ? "Paid Pollen required" : "Works with any Pollen";
296
+ const Icon = paidOnly ? CardIcon : SproutIcon;
297
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
298
+ "span",
299
+ {
300
+ role: "img",
301
+ "aria-label": label,
302
+ title: label,
303
+ className: "polli:inline-flex polli:shrink-0",
304
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { className })
305
+ }
306
+ );
307
+ }
308
+
309
+ // src/primitives/Button.tsx
310
+ var import_jsx_runtime8 = require("react/jsx-runtime");
311
+ var pillSizes = {
312
+ icon: "polli:h-12 polli:w-12 polli:p-0",
313
+ xs: "polli:h-5 polli:px-1.5 polli:py-0 polli:text-[11px] polli:leading-none",
314
+ sm: "polli:min-h-7 polli:px-2 polli:pt-0.5 polli:pb-1",
315
+ md: "polli:min-h-9 polli:px-4 polli:pt-1.5 polli:pb-2",
316
+ lg: "polli:min-h-12 polli:px-6 polli:py-3 polli:text-base"
317
+ };
318
+ var raisedSizes = {
319
+ icon: "polli:h-12 polli:w-12 polli:p-0",
320
+ xs: "polli:px-2 polli:py-1 polli:text-xs",
321
+ sm: "polli:px-4 polli:py-2 polli:text-sm",
322
+ md: "polli:px-7 polli:py-3.5 polli:text-base",
323
+ lg: "polli:px-8 polli:py-4 polli:text-lg"
324
+ };
325
+ var appearanceClasses = {
326
+ pill: "polli:rounded-full",
327
+ raised: "polli:rounded-xl polli:border-r-[3px] polli:border-b-[3px] polli:border-solid polli:border-theme-text-strong/20 polli:hover:border-theme-text-strong/45"
328
+ };
329
+ var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-strong polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover polli:transition-colors";
330
+ var outlined = "polli:border polli:border-theme-text-soft polli:bg-theme-bg-active/30 polli:text-theme-text-strong polli:transition-colors polli:[.dark_&]:bg-transparent";
331
+ var intentClasses3 = {
332
+ brand: `${outlined} polli:hover:bg-theme-bg-active/50 polli:[.dark_&]:hover:bg-theme-text-soft/10`,
333
+ commit: `${outlined} polli:hover:border-theme-bg-active polli:hover:bg-theme-bg-active polli:focus-visible:border-theme-bg-active polli:focus-visible:bg-theme-bg-active polli:[.dark_&]:hover:bg-theme-bg-active polli:[.dark_&]:focus-visible:bg-theme-bg-active`,
334
+ danger: "polli:border polli:border-intent-danger-text polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-intent-danger-bg-hover polli:focus-visible:bg-intent-danger-bg-hover polli:transition-colors polli:[.dark_&]:bg-transparent polli:[.dark_&]:hover:bg-intent-danger-bg-hover polli:[.dark_&]:focus-visible:bg-intent-danger-bg-hover",
335
+ info: "polli:bg-intent-info-bg-light polli:text-intent-info-text polli:hover:bg-intent-info-bg-hover polli:transition-colors",
336
+ // Secondary actions never take the accent: one step stronger grey on hover.
337
+ neutral: "polli:bg-theme-bg-subtle polli:text-theme-text-base polli:hover:bg-theme-text-muted/25 polli:hover:text-theme-text-strong polli:transition-colors"
49
338
  };
50
339
  var buttonClasses = ({
51
- theme: _theme,
52
340
  intent,
341
+ appearance = "pill",
53
342
  size,
54
343
  className,
55
- disabled
344
+ disabled,
345
+ busy
56
346
  }) => {
57
- const colorClasses = intent ? intentClasses[intent] : themeClasses;
347
+ const colorClasses = intent ? intentClasses3[intent] : themeClasses;
348
+ const sizeClasses = appearance === "raised" ? raisedSizes : pillSizes;
58
349
  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",
350
+ "polli-control polli:inline-flex polli:items-center polli:justify-center polli:self-center polli:font-body polli:text-sm polli:font-medium polli:leading-normal polli:box-border polli:border polli:border-transparent",
351
+ // A busy button is working, not unavailable: it keeps its strength.
352
+ busy ? "polli:cursor-progress" : disabled ? "polli:opacity-50 polli:cursor-not-allowed" : "polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer",
61
353
  colorClasses,
62
- sizes[size || "md"],
354
+ appearanceClasses[appearance],
355
+ sizeClasses[size || "md"],
63
356
  className
64
357
  );
65
358
  };
66
359
  function Button({
67
360
  as,
68
361
  children,
69
- theme,
362
+ icon,
70
363
  intent,
364
+ appearance,
71
365
  size,
72
366
  className,
73
367
  disabled,
74
368
  ...buttonProps
75
369
  }) {
76
370
  const Component = as || "button";
77
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
371
+ const isButton = Component === "button";
372
+ const isAnchor = Component === "a";
373
+ const buttonType = buttonProps.type;
374
+ const onClick = buttonProps.onClick;
375
+ const ariaBusy = buttonProps["aria-busy"];
376
+ const busy = ariaBusy === true || ariaBusy === "true";
377
+ const handleClick = disabled ? (event) => {
378
+ event.preventDefault();
379
+ event.stopPropagation();
380
+ } : onClick;
381
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
78
382
  Component,
79
383
  {
80
- "data-theme": intent ? void 0 : theme,
384
+ ...buttonProps,
81
385
  "data-intent": intent,
386
+ ...isButton ? { type: buttonType ?? "button", disabled } : {},
387
+ ...!isButton && disabled ? { "aria-disabled": true, tabIndex: -1 } : {},
388
+ ...isAnchor && disabled ? { href: void 0 } : {},
389
+ onClick: handleClick,
82
390
  className: buttonClasses({
83
- theme,
84
391
  intent,
392
+ appearance,
85
393
  size,
86
394
  className,
87
- disabled
395
+ disabled,
396
+ busy
88
397
  }),
89
- disabled,
90
- ...buttonProps,
91
- children
398
+ children: [
399
+ icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
400
+ "span",
401
+ {
402
+ "aria-hidden": "true",
403
+ className: "polli:mr-2 polli:flex polli:size-4 polli:shrink-0 polli:[&>svg]:size-full",
404
+ children: busy ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "polli:block polli:size-full polli:animate-spin polli:rounded-full polli:border-2 polli:border-current polli:border-r-transparent polli:motion-reduce:animate-none" }) : icon
405
+ }
406
+ ),
407
+ children
408
+ ]
92
409
  }
93
410
  );
94
411
  }
95
412
 
96
413
  // src/primitives/ChevronIcon.tsx
97
- var import_jsx_runtime2 = require("react/jsx-runtime");
98
- var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
414
+ var import_jsx_runtime9 = require("react/jsx-runtime");
415
+ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
99
416
  "svg",
100
417
  {
101
418
  "aria-hidden": "true",
@@ -107,7 +424,7 @@ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_ru
107
424
  expanded && "polli:rotate-180",
108
425
  className
109
426
  ),
110
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
427
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
111
428
  "path",
112
429
  {
113
430
  d: "M3 4.5 6 7.5l3-3",
@@ -121,61 +438,24 @@ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_ru
121
438
  }
122
439
  );
123
440
 
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
441
  // src/primitives/Dropdown.tsx
165
442
  var import_popover = require("@ark-ui/react/popover");
166
443
  var import_portal = require("@ark-ui/react/portal");
167
444
  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";
445
+ var import_jsx_runtime10 = require("react/jsx-runtime");
446
+ var DEFAULT_PANEL = "polli:rounded-lg polli:bg-surface-menu polli:shadow-lg";
170
447
  var Dropdown = ({
171
- theme,
172
448
  trigger,
173
449
  children,
174
450
  align = "start",
451
+ side = "bottom",
175
452
  open: openProp,
453
+ portalled = true,
176
454
  onOpenChange,
177
- className
455
+ className,
456
+ panelStyle
178
457
  }) => {
458
+ const triggerId = (0, import_react.useId)();
179
459
  const [internalOpen, setInternalOpen] = (0, import_react.useState)(false);
180
460
  const isControlled = openProp !== void 0;
181
461
  const open = isControlled ? openProp : internalOpen;
@@ -183,22 +463,26 @@ var Dropdown = ({
183
463
  if (!isControlled) setInternalOpen(next);
184
464
  onOpenChange?.(next);
185
465
  };
186
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
466
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
187
467
  import_popover.Popover.Root,
188
468
  {
469
+ ids: { trigger: triggerId },
189
470
  open,
471
+ portalled,
190
472
  onOpenChange: (details) => setOpen(details.open),
191
473
  positioning: {
192
- placement: align === "end" ? "bottom-end" : "bottom-start"
474
+ placement: `${side}-${align}`,
475
+ strategy: portalled ? "absolute" : "fixed"
193
476
  },
194
477
  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)(
478
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_popover.Popover.Trigger, { asChild: true, children: trigger(open) }),
479
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_portal.Portal, { disabled: !portalled, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_popover.Popover.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
197
480
  import_popover.Popover.Content,
198
481
  {
199
- "data-theme": theme,
482
+ "aria-labelledby": triggerId,
483
+ style: panelStyle,
200
484
  className: cn(
201
- "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
485
+ "polli:z-[120] polli:overflow-hidden polli:focus:outline-none",
202
486
  DEFAULT_PANEL,
203
487
  className
204
488
  ),
@@ -212,17 +496,18 @@ var Dropdown = ({
212
496
 
213
497
  // src/primitives/ScrollArea.tsx
214
498
  var import_react2 = require("react");
215
- var import_jsx_runtime5 = require("react/jsx-runtime");
499
+ var import_jsx_runtime11 = require("react/jsx-runtime");
216
500
  var axisClasses = {
217
501
  y: "polli:overflow-y-auto polli:overflow-x-hidden",
218
- x: "polli:overflow-x-auto polli:overflow-y-hidden"
502
+ x: "polli:overflow-x-auto polli:overflow-y-hidden",
503
+ both: "polli:overflow-auto"
219
504
  };
220
505
  function assignRef(ref, value) {
221
506
  if (typeof ref === "function") ref(value);
222
507
  else if (ref) ref.current = value;
223
508
  }
224
509
  var ScrollArea = (0, import_react2.forwardRef)(
225
- ({ theme, axis = "y", className, children, ...rest }, externalRef) => {
510
+ ({ axis = "y", scrollbar = "subtle", className, children, ...rest }, externalRef) => {
226
511
  const innerRef = (0, import_react2.useRef)(null);
227
512
  const setRef = (0, import_react2.useCallback)(
228
513
  (node) => {
@@ -232,6 +517,7 @@ var ScrollArea = (0, import_react2.forwardRef)(
232
517
  [externalRef]
233
518
  );
234
519
  (0, import_react2.useEffect)(() => {
520
+ if (scrollbar === "native") return;
235
521
  const element = innerRef.current;
236
522
  if (!element) return;
237
523
  let hideTimer = null;
@@ -281,15 +567,15 @@ var ScrollArea = (0, import_react2.forwardRef)(
281
567
  element.removeEventListener("focusin", handleInteraction);
282
568
  element.removeEventListener("focusout", scheduleHide);
283
569
  };
284
- }, []);
285
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
570
+ }, [scrollbar]);
571
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
286
572
  "div",
287
573
  {
288
574
  ...rest,
289
575
  ref: setRef,
290
- "data-theme": theme,
291
576
  className: cn(
292
- "polli-scrollbar-subtle polli:min-w-0 polli:max-w-full",
577
+ scrollbar === "subtle" && "polli-scrollbar-subtle",
578
+ "polli:min-w-0 polli:max-w-full",
293
579
  axisClasses[axis],
294
580
  className
295
581
  ),
@@ -300,96 +586,22 @@ var ScrollArea = (0, import_react2.forwardRef)(
300
586
  );
301
587
  ScrollArea.displayName = "ScrollArea";
302
588
 
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
589
  // src/modules/gen/ModelSelector.tsx
379
- var import_jsx_runtime7 = require("react/jsx-runtime");
590
+ var import_jsx_runtime12 = require("react/jsx-runtime");
380
591
  var CATEGORY_LABELS = {
381
592
  image: "Image",
382
593
  video: "Video",
383
594
  text: "Text",
384
595
  audio: "Audio",
596
+ "3d": "3D",
385
597
  embedding: "Embeddings",
386
598
  realtime: "Realtime"
387
599
  };
388
600
  function categoryLabel(category) {
389
601
  return CATEGORY_LABELS[category];
390
602
  }
391
- function displayModelName(model) {
392
- return model.title;
603
+ function modelId(model) {
604
+ return model.id ?? model.name;
393
605
  }
394
606
  function ModelSelector({
395
607
  models,
@@ -398,80 +610,78 @@ function ModelSelector({
398
610
  isLoading = false,
399
611
  onChange
400
612
  }) {
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";
613
+ const filteredModels = models.filter((model) => model.category === category).sort((a, b) => modelId(a).localeCompare(modelId(b)));
614
+ const currentModel = models.find((model) => modelId(model) === value);
615
+ const modelLabel = currentModel ? currentModel.title ?? currentModel.name : "Select";
407
616
  const accessibleLabel = currentModel ? `${CATEGORY_LABELS[category]} model: ${modelLabel}` : `Select ${CATEGORY_LABELS[category].toLowerCase()} model`;
408
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
617
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
409
618
  Dropdown,
410
619
  {
411
- theme,
412
- align: "end",
620
+ align: "start",
413
621
  className: "polli:w-[min(24rem,calc(100vw-2rem))] polli:p-2",
414
- trigger: (open) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
622
+ trigger: (open) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
415
623
  Button,
416
624
  {
417
625
  type: "button",
418
- theme,
419
626
  "aria-label": accessibleLabel,
420
627
  className: "polli:min-w-64 polli:max-w-full polli:self-start polli:justify-between polli:gap-2",
421
628
  children: [
422
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "polli:truncate", children: modelLabel }),
423
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronIcon, { expanded: open })
629
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "polli:flex polli:min-w-0 polli:items-center polli:gap-2", children: [
630
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "polli:truncate", children: modelLabel }),
631
+ currentModel && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
632
+ ModelAccessIcon,
633
+ {
634
+ paidOnly: currentModel.paid_only
635
+ }
636
+ )
637
+ ] }),
638
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChevronIcon, { expanded: open })
424
639
  ]
425
640
  }
426
641
  ),
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
- )
642
+ children: (close) => isLoading ? /* @__PURE__ */ (0, import_jsx_runtime12.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_runtime12.jsx)(ScrollArea, { className: "polli:max-h-80 polli:pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "polli:flex polli:flex-col polli:gap-1", children: filteredModels.map((model) => {
643
+ const id = modelId(model);
644
+ const isActive = value === id;
645
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
646
+ TabButton,
647
+ {
648
+ active: isActive,
649
+ size: "sm",
650
+ variant: "ghost",
651
+ className: "polli:w-full polli:justify-start polli:text-left",
652
+ onClick: () => {
653
+ onChange(id);
654
+ close();
655
+ },
656
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "polli:flex polli:min-w-0 polli:flex-col polli:gap-0.5", children: [
657
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "polli:flex polli:min-w-0 polli:items-center polli:gap-2", children: [
658
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "polli:truncate", children: model.title ?? model.name }),
659
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
660
+ ModelAccessIcon,
661
+ {
662
+ paidOnly: model.paid_only
663
+ }
664
+ )
665
+ ] }),
666
+ model.description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "polli:truncate polli:text-xs polli:font-normal polli:text-theme-text-muted", children: model.description })
667
+ ] })
668
+ },
669
+ id
670
+ );
671
+ }) }) })
466
672
  }
467
673
  );
468
674
  }
469
675
  // Annotate the CommonJS export names for ESM import in node:
470
676
  0 && (module.exports = {
471
- CATEGORY_LABELS,
677
+ ModalityChip,
678
+ ModalityDot,
679
+ ModalityTab,
680
+ ModelAccessIcon,
472
681
  ModelSelector,
473
682
  categoryLabel,
474
- getModalityTheme,
475
- modalityTheme
683
+ getModalityKey,
684
+ modalityBgVar,
685
+ modalityTextColor
476
686
  });
477
687
  //# sourceMappingURL=index.cjs.map