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

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 +137 -36
  2. package/dist/Button-CO3Dpbkj.d.cts +29 -0
  3. package/dist/Button-CO3Dpbkj.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-yXzIFrDg.d.cts +63 -0
  7. package/dist/Dialog-yXzIFrDg.d.ts +63 -0
  8. package/dist/app-user-menu/sdk.cjs +631 -235
  9. package/dist/app-user-menu/sdk.cjs.map +1 -1
  10. package/dist/app-user-menu/sdk.d.cts +6 -7
  11. package/dist/app-user-menu/sdk.d.ts +6 -7
  12. package/dist/app-user-menu/sdk.js +639 -236
  13. package/dist/app-user-menu/sdk.js.map +1 -1
  14. package/dist/app.css +6 -122
  15. package/dist/auth/index.cjs +1346 -76
  16. package/dist/auth/index.cjs.map +1 -1
  17. package/dist/auth/index.d.cts +88 -6
  18. package/dist/auth/index.d.ts +88 -6
  19. package/dist/auth/index.js +1343 -75
  20. package/dist/auth/index.js.map +1 -1
  21. package/dist/auth/sdk.cjs +239 -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 +208 -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 +1 -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 +3 -0
  39. package/dist/brand/mark-white.png +0 -0
  40. package/dist/brand/mark-white.svg +3 -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 +395 -214
  54. package/dist/gen/index.cjs.map +1 -1
  55. package/dist/gen/index.d.cts +64 -19
  56. package/dist/gen/index.d.ts +64 -19
  57. package/dist/gen/index.js +391 -212
  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 +3464 -1559
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.cts +498 -174
  64. package/dist/index.d.ts +498 -174
  65. package/dist/index.js +3518 -1671
  66. package/dist/index.js.map +1 -1
  67. package/dist/licenses/Geist-OFL.txt +93 -0
  68. package/dist/markdown.cjs +821 -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 +792 -0
  73. package/dist/markdown.js.map +1 -0
  74. package/dist/styles.css +1 -1
  75. package/dist/theme.css +92 -0
  76. package/dist/wallet/index.cjs +255 -42
  77. package/dist/wallet/index.cjs.map +1 -1
  78. package/dist/wallet/index.d.cts +29 -7
  79. package/dist/wallet/index.d.ts +29 -7
  80. package/dist/wallet/index.js +254 -42
  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
package/dist/gen/index.js CHANGED
@@ -6,66 +6,354 @@ function cn(...inputs) {
6
6
  return twMerge(clsx(...inputs));
7
7
  }
8
8
 
9
- // src/primitives/Button.tsx
9
+ // src/primitives/Chip.tsx
10
10
  import { jsx } from "react/jsx-runtime";
11
- var sizes = {
12
- sm: "polli:px-2 polli:pt-0.5 polli:pb-1",
13
- md: "polli:px-4 polli:pt-1.5 polli:pb-2",
14
- lg: "polli:px-6 polli:py-3"
11
+ var chipSizes = {
12
+ icon: "polli:h-5 polli:w-5 polli:p-0 polli:text-xs",
13
+ sm: "polli:h-5 polli:px-2 polli:text-xs",
14
+ md: "polli:h-6 polli:px-2.5 polli:text-sm",
15
+ lg: "polli:h-7 polli:px-3 polli:text-sm"
15
16
  };
16
- var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:transition-colors";
17
17
  var intentClasses = {
18
- danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-intent-danger-bg-hover polli:transition-colors"
18
+ news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
19
+ new: "polli:bg-intent-new-bg-light polli:text-intent-new-text",
20
+ free: "polli:bg-intent-free-bg-light polli:text-intent-free-text",
21
+ alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
22
+ neutral: "polli:bg-ink-100/80 polli:text-ink-900",
23
+ success: "polli:bg-intent-success-bg-bright/15 polli:text-intent-success-text",
24
+ warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
25
+ info: "polli:bg-intent-info-bg-light polli:text-intent-info-text",
26
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
27
+ };
28
+ var Chip = ({
29
+ intent,
30
+ size = "md",
31
+ className,
32
+ children,
33
+ ...rest
34
+ }) => {
35
+ const intentClass = intent ? intentClasses[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
36
+ return /* @__PURE__ */ jsx(
37
+ "span",
38
+ {
39
+ ...rest,
40
+ className: cn(
41
+ "polli:inline-flex polli:shrink-0 polli:items-center polli:justify-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-none",
42
+ chipSizes[size],
43
+ intentClass,
44
+ className
45
+ ),
46
+ children
47
+ }
48
+ );
49
+ };
50
+
51
+ // src/modules/gen/themes.ts
52
+ var MODALITIES = [
53
+ "text",
54
+ "image",
55
+ "video",
56
+ "audio",
57
+ "realtime",
58
+ "embedding"
59
+ ];
60
+ function getModalityKey(category) {
61
+ const lower = category.toLowerCase();
62
+ if (lower === "images") return "image";
63
+ if (lower === "embeddings") return "embedding";
64
+ return MODALITIES.includes(lower) ? lower : null;
65
+ }
66
+ var modalityColorVar = (key) => `var(--polli-color-modality-${key})`;
67
+ var modalityBgVar = (key) => `var(--polli-color-modality-${key}-bg)`;
68
+
69
+ // src/modules/gen/ModalityChip.tsx
70
+ import { jsx as jsx2 } from "react/jsx-runtime";
71
+ function ModalityChip({
72
+ modality,
73
+ size = "sm",
74
+ className,
75
+ children
76
+ }) {
77
+ const key = getModalityKey(modality);
78
+ if (!key) {
79
+ return /* @__PURE__ */ jsx2(Chip, { intent: "neutral", size, className, children });
80
+ }
81
+ return /* @__PURE__ */ jsx2(
82
+ Chip,
83
+ {
84
+ size,
85
+ className,
86
+ style: {
87
+ backgroundColor: modalityBgVar(key),
88
+ color: `color-mix(in oklab, ${modalityColorVar(key)} 72%, var(--polli-color-text-strong))`
89
+ },
90
+ children
91
+ }
92
+ );
93
+ }
94
+
95
+ // src/modules/gen/ModalityDot.tsx
96
+ import { jsx as jsx3 } from "react/jsx-runtime";
97
+ function ModalityDot({
98
+ modality,
99
+ className
100
+ }) {
101
+ const key = getModalityKey(modality);
102
+ if (!key) return null;
103
+ return /* @__PURE__ */ jsx3(
104
+ "span",
105
+ {
106
+ "aria-hidden": "true",
107
+ className: cn(
108
+ "polli:inline-block polli:size-2 polli:shrink-0 polli:rounded-full",
109
+ className
110
+ ),
111
+ style: { backgroundColor: modalityColorVar(key) }
112
+ }
113
+ );
114
+ }
115
+
116
+ // src/primitives/TabButton.tsx
117
+ import { jsx as jsx4 } from "react/jsx-runtime";
118
+ 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";
119
+ var tabButtonSizeClass = {
120
+ xs: "polli:px-2.5 polli:py-1 polli:text-xs",
121
+ lg: "polli:px-5 polli:py-2 polli:text-lg",
122
+ md: "polli:px-4 polli:py-1.5 polli:text-base",
123
+ sm: "polli:px-3 polli:py-1.5 polli:text-sm"
124
+ };
125
+ var variantClasses = {
126
+ // The default tab look: borderless and monochrome. Selected uses `bg-active`
127
+ // — the same light resting fill as the site's normal buttons. Both states
128
+ // deepen to `bg-hover` and use the theme's hover label color. Non-selected
129
+ // uses the quiet `bg-subtle` token until then.
130
+ soft: {
131
+ base: "",
132
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover",
133
+ inactive: "polli:bg-theme-bg-subtle polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover"
134
+ },
135
+ // Transparent until hovered or selected — for multi-select toggles and
136
+ // inline rows where a filled idle pill would read as a hard selection.
137
+ ghost: {
138
+ base: "polli:border polli:border-transparent",
139
+ active: "polli:bg-theme-bg-active polli:text-theme-text-strong polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover",
140
+ inactive: "polli:bg-transparent polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover"
141
+ }
142
+ };
143
+ function TabButton({
144
+ as,
145
+ active,
146
+ onClick,
147
+ children,
148
+ size = "md",
149
+ variant = "soft",
150
+ intent,
151
+ ariaLabel,
152
+ disabled = false,
153
+ className,
154
+ ...rest
155
+ }) {
156
+ const Component = as || "button";
157
+ const isButton = Component === "button";
158
+ const colors = variantClasses[intent === "neutral" ? "soft" : variant];
159
+ const handleClick = disabled ? (event) => {
160
+ event.preventDefault();
161
+ event.stopPropagation();
162
+ } : onClick;
163
+ return /* @__PURE__ */ jsx4(
164
+ Component,
165
+ {
166
+ ...rest,
167
+ ...isButton ? { type: "button", disabled } : {},
168
+ ...!isButton && disabled ? { "aria-disabled": true, tabIndex: -1 } : {},
169
+ ...Component === "a" && disabled ? { href: void 0 } : {},
170
+ onClick: handleClick,
171
+ ...ariaLabel !== void 0 ? { "aria-label": ariaLabel } : {},
172
+ ...isButton ? { "aria-pressed": active } : { "aria-current": active ? "page" : void 0 },
173
+ className: cn(
174
+ tabButtonBaseClass,
175
+ variantClasses[variant].base,
176
+ active ? colors.active : colors.inactive,
177
+ disabled && "polli:pointer-events-none polli:cursor-not-allowed polli:opacity-50",
178
+ tabButtonSizeClass[size],
179
+ className
180
+ ),
181
+ children
182
+ }
183
+ );
184
+ }
185
+
186
+ // src/modules/gen/ModalityTab.tsx
187
+ import { jsx as jsx5 } from "react/jsx-runtime";
188
+ function ModalityTab({
189
+ active,
190
+ onClick,
191
+ children,
192
+ size = "md",
193
+ disabled = false,
194
+ className,
195
+ ...rest
196
+ }) {
197
+ return /* @__PURE__ */ jsx5(
198
+ TabButton,
199
+ {
200
+ ...rest,
201
+ active,
202
+ onClick,
203
+ size,
204
+ disabled,
205
+ className,
206
+ children
207
+ }
208
+ );
209
+ }
210
+
211
+ // src/primitives/icons/index.tsx
212
+ import { jsx as jsx6, jsxs } from "react/jsx-runtime";
213
+ var strokeProps = {
214
+ fill: "none",
215
+ stroke: "currentColor",
216
+ strokeWidth: 2,
217
+ strokeLinecap: "round",
218
+ strokeLinejoin: "round"
219
+ };
220
+ function CardIcon(props) {
221
+ return /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
222
+ /* @__PURE__ */ jsx6("rect", { x: "2", y: "5", width: "20", height: "14", rx: "2" }),
223
+ /* @__PURE__ */ jsx6("path", { d: "M2 10h20" })
224
+ ] });
225
+ }
226
+ function SproutIcon(props) {
227
+ return /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", ...strokeProps, ...props, children: [
228
+ /* @__PURE__ */ jsx6("path", { d: "M7 20h10" }),
229
+ /* @__PURE__ */ jsx6("path", { d: "M10 20c5.5-2.5.8-6.4 3-10" }),
230
+ /* @__PURE__ */ jsx6("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" }),
231
+ /* @__PURE__ */ jsx6("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" })
232
+ ] });
233
+ }
234
+
235
+ // src/modules/gen/ModelAccessIcon.tsx
236
+ import { jsx as jsx7 } from "react/jsx-runtime";
237
+ function ModelAccessIcon({
238
+ paidOnly = false,
239
+ className = "polli:h-3.5 polli:w-3.5"
240
+ }) {
241
+ const label = paidOnly ? "Paid Pollen required" : "Works with any Pollen";
242
+ const Icon = paidOnly ? CardIcon : SproutIcon;
243
+ return /* @__PURE__ */ jsx7(
244
+ "span",
245
+ {
246
+ role: "img",
247
+ "aria-label": label,
248
+ title: label,
249
+ className: "polli:inline-flex polli:shrink-0",
250
+ children: /* @__PURE__ */ jsx7(Icon, { className })
251
+ }
252
+ );
253
+ }
254
+
255
+ // src/primitives/Button.tsx
256
+ import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
257
+ var pillSizes = {
258
+ icon: "polli:h-12 polli:w-12 polli:p-0",
259
+ xs: "polli:h-5 polli:px-1.5 polli:py-0 polli:text-[11px] polli:leading-none",
260
+ sm: "polli:min-h-7 polli:px-2 polli:pt-0.5 polli:pb-1",
261
+ md: "polli:min-h-9 polli:px-4 polli:pt-1.5 polli:pb-2",
262
+ lg: "polli:min-h-12 polli:px-6 polli:py-3"
263
+ };
264
+ var raisedSizes = {
265
+ icon: "polli:h-12 polli:w-12 polli:p-0",
266
+ xs: "polli:px-2 polli:py-1 polli:text-xs",
267
+ sm: "polli:px-4 polli:py-2 polli:text-sm",
268
+ md: "polli:px-7 polli:py-3.5 polli:text-base",
269
+ lg: "polli:px-8 polli:py-4 polli:text-lg"
270
+ };
271
+ var appearanceClasses = {
272
+ pill: "polli:rounded-full",
273
+ 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"
274
+ };
275
+ 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";
276
+ var outlined = "polli:border polli:border-theme-text-soft polli:bg-surface-white polli:text-theme-text-strong polli:transition-colors polli:[.dark_&]:bg-transparent";
277
+ var intentClasses2 = {
278
+ brand: `${outlined} polli:hover:bg-theme-text-soft/10`,
279
+ 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`,
280
+ danger: "polli:border polli:border-intent-danger-text polli:bg-transparent polli:text-intent-danger-text polli:hover:bg-intent-danger-bg-hover polli:focus-visible:bg-intent-danger-bg-hover polli:transition-colors",
281
+ info: "polli:bg-intent-info-bg-light polli:text-intent-info-text polli:hover:bg-intent-info-bg-hover polli:transition-colors",
282
+ // Secondary actions never take the accent: one step stronger grey on hover.
283
+ 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"
19
284
  };
20
285
  var buttonClasses = ({
21
- theme: _theme,
22
286
  intent,
287
+ appearance = "pill",
23
288
  size,
24
289
  className,
25
290
  disabled
26
291
  }) => {
27
- const colorClasses = intent ? intentClasses[intent] : themeClasses;
292
+ const colorClasses = intent ? intentClasses2[intent] : themeClasses;
293
+ const sizeClasses = appearance === "raised" ? raisedSizes : pillSizes;
28
294
  return cn(
29
- "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",
295
+ "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",
30
296
  disabled ? "polli:opacity-50 polli:cursor-not-allowed" : "polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer",
31
297
  colorClasses,
32
- sizes[size || "md"],
298
+ appearanceClasses[appearance],
299
+ sizeClasses[size || "md"],
33
300
  className
34
301
  );
35
302
  };
36
303
  function Button({
37
304
  as,
38
305
  children,
39
- theme,
306
+ icon,
40
307
  intent,
308
+ appearance,
41
309
  size,
42
310
  className,
43
311
  disabled,
44
312
  ...buttonProps
45
313
  }) {
46
314
  const Component = as || "button";
47
- return /* @__PURE__ */ jsx(
315
+ const isButton = Component === "button";
316
+ const isAnchor = Component === "a";
317
+ const buttonType = buttonProps.type;
318
+ const onClick = buttonProps.onClick;
319
+ const handleClick = disabled ? (event) => {
320
+ event.preventDefault();
321
+ event.stopPropagation();
322
+ } : onClick;
323
+ return /* @__PURE__ */ jsxs2(
48
324
  Component,
49
325
  {
50
- "data-theme": intent ? void 0 : theme,
326
+ ...buttonProps,
51
327
  "data-intent": intent,
328
+ ...isButton ? { type: buttonType ?? "button", disabled } : {},
329
+ ...!isButton && disabled ? { "aria-disabled": true, tabIndex: -1 } : {},
330
+ ...isAnchor && disabled ? { href: void 0 } : {},
331
+ onClick: handleClick,
52
332
  className: buttonClasses({
53
- theme,
54
333
  intent,
334
+ appearance,
55
335
  size,
56
336
  className,
57
337
  disabled
58
338
  }),
59
- disabled,
60
- ...buttonProps,
61
- children
339
+ children: [
340
+ icon && /* @__PURE__ */ jsx8(
341
+ "span",
342
+ {
343
+ "aria-hidden": "true",
344
+ className: "polli:mr-2 polli:flex polli:size-4 polli:shrink-0 polli:[&>svg]:size-full",
345
+ children: icon
346
+ }
347
+ ),
348
+ children
349
+ ]
62
350
  }
63
351
  );
64
352
  }
65
353
 
66
354
  // src/primitives/ChevronIcon.tsx
67
- import { jsx as jsx2 } from "react/jsx-runtime";
68
- var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ jsx2(
355
+ import { jsx as jsx9 } from "react/jsx-runtime";
356
+ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ jsx9(
69
357
  "svg",
70
358
  {
71
359
  "aria-hidden": "true",
@@ -77,7 +365,7 @@ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ jsx2(
77
365
  expanded && "polli:rotate-180",
78
366
  className
79
367
  ),
80
- children: /* @__PURE__ */ jsx2(
368
+ children: /* @__PURE__ */ jsx9(
81
369
  "path",
82
370
  {
83
371
  d: "M3 4.5 6 7.5l3-3",
@@ -91,61 +379,24 @@ var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ jsx2(
91
379
  }
92
380
  );
93
381
 
94
- // src/primitives/Chip.tsx
95
- import { jsx as jsx3 } from "react/jsx-runtime";
96
- var chipSizes = {
97
- sm: "polli:px-2 polli:py-0.5 polli:text-xs",
98
- md: "polli:px-2.5 polli:py-0.5 polli:text-sm",
99
- lg: "polli:px-3 polli:py-1 polli:text-sm"
100
- };
101
- var intentClasses2 = {
102
- news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
103
- alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
104
- neutral: "polli:bg-ink-100/80 polli:text-ink-900",
105
- success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
106
- warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
107
- danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
108
- };
109
- var Chip = ({
110
- theme,
111
- intent,
112
- size = "md",
113
- className,
114
- children,
115
- ...rest
116
- }) => {
117
- const intentClass = intent ? intentClasses2[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
118
- return /* @__PURE__ */ jsx3(
119
- "span",
120
- {
121
- ...rest,
122
- "data-theme": theme,
123
- className: cn(
124
- "polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal",
125
- chipSizes[size],
126
- intentClass,
127
- className
128
- ),
129
- children
130
- }
131
- );
132
- };
133
-
134
382
  // src/primitives/Dropdown.tsx
135
383
  import { Popover } from "@ark-ui/react/popover";
136
384
  import { Portal } from "@ark-ui/react/portal";
137
- import { useState } from "react";
138
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
139
- var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg";
385
+ import { useId, useState } from "react";
386
+ import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
387
+ var DEFAULT_PANEL = "polli:rounded-lg polli:bg-surface-menu polli:shadow-lg";
140
388
  var Dropdown = ({
141
- theme,
142
389
  trigger,
143
390
  children,
144
391
  align = "start",
392
+ side = "bottom",
145
393
  open: openProp,
394
+ portalled = true,
146
395
  onOpenChange,
147
- className
396
+ className,
397
+ panelStyle
148
398
  }) => {
399
+ const triggerId = useId();
149
400
  const [internalOpen, setInternalOpen] = useState(false);
150
401
  const isControlled = openProp !== void 0;
151
402
  const open = isControlled ? openProp : internalOpen;
@@ -153,22 +404,26 @@ var Dropdown = ({
153
404
  if (!isControlled) setInternalOpen(next);
154
405
  onOpenChange?.(next);
155
406
  };
156
- return /* @__PURE__ */ jsxs(
407
+ return /* @__PURE__ */ jsxs3(
157
408
  Popover.Root,
158
409
  {
410
+ ids: { trigger: triggerId },
159
411
  open,
412
+ portalled,
160
413
  onOpenChange: (details) => setOpen(details.open),
161
414
  positioning: {
162
- placement: align === "end" ? "bottom-end" : "bottom-start"
415
+ placement: `${side}-${align}`,
416
+ strategy: portalled ? "absolute" : "fixed"
163
417
  },
164
418
  children: [
165
- /* @__PURE__ */ jsx4(Popover.Trigger, { asChild: true, children: trigger(open) }),
166
- /* @__PURE__ */ jsx4(Portal, { children: /* @__PURE__ */ jsx4(Popover.Positioner, { children: /* @__PURE__ */ jsx4(
419
+ /* @__PURE__ */ jsx10(Popover.Trigger, { asChild: true, children: trigger(open) }),
420
+ /* @__PURE__ */ jsx10(Portal, { disabled: !portalled, children: /* @__PURE__ */ jsx10(Popover.Positioner, { children: /* @__PURE__ */ jsx10(
167
421
  Popover.Content,
168
422
  {
169
- "data-theme": theme,
423
+ "aria-labelledby": triggerId,
424
+ style: panelStyle,
170
425
  className: cn(
171
- "polli:z-50 polli:overflow-hidden polli:focus:outline-none",
426
+ "polli:z-[120] polli:overflow-hidden polli:focus:outline-none",
172
427
  DEFAULT_PANEL,
173
428
  className
174
429
  ),
@@ -187,17 +442,18 @@ import {
187
442
  useEffect,
188
443
  useRef
189
444
  } from "react";
190
- import { jsx as jsx5 } from "react/jsx-runtime";
445
+ import { jsx as jsx11 } from "react/jsx-runtime";
191
446
  var axisClasses = {
192
447
  y: "polli:overflow-y-auto polli:overflow-x-hidden",
193
- x: "polli:overflow-x-auto polli:overflow-y-hidden"
448
+ x: "polli:overflow-x-auto polli:overflow-y-hidden",
449
+ both: "polli:overflow-auto"
194
450
  };
195
451
  function assignRef(ref, value) {
196
452
  if (typeof ref === "function") ref(value);
197
453
  else if (ref) ref.current = value;
198
454
  }
199
455
  var ScrollArea = forwardRef(
200
- ({ theme, axis = "y", className, children, ...rest }, externalRef) => {
456
+ ({ axis = "y", scrollbar = "subtle", className, children, ...rest }, externalRef) => {
201
457
  const innerRef = useRef(null);
202
458
  const setRef = useCallback(
203
459
  (node) => {
@@ -207,6 +463,7 @@ var ScrollArea = forwardRef(
207
463
  [externalRef]
208
464
  );
209
465
  useEffect(() => {
466
+ if (scrollbar === "native") return;
210
467
  const element = innerRef.current;
211
468
  if (!element) return;
212
469
  let hideTimer = null;
@@ -256,15 +513,15 @@ var ScrollArea = forwardRef(
256
513
  element.removeEventListener("focusin", handleInteraction);
257
514
  element.removeEventListener("focusout", scheduleHide);
258
515
  };
259
- }, []);
260
- return /* @__PURE__ */ jsx5(
516
+ }, [scrollbar]);
517
+ return /* @__PURE__ */ jsx11(
261
518
  "div",
262
519
  {
263
520
  ...rest,
264
521
  ref: setRef,
265
- "data-theme": theme,
266
522
  className: cn(
267
- "polli-scrollbar-subtle polli:min-w-0 polli:max-w-full",
523
+ scrollbar === "subtle" && "polli-scrollbar-subtle",
524
+ "polli:min-w-0 polli:max-w-full",
268
525
  axisClasses[axis],
269
526
  className
270
527
  ),
@@ -275,96 +532,22 @@ var ScrollArea = forwardRef(
275
532
  );
276
533
  ScrollArea.displayName = "ScrollArea";
277
534
 
278
- // src/primitives/TabButton.tsx
279
- import { jsx as jsx6 } from "react/jsx-runtime";
280
- var sizeClasses = {
281
- md: "polli:px-4 polli:py-1.5 polli:text-base",
282
- sm: "polli:px-3 polli:py-1.5 polli:text-sm"
283
- };
284
- var variantClasses = {
285
- default: {
286
- base: "polli:border",
287
- active: "polli:bg-theme-bg-active polli:text-theme-text-strong polli:border-theme-border",
288
- inactive: "polli:bg-theme-bg-subtle polli:text-theme-text-base polli:border-theme-border polli:hover:bg-theme-bg-active"
289
- },
290
- ghost: {
291
- base: "polli:border polli:border-transparent",
292
- active: "polli:bg-theme-bg-active polli:text-theme-text-strong",
293
- inactive: "polli:bg-transparent polli:text-theme-text-base polli:hover:bg-theme-bg-subtle polli:hover:text-theme-text-strong"
294
- }
295
- };
296
- var TabButton = ({
297
- theme,
298
- active,
299
- onClick,
300
- children,
301
- size = "md",
302
- variant = "default",
303
- ariaLabel,
304
- disabled = false,
305
- className
306
- }) => {
307
- const classes = variantClasses[variant];
308
- return /* @__PURE__ */ jsx6(
309
- "button",
310
- {
311
- type: "button",
312
- "data-theme": theme,
313
- onClick,
314
- "aria-label": ariaLabel,
315
- "aria-pressed": active,
316
- disabled,
317
- className: cn(
318
- "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",
319
- classes.base,
320
- active ? classes.active : classes.inactive,
321
- disabled && "polli:cursor-not-allowed polli:opacity-50",
322
- sizeClasses[size],
323
- className
324
- ),
325
- children
326
- }
327
- );
328
- };
329
-
330
- // src/modules/gen/themes.ts
331
- var MODALITY_THEMES = {
332
- text: "blue",
333
- image: "pink",
334
- video: "teal",
335
- audio: "amber",
336
- realtime: "coral",
337
- embedding: "violet"
338
- };
339
- function modalityTheme(category) {
340
- return MODALITY_THEMES[category];
341
- }
342
- function normalize(category) {
343
- const lower = category.toLowerCase();
344
- if (lower === "images") return "image";
345
- if (lower === "embeddings") return "embedding";
346
- return lower in MODALITY_THEMES ? lower : null;
347
- }
348
- function getModalityTheme(category) {
349
- const key = normalize(category);
350
- return key ? MODALITY_THEMES[key] : null;
351
- }
352
-
353
535
  // src/modules/gen/ModelSelector.tsx
354
- import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
536
+ import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
355
537
  var CATEGORY_LABELS = {
356
538
  image: "Image",
357
539
  video: "Video",
358
540
  text: "Text",
359
541
  audio: "Audio",
542
+ "3d": "3D",
360
543
  embedding: "Embeddings",
361
544
  realtime: "Realtime"
362
545
  };
363
546
  function categoryLabel(category) {
364
547
  return CATEGORY_LABELS[category];
365
548
  }
366
- function displayModelName(model) {
367
- return model.title;
549
+ function modelId(model) {
550
+ return model.id ?? model.name;
368
551
  }
369
552
  function ModelSelector({
370
553
  models,
@@ -373,79 +556,75 @@ function ModelSelector({
373
556
  isLoading = false,
374
557
  onChange
375
558
  }) {
376
- const filteredModels = models.filter(
377
- (model) => model.category === category
378
- );
379
- const currentModel = models.find((model) => model.id === value);
380
- const theme = modalityTheme(category);
381
- const modelLabel = currentModel ? displayModelName(currentModel) : "Select";
559
+ const filteredModels = models.filter((model) => model.category === category).sort((a, b) => modelId(a).localeCompare(modelId(b)));
560
+ const currentModel = models.find((model) => modelId(model) === value);
561
+ const modelLabel = currentModel ? currentModel.title ?? currentModel.name : "Select";
382
562
  const accessibleLabel = currentModel ? `${CATEGORY_LABELS[category]} model: ${modelLabel}` : `Select ${CATEGORY_LABELS[category].toLowerCase()} model`;
383
- return /* @__PURE__ */ jsx7(
563
+ return /* @__PURE__ */ jsx12(
384
564
  Dropdown,
385
565
  {
386
- theme,
387
- align: "end",
566
+ align: "start",
388
567
  className: "polli:w-[min(24rem,calc(100vw-2rem))] polli:p-2",
389
- trigger: (open) => /* @__PURE__ */ jsxs2(
568
+ trigger: (open) => /* @__PURE__ */ jsxs4(
390
569
  Button,
391
570
  {
392
571
  type: "button",
393
- theme,
394
572
  "aria-label": accessibleLabel,
395
573
  className: "polli:min-w-64 polli:max-w-full polli:self-start polli:justify-between polli:gap-2",
396
574
  children: [
397
- /* @__PURE__ */ jsx7("span", { className: "polli:truncate", children: modelLabel }),
398
- /* @__PURE__ */ jsx7(ChevronIcon, { expanded: open })
575
+ /* @__PURE__ */ jsxs4("span", { className: "polli:flex polli:min-w-0 polli:items-center polli:gap-2", children: [
576
+ /* @__PURE__ */ jsx12("span", { className: "polli:truncate", children: modelLabel }),
577
+ currentModel && /* @__PURE__ */ jsx12(
578
+ ModelAccessIcon,
579
+ {
580
+ paidOnly: currentModel.paid_only
581
+ }
582
+ )
583
+ ] }),
584
+ /* @__PURE__ */ jsx12(ChevronIcon, { expanded: open })
399
585
  ]
400
586
  }
401
587
  ),
402
- children: (close) => isLoading ? /* @__PURE__ */ jsx7("p", { className: "polli:m-0 polli:px-2 polli:py-2 polli:text-sm polli:text-theme-text-soft", children: "Loading models..." }) : /* @__PURE__ */ jsx7(
403
- ScrollArea,
404
- {
405
- theme,
406
- className: "polli:max-h-64 polli:pr-2",
407
- children: /* @__PURE__ */ jsx7("div", { className: "polli:flex polli:flex-col polli:gap-1", children: filteredModels.map((model) => {
408
- const isActive = value === model.id;
409
- return /* @__PURE__ */ jsxs2(
410
- TabButton,
411
- {
412
- active: isActive,
413
- theme: modalityTheme(model.category),
414
- size: "sm",
415
- variant: "ghost",
416
- className: "polli:w-full polli:justify-between polli:text-left",
417
- onClick: () => {
418
- onChange(model.id);
419
- close();
420
- },
421
- children: [
422
- /* @__PURE__ */ jsx7("span", { className: "polli:truncate", children: displayModelName(model) }),
423
- model.paidOnly && /* @__PURE__ */ jsx7(
424
- Chip,
425
- {
426
- size: "sm",
427
- className: cn(
428
- "polli:shrink-0",
429
- isActive && "polli:bg-surface-white"
430
- ),
431
- children: "paid"
432
- }
433
- )
434
- ]
435
- },
436
- model.id
437
- );
438
- }) })
439
- }
440
- )
588
+ children: (close) => isLoading ? /* @__PURE__ */ jsx12("p", { className: "polli:m-0 polli:px-2 polli:py-2 polli:text-sm polli:text-theme-text-soft", children: "Loading models..." }) : /* @__PURE__ */ jsx12(ScrollArea, { className: "polli:max-h-80 polli:pr-2", children: /* @__PURE__ */ jsx12("div", { className: "polli:flex polli:flex-col polli:gap-1", children: filteredModels.map((model) => {
589
+ const id = modelId(model);
590
+ const isActive = value === id;
591
+ return /* @__PURE__ */ jsx12(
592
+ TabButton,
593
+ {
594
+ active: isActive,
595
+ size: "sm",
596
+ variant: "ghost",
597
+ className: "polli:w-full polli:justify-start polli:text-left",
598
+ onClick: () => {
599
+ onChange(id);
600
+ close();
601
+ },
602
+ children: /* @__PURE__ */ jsxs4("span", { className: "polli:flex polli:min-w-0 polli:flex-col polli:gap-0.5", children: [
603
+ /* @__PURE__ */ jsxs4("span", { className: "polli:flex polli:min-w-0 polli:items-center polli:gap-2", children: [
604
+ /* @__PURE__ */ jsx12("span", { className: "polli:truncate", children: model.title ?? model.name }),
605
+ /* @__PURE__ */ jsx12(
606
+ ModelAccessIcon,
607
+ {
608
+ paidOnly: model.paid_only
609
+ }
610
+ )
611
+ ] }),
612
+ model.description && /* @__PURE__ */ jsx12("span", { className: "polli:truncate polli:text-xs polli:font-normal polli:text-theme-text-muted", children: model.description })
613
+ ] })
614
+ },
615
+ id
616
+ );
617
+ }) }) })
441
618
  }
442
619
  );
443
620
  }
444
621
  export {
445
- CATEGORY_LABELS,
622
+ ModalityChip,
623
+ ModalityDot,
624
+ ModalityTab,
625
+ ModelAccessIcon,
446
626
  ModelSelector,
447
627
  categoryLabel,
448
- getModalityTheme,
449
- modalityTheme
628
+ getModalityKey
450
629
  };
451
630
  //# sourceMappingURL=index.js.map