@pollinations/ui 0.1.0-alpha.0 → 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.
- package/README.md +28 -65
- package/dist/{Chip-SM52sUbZ.d.cts → Chip-CQCq34kS.d.cts} +1 -1
- package/dist/{Chip-C5impfYd.d.ts → Chip-Cj4xG7Te.d.ts} +1 -1
- package/dist/{compositions/app-user.cjs → app-user-menu/sdk.cjs} +148 -148
- package/dist/app-user-menu/sdk.cjs.map +1 -0
- package/dist/{compositions/app-user.js → app-user-menu/sdk.js} +127 -127
- package/dist/app-user-menu/sdk.js.map +1 -0
- package/dist/app.css +94 -3
- package/dist/auth/index.cjs +2 -2
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.js +2 -2
- package/dist/auth/index.js.map +1 -1
- package/dist/{models → gen}/index.cjs +40 -71
- package/dist/gen/index.cjs.map +1 -0
- package/dist/gen/index.d.cts +35 -0
- package/dist/gen/index.d.ts +35 -0
- package/dist/{models → gen}/index.js +31 -66
- package/dist/gen/index.js.map +1 -0
- package/dist/index.cjs +1594 -1142
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +268 -178
- package/dist/index.d.ts +268 -178
- package/dist/index.js +1581 -1134
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/theme-jRPPBmld.d.cts +20 -0
- package/dist/theme-jRPPBmld.d.ts +20 -0
- package/dist/wallet/index.cjs +4 -4
- package/dist/wallet/index.cjs.map +1 -1
- package/dist/wallet/index.d.cts +2 -2
- package/dist/wallet/index.d.ts +2 -2
- package/dist/wallet/index.js +4 -4
- package/dist/wallet/index.js.map +1 -1
- package/package.json +9 -24
- package/dist/Button-BvLF_Km2.d.cts +0 -26
- package/dist/Button-DQAZzvyQ.d.ts +0 -26
- package/dist/auth/sdk.cjs +0 -221
- package/dist/auth/sdk.cjs.map +0 -1
- package/dist/auth/sdk.d.cts +0 -53
- package/dist/auth/sdk.d.ts +0 -53
- package/dist/auth/sdk.js +0 -188
- package/dist/auth/sdk.js.map +0 -1
- package/dist/compositions/app-user.cjs.map +0 -1
- package/dist/compositions/app-user.js.map +0 -1
- package/dist/modality/index.cjs +0 -86
- package/dist/modality/index.cjs.map +0 -1
- package/dist/modality/index.d.cts +0 -26
- package/dist/modality/index.d.ts +0 -26
- package/dist/modality/index.js +0 -59
- package/dist/modality/index.js.map +0 -1
- package/dist/models/index.cjs.map +0 -1
- package/dist/models/index.d.cts +0 -22
- package/dist/models/index.d.ts +0 -22
- package/dist/models/index.js.map +0 -1
- package/dist/theme-VMRlhqST.d.cts +0 -9
- package/dist/theme-VMRlhqST.d.ts +0 -9
- package/dist/wallet/sdk.cjs +0 -206
- package/dist/wallet/sdk.cjs.map +0 -1
- package/dist/wallet/sdk.d.cts +0 -33
- package/dist/wallet/sdk.d.ts +0 -33
- package/dist/wallet/sdk.js +0 -175
- package/dist/wallet/sdk.js.map +0 -1
- /package/dist/{compositions/app-user.d.cts → app-user-menu/sdk.d.cts} +0 -0
- /package/dist/{compositions/app-user.d.ts → app-user-menu/sdk.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# @pollinations/ui
|
|
2
2
|
|
|
3
|
-
Internal UI primitives for Pollinations apps.
|
|
4
|
-
state from
|
|
5
|
-
core
|
|
3
|
+
Internal UI primitives, compositions, and modules for Pollinations apps.
|
|
4
|
+
SDK-backed subpaths consume auth state from
|
|
5
|
+
[`@pollinations/sdk/react`](../sdk/README.md#react-auth-provider); core
|
|
6
|
+
primitives and display recipes stay SDK-free.
|
|
6
7
|
|
|
7
8
|
## Install
|
|
8
9
|
|
|
@@ -17,56 +18,22 @@ npm install @pollinations/ui
|
|
|
17
18
|
npm install @pollinations/ui@alpha
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
Install `@pollinations/sdk` too when using
|
|
21
|
-
|
|
21
|
+
Install `@pollinations/sdk` too when using the
|
|
22
|
+
`@pollinations/ui/app-user-menu/sdk` subpath.
|
|
22
23
|
|
|
23
24
|
## Usage
|
|
24
25
|
|
|
25
26
|
```tsx
|
|
26
27
|
import "@pollinations/ui/styles.css";
|
|
27
|
-
import { PolliProvider
|
|
28
|
+
import { PolliProvider } from "@pollinations/sdk/react";
|
|
28
29
|
import { Surface } from "@pollinations/ui";
|
|
29
|
-
import {
|
|
30
|
-
LoginButton,
|
|
31
|
-
LogoutButton,
|
|
32
|
-
UserAvatar,
|
|
33
|
-
UserName,
|
|
34
|
-
WhenLoggedIn,
|
|
35
|
-
WhenLoggedOut,
|
|
36
|
-
} from "@pollinations/ui/auth/sdk";
|
|
37
|
-
import {
|
|
38
|
-
Balance,
|
|
39
|
-
KeyBudget,
|
|
40
|
-
KeyExpiry,
|
|
41
|
-
KeyModels,
|
|
42
|
-
KeyPrefix,
|
|
43
|
-
} from "@pollinations/ui/wallet/sdk";
|
|
44
|
-
|
|
45
|
-
function RecentRequests() {
|
|
46
|
-
const { data: usage } = useAccountKeyUsage({ days: 7, limit: 5 });
|
|
47
|
-
return <span>{usage?.usage.length ?? 0} recent requests</span>;
|
|
48
|
-
}
|
|
30
|
+
import { AppUserMenu } from "@pollinations/ui/app-user-menu/sdk";
|
|
49
31
|
|
|
50
32
|
export function App() {
|
|
51
33
|
return (
|
|
52
34
|
<PolliProvider appKey="pk_your_publishable_key" permissions={["profile"]}>
|
|
53
35
|
<Surface data-theme="amber">
|
|
54
|
-
<
|
|
55
|
-
<LoginButton theme="amber">
|
|
56
|
-
Log in with Pollinations
|
|
57
|
-
</LoginButton>
|
|
58
|
-
</WhenLoggedOut>
|
|
59
|
-
<WhenLoggedIn>
|
|
60
|
-
<UserAvatar size="md" />
|
|
61
|
-
<UserName />
|
|
62
|
-
<Balance />
|
|
63
|
-
<KeyPrefix />
|
|
64
|
-
<KeyBudget />
|
|
65
|
-
<KeyExpiry />
|
|
66
|
-
<KeyModels />
|
|
67
|
-
<RecentRequests />
|
|
68
|
-
<LogoutButton theme="amber">Log out</LogoutButton>
|
|
69
|
-
</WhenLoggedIn>
|
|
36
|
+
<AppUserMenu dashboardHref="https://enter.pollinations.ai" />
|
|
70
37
|
</Surface>
|
|
71
38
|
</PolliProvider>
|
|
72
39
|
);
|
|
@@ -104,30 +71,25 @@ Wallet colors and utilities are bundled into the main stylesheet
|
|
|
104
71
|
- `@pollinations/ui/auth` exports SDK-free auth modal pieces:
|
|
105
72
|
`AuthModal`, `AuthModalHeader`, `AuthModalLoading`, `AuthInfoCard`, and
|
|
106
73
|
`ErrorBanner`.
|
|
107
|
-
- `@pollinations/ui/auth/sdk` exports identity/session components that read
|
|
108
|
-
from the surrounding `<PolliProvider>`:
|
|
109
|
-
- **null when not logged in (or before data loads):** `LogoutButton`,
|
|
110
|
-
`UserAvatar`, `UserEmail`, `UserName`, `WhenLoggedIn`.
|
|
111
|
-
- **shown only when logged out:** `LoginButton`, `WhenLoggedOut`.
|
|
112
|
-
|
|
113
|
-
These are intentionally bare wrappers around `useAuth*` hooks. They render
|
|
114
|
-
the data and nothing else — no default copy, no default theme, no default
|
|
115
|
-
intent. The app composes layout, copy, and color.
|
|
116
74
|
- `@pollinations/ui/wallet` exports SDK-free wallet-specific display helpers
|
|
117
75
|
and recipes: `formatPollen`, `PaidChip`, `TierChip`, `WalletDot`,
|
|
118
76
|
`WalletBalanceCard`, `PAID_BALANCE_CHART_COLOR`, and
|
|
119
77
|
`TIER_BALANCE_CHART_COLOR`.
|
|
120
|
-
- `@pollinations/ui/
|
|
121
|
-
|
|
122
|
-
- `@pollinations/ui/
|
|
78
|
+
- `@pollinations/ui/app-user-menu/sdk` exports the SDK-backed app account
|
|
79
|
+
menu module.
|
|
80
|
+
- `@pollinations/ui/gen` exports the generation UI — `ModelSelector`,
|
|
81
|
+
category labels, and the model-modality theme mapping.
|
|
123
82
|
- `@pollinations/ui/assets/*` exports canonical Pollinations source SVGs:
|
|
124
83
|
`logo.svg` and `logo-wordmark.svg`.
|
|
125
|
-
- **Design primitives** — `
|
|
126
|
-
`
|
|
127
|
-
`IconButton`, `
|
|
128
|
-
`
|
|
129
|
-
`
|
|
130
|
-
|
|
84
|
+
- **Design primitives** — `Button`, `ButtonGroup`, `Chip`, `ChevronIcon`,
|
|
85
|
+
`Dialog`, `DialogTitle`, `Dropdown`, `DropdownItem`, `Field`, `Heading`,
|
|
86
|
+
`IconButton`, `InlineLink`, `Input`, `ScrollArea`, `Slider`, `Surface`,
|
|
87
|
+
`Switch`, `TabButton`, `Table`, `TableBody`, `TableCell`, `TableHead`,
|
|
88
|
+
`TableHeaderCell`, `TableRow`, `Text`, `Textarea`, `Tooltip`.
|
|
89
|
+
- **Design compositions** — `Alert`, `CodeBlock`, `Collapsible`,
|
|
90
|
+
`CopyButton`, `ExternalLinkButton`, `FileUpload`, `InfoTip`, `LinkCard`,
|
|
91
|
+
`Markdown`, `MediaPlaceholder`, `MultiSelect`, `NavItem`, `PeriodPicker`,
|
|
92
|
+
`Prose`, `Section`, `StatCard`.
|
|
131
93
|
- **Helpers** — `cn`, `useScrollLock`, `currentPeriod`,
|
|
132
94
|
`getPeriodBucketKeys`, `periodBucketKeyToDate`.
|
|
133
95
|
- **Theme** — `themes` (runtime array of theme names), `ThemeName` (type).
|
|
@@ -139,16 +101,17 @@ from `@pollinations/sdk/react` (`useAccountKeyUsage`, `useAccountKey`,
|
|
|
139
101
|
## Source Layout
|
|
140
102
|
|
|
141
103
|
- `src/primitives/*` contains generic, SDK-free building blocks.
|
|
104
|
+
- `src/compositions/*` contains SDK-free recipes that compose primitives.
|
|
142
105
|
- `src/modules/*` contains package-owned recipes with domain assumptions
|
|
143
|
-
such as auth, wallet, and
|
|
106
|
+
such as auth, wallet, app-user-menu, and gen.
|
|
144
107
|
- Public subpath exports (`@pollinations/ui/auth`,
|
|
145
|
-
`@pollinations/ui/
|
|
146
|
-
`@pollinations/ui/
|
|
147
|
-
|
|
108
|
+
`@pollinations/ui/wallet`, `@pollinations/ui/gen`,
|
|
109
|
+
`@pollinations/ui/app-user-menu/sdk`) are built directly from those source
|
|
110
|
+
layers.
|
|
148
111
|
|
|
149
112
|
## Theming
|
|
150
113
|
|
|
151
|
-
Set `data-theme="amber" | "blue" | "pink" | "teal" | "violet" | "
|
|
114
|
+
Set `data-theme="amber" | "blue" | "pink" | "coral" | "teal" | "violet" | "emerald"`
|
|
152
115
|
on any ancestor (or per-component via the `theme` prop on Button-family
|
|
153
116
|
components) to switch the cascade. Theme variables are defined in
|
|
154
117
|
`styles.css` — import it once at your app entry.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FC, ComponentPropsWithoutRef } from 'react';
|
|
2
|
-
import { T as ThemeName } from './theme-
|
|
2
|
+
import { T as ThemeName } from './theme-jRPPBmld.cjs';
|
|
3
3
|
|
|
4
4
|
/** Semantic chip labels for status and metadata badges. */
|
|
5
5
|
type ChipIntent = "news" | "alpha" | "neutral" | "success" | "warning" | "danger";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FC, ComponentPropsWithoutRef } from 'react';
|
|
2
|
-
import { T as ThemeName } from './theme-
|
|
2
|
+
import { T as ThemeName } from './theme-jRPPBmld.js';
|
|
3
3
|
|
|
4
4
|
/** Semantic chip labels for status and metadata badges. */
|
|
5
5
|
type ChipIntent = "news" | "alpha" | "neutral" | "success" | "warning" | "danger";
|
|
@@ -17,20 +17,17 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
|
-
// src/
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
20
|
+
// src/modules/app-user-menu/sdk.ts
|
|
21
|
+
var sdk_exports = {};
|
|
22
|
+
__export(sdk_exports, {
|
|
23
23
|
AppUserMenu: () => AppUserMenu,
|
|
24
24
|
isEmbeddedContext: () => isEmbeddedContext
|
|
25
25
|
});
|
|
26
|
-
module.exports = __toCommonJS(
|
|
26
|
+
module.exports = __toCommonJS(sdk_exports);
|
|
27
27
|
|
|
28
|
-
// src/
|
|
28
|
+
// src/modules/app-user-menu/AppUserMenu.tsx
|
|
29
29
|
var import_react10 = require("@pollinations/sdk/react");
|
|
30
30
|
|
|
31
|
-
// src/modules/auth/LoginButton.tsx
|
|
32
|
-
var import_react = require("@pollinations/sdk/react");
|
|
33
|
-
|
|
34
31
|
// src/lib/cn.ts
|
|
35
32
|
var import_clsx = require("clsx");
|
|
36
33
|
var import_tailwind_merge = require("tailwind-merge");
|
|
@@ -39,8 +36,111 @@ function cn(...inputs) {
|
|
|
39
36
|
return twMerge((0, import_clsx.clsx)(...inputs));
|
|
40
37
|
}
|
|
41
38
|
|
|
42
|
-
// src/primitives/
|
|
39
|
+
// src/primitives/ChevronIcon.tsx
|
|
43
40
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
41
|
+
var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
42
|
+
"svg",
|
|
43
|
+
{
|
|
44
|
+
"aria-hidden": "true",
|
|
45
|
+
width: "12",
|
|
46
|
+
height: "12",
|
|
47
|
+
viewBox: "0 0 12 12",
|
|
48
|
+
className: cn(
|
|
49
|
+
"polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out",
|
|
50
|
+
expanded && "polli:rotate-180",
|
|
51
|
+
className
|
|
52
|
+
),
|
|
53
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
54
|
+
"path",
|
|
55
|
+
{
|
|
56
|
+
d: "M3 4.5 6 7.5l3-3",
|
|
57
|
+
fill: "none",
|
|
58
|
+
stroke: "currentColor",
|
|
59
|
+
strokeLinecap: "round",
|
|
60
|
+
strokeLinejoin: "round",
|
|
61
|
+
strokeWidth: "1.5"
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// src/primitives/Dropdown.tsx
|
|
68
|
+
var import_popover = require("@ark-ui/react/popover");
|
|
69
|
+
var import_portal = require("@ark-ui/react/portal");
|
|
70
|
+
var import_react = require("react");
|
|
71
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
72
|
+
var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg";
|
|
73
|
+
var Dropdown = ({
|
|
74
|
+
theme,
|
|
75
|
+
trigger,
|
|
76
|
+
children,
|
|
77
|
+
align = "start",
|
|
78
|
+
open: openProp,
|
|
79
|
+
onOpenChange,
|
|
80
|
+
className
|
|
81
|
+
}) => {
|
|
82
|
+
const [internalOpen, setInternalOpen] = (0, import_react.useState)(false);
|
|
83
|
+
const isControlled = openProp !== void 0;
|
|
84
|
+
const open = isControlled ? openProp : internalOpen;
|
|
85
|
+
const setOpen = (next) => {
|
|
86
|
+
if (!isControlled) setInternalOpen(next);
|
|
87
|
+
onOpenChange?.(next);
|
|
88
|
+
};
|
|
89
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
90
|
+
import_popover.Popover.Root,
|
|
91
|
+
{
|
|
92
|
+
open,
|
|
93
|
+
onOpenChange: (details) => setOpen(details.open),
|
|
94
|
+
positioning: {
|
|
95
|
+
placement: align === "end" ? "bottom-end" : "bottom-start"
|
|
96
|
+
},
|
|
97
|
+
children: [
|
|
98
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_popover.Popover.Trigger, { asChild: true, children: trigger(open) }),
|
|
99
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_portal.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_popover.Popover.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
100
|
+
import_popover.Popover.Content,
|
|
101
|
+
{
|
|
102
|
+
"data-theme": theme,
|
|
103
|
+
className: cn(
|
|
104
|
+
"polli:z-50 polli:overflow-hidden polli:focus:outline-none",
|
|
105
|
+
DEFAULT_PANEL,
|
|
106
|
+
className
|
|
107
|
+
),
|
|
108
|
+
children: typeof children === "function" ? children(() => setOpen(false)) : children
|
|
109
|
+
}
|
|
110
|
+
) }) })
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/primitives/DropdownItem.tsx
|
|
117
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
118
|
+
function DropdownItem({
|
|
119
|
+
as,
|
|
120
|
+
className,
|
|
121
|
+
children,
|
|
122
|
+
...rest
|
|
123
|
+
}) {
|
|
124
|
+
const Component = as || "button";
|
|
125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
126
|
+
Component,
|
|
127
|
+
{
|
|
128
|
+
...Component === "button" ? { type: "button" } : void 0,
|
|
129
|
+
...rest,
|
|
130
|
+
className: cn(
|
|
131
|
+
"polli-control polli:flex polli:w-full polli:cursor-pointer polli:items-center polli:gap-2 polli:rounded-lg polli:bg-transparent polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:text-theme-text-base polli:no-underline polli:transition-colors polli:hover:bg-theme-bg-hover polli:focus-visible:bg-theme-bg-hover",
|
|
132
|
+
className
|
|
133
|
+
),
|
|
134
|
+
children
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/modules/auth/LoginButton.tsx
|
|
140
|
+
var import_react2 = require("@pollinations/sdk/react");
|
|
141
|
+
|
|
142
|
+
// src/primitives/Button.tsx
|
|
143
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
44
144
|
var sizes = {
|
|
45
145
|
sm: "polli:px-2 polli:pt-0.5 polli:pb-1",
|
|
46
146
|
md: "polli:px-4 polli:pt-1.5 polli:pb-2",
|
|
@@ -77,7 +177,7 @@ function Button({
|
|
|
77
177
|
...buttonProps
|
|
78
178
|
}) {
|
|
79
179
|
const Component = as || "button";
|
|
80
|
-
return /* @__PURE__ */ (0,
|
|
180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
81
181
|
Component,
|
|
82
182
|
{
|
|
83
183
|
"data-theme": intent ? void 0 : theme,
|
|
@@ -97,17 +197,17 @@ function Button({
|
|
|
97
197
|
}
|
|
98
198
|
|
|
99
199
|
// src/modules/auth/LoginButton.tsx
|
|
100
|
-
var
|
|
200
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
101
201
|
function LoginButton({ children, ...buttonProps }) {
|
|
102
|
-
const { isLoggedIn } = (0,
|
|
103
|
-
const { login } = (0,
|
|
202
|
+
const { isLoggedIn } = (0, import_react2.useAuthState)();
|
|
203
|
+
const { login } = (0, import_react2.useAuthActions)();
|
|
104
204
|
if (isLoggedIn) return null;
|
|
105
|
-
return /* @__PURE__ */ (0,
|
|
205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { ...buttonProps, onClick: () => login(), children });
|
|
106
206
|
}
|
|
107
207
|
|
|
108
208
|
// src/modules/auth/UserAvatar.tsx
|
|
109
|
-
var
|
|
110
|
-
var
|
|
209
|
+
var import_react3 = require("@pollinations/sdk/react");
|
|
210
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
111
211
|
var sizeClass = {
|
|
112
212
|
sm: "polli:w-6 polli:h-6 polli:text-xs",
|
|
113
213
|
md: "polli:w-9 polli:h-9 polli:text-sm",
|
|
@@ -122,8 +222,8 @@ function initials(name) {
|
|
|
122
222
|
return (first + last).toUpperCase() || null;
|
|
123
223
|
}
|
|
124
224
|
function UserAvatar({ size = "md", className }) {
|
|
125
|
-
const { isLoggedIn } = (0,
|
|
126
|
-
const { data: profile } = (0,
|
|
225
|
+
const { isLoggedIn } = (0, import_react3.useAuthState)();
|
|
226
|
+
const { data: profile } = (0, import_react3.useAccountProfile)({ enabled: isLoggedIn });
|
|
127
227
|
if (!isLoggedIn) return null;
|
|
128
228
|
const base = cn(
|
|
129
229
|
"polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:overflow-hidden polli:bg-theme-bg-pale polli:text-theme-text-strong polli:font-semibold polli:select-none",
|
|
@@ -131,7 +231,7 @@ function UserAvatar({ size = "md", className }) {
|
|
|
131
231
|
className
|
|
132
232
|
);
|
|
133
233
|
if (profile?.image) {
|
|
134
|
-
return /* @__PURE__ */ (0,
|
|
234
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
135
235
|
"img",
|
|
136
236
|
{
|
|
137
237
|
"data-polli": "user-avatar",
|
|
@@ -143,7 +243,7 @@ function UserAvatar({ size = "md", className }) {
|
|
|
143
243
|
}
|
|
144
244
|
const label = profile?.name ? initials(profile.name) : null;
|
|
145
245
|
if (!label) return null;
|
|
146
|
-
return /* @__PURE__ */ (0,
|
|
246
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
147
247
|
"div",
|
|
148
248
|
{
|
|
149
249
|
"data-polli": "user-avatar",
|
|
@@ -156,42 +256,42 @@ function UserAvatar({ size = "md", className }) {
|
|
|
156
256
|
}
|
|
157
257
|
|
|
158
258
|
// src/modules/auth/UserName.tsx
|
|
159
|
-
var
|
|
160
|
-
var
|
|
259
|
+
var import_react4 = require("@pollinations/sdk/react");
|
|
260
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
161
261
|
function UserName({ className }) {
|
|
162
|
-
const { isLoggedIn } = (0,
|
|
163
|
-
const { data: profile } = (0,
|
|
262
|
+
const { isLoggedIn } = (0, import_react4.useAuthState)();
|
|
263
|
+
const { data: profile } = (0, import_react4.useAccountProfile)({ enabled: isLoggedIn });
|
|
164
264
|
if (!isLoggedIn || !profile) return null;
|
|
165
265
|
const display = profile.name || profile.githubUsername;
|
|
166
266
|
if (!display) return null;
|
|
167
|
-
return /* @__PURE__ */ (0,
|
|
267
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "data-polli": "user-name", className, children: display });
|
|
168
268
|
}
|
|
169
269
|
|
|
170
270
|
// src/modules/auth/WhenLoggedIn.tsx
|
|
171
|
-
var
|
|
172
|
-
var
|
|
173
|
-
var
|
|
271
|
+
var import_react5 = require("@pollinations/sdk/react");
|
|
272
|
+
var import_react6 = require("react");
|
|
273
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
174
274
|
function WhenLoggedIn({ children }) {
|
|
175
|
-
const { isLoggedIn } = (0,
|
|
275
|
+
const { isLoggedIn } = (0, import_react5.useAuthState)();
|
|
176
276
|
if (!isLoggedIn) return null;
|
|
177
|
-
return /* @__PURE__ */ (0,
|
|
277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react6.Fragment, { children });
|
|
178
278
|
}
|
|
179
279
|
|
|
180
280
|
// src/modules/auth/WhenLoggedOut.tsx
|
|
181
|
-
var
|
|
182
|
-
var
|
|
183
|
-
var
|
|
281
|
+
var import_react7 = require("@pollinations/sdk/react");
|
|
282
|
+
var import_react8 = require("react");
|
|
283
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
184
284
|
function WhenLoggedOut({ children }) {
|
|
185
|
-
const { isLoggedIn } = (0,
|
|
285
|
+
const { isLoggedIn } = (0, import_react7.useAuthState)();
|
|
186
286
|
if (isLoggedIn) return null;
|
|
187
|
-
return /* @__PURE__ */ (0,
|
|
287
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react8.Fragment, { children });
|
|
188
288
|
}
|
|
189
289
|
|
|
190
290
|
// src/modules/wallet/Balance.tsx
|
|
191
|
-
var
|
|
291
|
+
var import_react9 = require("@pollinations/sdk/react");
|
|
192
292
|
|
|
193
293
|
// src/primitives/Chip.tsx
|
|
194
|
-
var
|
|
294
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
195
295
|
var chipSizes = {
|
|
196
296
|
sm: "polli:px-2 polli:py-0.5 polli:text-xs",
|
|
197
297
|
md: "polli:px-2.5 polli:py-0.5 polli:text-sm",
|
|
@@ -200,10 +300,10 @@ var chipSizes = {
|
|
|
200
300
|
var intentClasses2 = {
|
|
201
301
|
news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
|
|
202
302
|
alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
|
|
203
|
-
neutral: "polli:
|
|
204
|
-
success: "polli:
|
|
205
|
-
warning: "polli:
|
|
206
|
-
danger: "polli:
|
|
303
|
+
neutral: "polli:bg-ink-100/80 polli:text-ink-900",
|
|
304
|
+
success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
|
|
305
|
+
warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
|
|
306
|
+
danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
|
|
207
307
|
};
|
|
208
308
|
var Chip = ({
|
|
209
309
|
theme,
|
|
@@ -214,7 +314,7 @@ var Chip = ({
|
|
|
214
314
|
...rest
|
|
215
315
|
}) => {
|
|
216
316
|
const intentClass = intent ? intentClasses2[intent] : "polli:bg-theme-bg-active polli:text-theme-text-strong";
|
|
217
|
-
return /* @__PURE__ */ (0,
|
|
317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
218
318
|
"span",
|
|
219
319
|
{
|
|
220
320
|
...rest,
|
|
@@ -260,12 +360,12 @@ function formatPollen(value) {
|
|
|
260
360
|
}
|
|
261
361
|
|
|
262
362
|
// src/modules/wallet/Balance.tsx
|
|
263
|
-
var
|
|
363
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
264
364
|
function Balance({ className } = {}) {
|
|
265
|
-
const { isLoggedIn } = (0,
|
|
266
|
-
const { data: balance } = (0,
|
|
365
|
+
const { isLoggedIn } = (0, import_react9.useAuthState)();
|
|
366
|
+
const { data: balance } = (0, import_react9.useAccountBalance)({ enabled: isLoggedIn });
|
|
267
367
|
if (!isLoggedIn || balance == null) return null;
|
|
268
|
-
return /* @__PURE__ */ (0,
|
|
368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
269
369
|
Chip,
|
|
270
370
|
{
|
|
271
371
|
"data-polli": "balance",
|
|
@@ -278,107 +378,7 @@ function Balance({ className } = {}) {
|
|
|
278
378
|
);
|
|
279
379
|
}
|
|
280
380
|
|
|
281
|
-
// src/
|
|
282
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
283
|
-
var ChevronIcon = ({ expanded, className }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
284
|
-
"svg",
|
|
285
|
-
{
|
|
286
|
-
"aria-hidden": "true",
|
|
287
|
-
width: "12",
|
|
288
|
-
height: "12",
|
|
289
|
-
viewBox: "0 0 12 12",
|
|
290
|
-
className: cn(
|
|
291
|
-
"polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out",
|
|
292
|
-
expanded && "polli:rotate-180",
|
|
293
|
-
className
|
|
294
|
-
),
|
|
295
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
296
|
-
"path",
|
|
297
|
-
{
|
|
298
|
-
d: "M3 4.5 6 7.5l3-3",
|
|
299
|
-
fill: "none",
|
|
300
|
-
stroke: "currentColor",
|
|
301
|
-
strokeLinecap: "round",
|
|
302
|
-
strokeLinejoin: "round",
|
|
303
|
-
strokeWidth: "1.5"
|
|
304
|
-
}
|
|
305
|
-
)
|
|
306
|
-
}
|
|
307
|
-
);
|
|
308
|
-
|
|
309
|
-
// src/primitives/Dropdown.tsx
|
|
310
|
-
var import_popover = require("@ark-ui/react/popover");
|
|
311
|
-
var import_portal = require("@ark-ui/react/portal");
|
|
312
|
-
var import_react9 = require("react");
|
|
313
|
-
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
314
|
-
var DEFAULT_PANEL = "polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg";
|
|
315
|
-
var Dropdown = ({
|
|
316
|
-
theme,
|
|
317
|
-
trigger,
|
|
318
|
-
children,
|
|
319
|
-
align = "start",
|
|
320
|
-
open: openProp,
|
|
321
|
-
onOpenChange,
|
|
322
|
-
className
|
|
323
|
-
}) => {
|
|
324
|
-
const [internalOpen, setInternalOpen] = (0, import_react9.useState)(false);
|
|
325
|
-
const isControlled = openProp !== void 0;
|
|
326
|
-
const open = isControlled ? openProp : internalOpen;
|
|
327
|
-
const setOpen = (next) => {
|
|
328
|
-
if (!isControlled) setInternalOpen(next);
|
|
329
|
-
onOpenChange?.(next);
|
|
330
|
-
};
|
|
331
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
332
|
-
import_popover.Popover.Root,
|
|
333
|
-
{
|
|
334
|
-
open,
|
|
335
|
-
onOpenChange: (details) => setOpen(details.open),
|
|
336
|
-
positioning: {
|
|
337
|
-
placement: align === "end" ? "bottom-end" : "bottom-start"
|
|
338
|
-
},
|
|
339
|
-
children: [
|
|
340
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_popover.Popover.Trigger, { asChild: true, children: trigger(open) }),
|
|
341
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_portal.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_popover.Popover.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
342
|
-
import_popover.Popover.Content,
|
|
343
|
-
{
|
|
344
|
-
"data-theme": theme,
|
|
345
|
-
className: cn(
|
|
346
|
-
"polli:z-50 polli:overflow-hidden polli:focus:outline-none",
|
|
347
|
-
DEFAULT_PANEL,
|
|
348
|
-
className
|
|
349
|
-
),
|
|
350
|
-
children: typeof children === "function" ? children(() => setOpen(false)) : children
|
|
351
|
-
}
|
|
352
|
-
) }) })
|
|
353
|
-
]
|
|
354
|
-
}
|
|
355
|
-
);
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
// src/primitives/DropdownItem.tsx
|
|
359
|
-
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
360
|
-
function DropdownItem({
|
|
361
|
-
as,
|
|
362
|
-
className,
|
|
363
|
-
children,
|
|
364
|
-
...rest
|
|
365
|
-
}) {
|
|
366
|
-
const Component = as || "button";
|
|
367
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
368
|
-
Component,
|
|
369
|
-
{
|
|
370
|
-
...Component === "button" ? { type: "button" } : void 0,
|
|
371
|
-
...rest,
|
|
372
|
-
className: cn(
|
|
373
|
-
"polli-control polli:flex polli:w-full polli:cursor-pointer polli:items-center polli:gap-2 polli:rounded-lg polli:bg-transparent polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:text-theme-text-base polli:no-underline polli:transition-colors polli:hover:bg-theme-bg-hover polli:focus-visible:bg-theme-bg-hover",
|
|
374
|
-
className
|
|
375
|
-
),
|
|
376
|
-
children
|
|
377
|
-
}
|
|
378
|
-
);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
// src/compositions/app-user/AppUserMenu.tsx
|
|
381
|
+
// src/modules/app-user-menu/AppUserMenu.tsx
|
|
382
382
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
383
383
|
var defaultLabels = {
|
|
384
384
|
authorize: "Authorize app",
|
|
@@ -494,4 +494,4 @@ function AppUserMenuContent({
|
|
|
494
494
|
AppUserMenu,
|
|
495
495
|
isEmbeddedContext
|
|
496
496
|
});
|
|
497
|
-
//# sourceMappingURL=
|
|
497
|
+
//# sourceMappingURL=sdk.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/app-user-menu/sdk.ts","../../src/modules/app-user-menu/AppUserMenu.tsx","../../src/lib/cn.ts","../../src/primitives/ChevronIcon.tsx","../../src/primitives/Dropdown.tsx","../../src/primitives/DropdownItem.tsx","../../src/modules/auth/LoginButton.tsx","../../src/primitives/Button.tsx","../../src/modules/auth/UserAvatar.tsx","../../src/modules/auth/UserName.tsx","../../src/modules/auth/WhenLoggedIn.tsx","../../src/modules/auth/WhenLoggedOut.tsx","../../src/modules/wallet/Balance.tsx","../../src/primitives/Chip.tsx","../../src/modules/wallet/format-pollen.ts"],"sourcesContent":["export {\n AppUserMenu,\n type AppUserMenuLabels,\n type AppUserMenuProps,\n isEmbeddedContext,\n} from \"./AppUserMenu.tsx\";\n","import { useAuthActions } from \"@pollinations/sdk/react\";\nimport { ChevronIcon } from \"../../primitives/ChevronIcon.tsx\";\nimport { Dropdown } from \"../../primitives/Dropdown.tsx\";\nimport { DropdownItem } from \"../../primitives/DropdownItem.tsx\";\nimport {\n LoginButton,\n UserAvatar,\n UserName,\n WhenLoggedIn,\n WhenLoggedOut,\n} from \"../auth/sdk.ts\";\nimport { Balance } from \"../wallet/sdk.ts\";\n\nexport type AppUserMenuLabels = {\n authorize: string;\n appUserMenu: string;\n topUpAccount: string;\n logout: string;\n};\n\nexport type AppUserMenuProps = {\n dashboardHref: string;\n labels?: Partial<AppUserMenuLabels>;\n hiddenWhenEmbedded?: boolean;\n embedQueryParam?: string;\n};\n\nconst defaultLabels: AppUserMenuLabels = {\n authorize: \"Authorize app\",\n appUserMenu: \"App user menu\",\n topUpAccount: \"Top up account\",\n logout: \"Log out from this app\",\n};\n\nexport function isEmbeddedContext(embedQueryParam = \"embed\"): boolean {\n if (typeof window === \"undefined\") return false;\n const search = new URLSearchParams(window.location.search);\n if (search.get(embedQueryParam) === \"1\") return true;\n try {\n return window.self !== window.top;\n } catch {\n return true;\n }\n}\n\nexport function AppUserMenu({\n dashboardHref,\n labels: labelOverrides,\n hiddenWhenEmbedded = false,\n embedQueryParam = \"embed\",\n}: AppUserMenuProps) {\n if (hiddenWhenEmbedded && isEmbeddedContext(embedQueryParam)) return null;\n\n return (\n <AppUserMenuContent\n dashboardHref={dashboardHref}\n labels={labelOverrides}\n />\n );\n}\n\nfunction AppUserMenuContent({\n dashboardHref,\n labels: labelOverrides,\n}: Pick<AppUserMenuProps, \"dashboardHref\" | \"labels\">) {\n const labels = { ...defaultLabels, ...labelOverrides };\n const { logout } = useAuthActions();\n\n return (\n <div data-theme=\"amber\" className=\"polli:flex polli:justify-end\">\n <WhenLoggedOut>\n <LoginButton theme=\"amber\">{labels.authorize}</LoginButton>\n </WhenLoggedOut>\n\n <WhenLoggedIn>\n <Dropdown\n theme=\"amber\"\n align=\"end\"\n className=\"polli:w-64 polli:p-1\"\n trigger={(open) => (\n <button\n type=\"button\"\n data-theme=\"amber\"\n aria-label={labels.appUserMenu}\n className=\"polli-control polli:flex polli:min-w-0 polli:items-center polli:gap-2 polli:rounded-full polli:bg-theme-bg-active polli:py-1 polli:pl-1 polli:pr-3 polli:text-theme-text-base polli:shadow-sm polli:transition-colors polli:hover:bg-theme-bg-hover\"\n >\n <UserAvatar\n size=\"md\"\n className=\"polli:h-8 polli:w-8\"\n />\n <span className=\"polli:flex polli:min-w-0 polli:flex-col polli:items-start polli:leading-tight\">\n <UserName className=\"polli:max-w-32 polli:truncate polli:text-sm polli:font-semibold\" />\n <Balance className=\"polli:bg-transparent polli:px-0 polli:py-0 polli:text-xs polli:text-theme-text-base\" />\n </span>\n <ChevronIcon\n expanded={open}\n className=\"polli:h-4 polli:w-4 polli:text-theme-text-base\"\n />\n </button>\n )}\n >\n {(close) => (\n <div\n data-theme=\"amber\"\n className=\"polli:flex polli:flex-col\"\n >\n <DropdownItem\n as=\"a\"\n href={dashboardHref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={close}\n >\n {labels.topUpAccount}\n </DropdownItem>\n <DropdownItem\n type=\"button\"\n onClick={() => {\n close();\n logout();\n }}\n >\n {labels.logout}\n </DropdownItem>\n </div>\n )}\n </Dropdown>\n </WhenLoggedIn>\n </div>\n );\n}\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 { 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 { 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 type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype BaseDropdownItemProps = {\n className?: string;\n};\n\nexport type DropdownItemProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseDropdownItemProps> & {\n as?: T;\n } & Omit<\n React.ComponentPropsWithoutRef<T>,\n keyof BaseDropdownItemProps | \"as\"\n >;\n\nexport function DropdownItem<T extends React.ElementType = \"button\">({\n as,\n className,\n children,\n ...rest\n}: DropdownItemProps<T>) {\n const Component: React.ElementType = as || \"button\";\n return (\n <Component\n {...(Component === \"button\" ? { type: \"button\" } : undefined)}\n {...rest}\n className={cn(\n \"polli-control polli:flex polli:w-full polli:cursor-pointer polli:items-center polli:gap-2 polli:rounded-lg polli:bg-transparent polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:text-theme-text-base polli:no-underline polli:transition-colors polli:hover:bg-theme-bg-hover polli:focus-visible:bg-theme-bg-hover\",\n className,\n )}\n >\n {children}\n </Component>\n );\n}\n","import { useAuthActions, useAuthState } from \"@pollinations/sdk/react\";\nimport type { ReactNode } from \"react\";\nimport { Button, type ButtonProps } from \"../../primitives/Button.tsx\";\n\nexport type LoginButtonProps = Omit<\n ButtonProps<\"button\">,\n \"as\" | \"onClick\" | \"children\"\n> & {\n children: ReactNode;\n};\n\n/** Button that kicks off the auth redirect. `null` when already logged in. */\nexport function LoginButton({ children, ...buttonProps }: LoginButtonProps) {\n const { isLoggedIn } = useAuthState();\n const { login } = useAuthActions();\n if (isLoggedIn) return null;\n return (\n <Button {...buttonProps} onClick={() => login()}>\n {children}\n </Button>\n );\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 { useAccountProfile, useAuthState } from \"@pollinations/sdk/react\";\nimport { cn } from \"../../lib/cn.ts\";\n\nexport type UserAvatarProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n};\n\nconst sizeClass = {\n sm: \"polli:w-6 polli:h-6 polli:text-xs\",\n md: \"polli:w-9 polli:h-9 polli:text-sm\",\n lg: \"polli:w-12 polli:h-12 polli:text-base\",\n} as const;\n\nfunction initials(name: string): string | null {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return null;\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase() || null;\n const first = parts[0][0] ?? \"\";\n const last = parts[parts.length - 1][0] ?? \"\";\n return (first + last).toUpperCase() || null;\n}\n\n/** Avatar from `profile.image`, or initials from `profile.name`. `null` otherwise. */\nexport function UserAvatar({ size = \"md\", className }: UserAvatarProps) {\n const { isLoggedIn } = useAuthState();\n const { data: profile } = useAccountProfile({ enabled: isLoggedIn });\n if (!isLoggedIn) return null;\n\n const base = cn(\n \"polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:overflow-hidden polli:bg-theme-bg-pale polli:text-theme-text-strong polli:font-semibold polli:select-none\",\n sizeClass[size],\n className,\n );\n\n if (profile?.image) {\n return (\n <img\n data-polli=\"user-avatar\"\n src={profile.image}\n alt={profile.name ?? \"\"}\n className={base}\n />\n );\n }\n const label = profile?.name ? initials(profile.name) : null;\n if (!label) return null;\n return (\n <div\n data-polli=\"user-avatar\"\n role=\"img\"\n aria-label={profile?.name ?? undefined}\n className={base}\n >\n {label}\n </div>\n );\n}\n","import { useAccountProfile, useAuthState } from \"@pollinations/sdk/react\";\n\nexport type UserNameProps = { className?: string };\n\n/**\n * Renders the user's display name. Falls back to GitHub username when the\n * `profile` scope was not granted (or `name` is empty). `null` when logged\n * out, or when neither name nor GitHub username is available.\n */\nexport function UserName({ className }: UserNameProps) {\n const { isLoggedIn } = useAuthState();\n const { data: profile } = useAccountProfile({ enabled: isLoggedIn });\n if (!isLoggedIn || !profile) return null;\n const display = profile.name || profile.githubUsername;\n if (!display) return null;\n return (\n <span data-polli=\"user-name\" className={className}>\n {display}\n </span>\n );\n}\n","import { useAuthState } from \"@pollinations/sdk/react\";\nimport { Fragment, type ReactNode } from \"react\";\n\nexport type WhenLoggedInProps = { children: ReactNode };\n\n/** Renders `children` only when a user is signed in. */\nexport function WhenLoggedIn({ children }: WhenLoggedInProps) {\n const { isLoggedIn } = useAuthState();\n if (!isLoggedIn) return null;\n return <Fragment>{children}</Fragment>;\n}\n","import { useAuthState } from \"@pollinations/sdk/react\";\nimport { Fragment, type ReactNode } from \"react\";\n\nexport type WhenLoggedOutProps = { children: ReactNode };\n\n/** Renders `children` only when no user is signed in. */\nexport function WhenLoggedOut({ children }: WhenLoggedOutProps) {\n const { isLoggedIn } = useAuthState();\n if (isLoggedIn) return null;\n return <Fragment>{children}</Fragment>;\n}\n","import { useAccountBalance, useAuthState } from \"@pollinations/sdk/react\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { Chip } from \"../../primitives/Chip.tsx\";\nimport { formatPollen } from \"./format-pollen.ts\";\n\nexport type BalanceProps = { className?: string };\n\n/** Renders the logged-in user's pollen balance. `null` until loaded. */\nexport function Balance({ className }: BalanceProps = {}) {\n const { isLoggedIn } = useAuthState();\n const { data: balance } = useAccountBalance({ enabled: isLoggedIn });\n if (!isLoggedIn || balance == null) return null;\n return (\n <Chip\n data-polli=\"balance\"\n className={cn(\"polli:tabular-nums\", className)}\n >\n {formatPollen(balance.balance)} pollen\n </Chip>\n );\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","// 5-digit budget for pollen display. Integer takes its space, decimals fill\n// the remainder (capped at 4), floor toward -infinity, trailing zeros stripped.\n// Integers needing >=6 digits switch to compact (K/M/B, 3 sig figs).\n// Decimal point and minus sign do not count toward the budget.\n\nconst BUDGET = 5;\nconst MAX_DECIMALS = 4;\nconst COMPACT_THRESHOLD = 100_000;\n\nfunction floorTo(value: number, decimals: number): number {\n const factor = 10 ** decimals;\n return Math.floor(value * factor) / factor;\n}\n\nfunction formatCompact(value: number): string {\n const abs = Math.abs(value);\n const sign = value < 0 ? \"-\" : \"\";\n const [unit, scale] =\n abs >= 1e9\n ? ([\"B\", 1e9] as const)\n : abs >= 1e6\n ? ([\"M\", 1e6] as const)\n : ([\"K\", 1e3] as const);\n const ratio = abs / scale;\n const intDigits = Math.max(1, Math.floor(Math.log10(ratio)) + 1);\n const decimals = Math.max(0, 3 - intDigits);\n const floored = floorTo(ratio, decimals);\n return `${sign}${Number(floored.toFixed(decimals)).toString()}${unit}`;\n}\n\nexport function formatPollen(value: number): string {\n if (!Number.isFinite(value) || value === 0) return \"0\";\n\n const abs = Math.abs(value);\n\n if (abs >= COMPACT_THRESHOLD) return formatCompact(value);\n\n const intDigits = abs >= 1 ? Math.floor(Math.log10(abs)) + 1 : 1;\n const decimals = Math.min(MAX_DECIMALS, Math.max(0, BUDGET - intDigits));\n const floored = floorTo(value, decimals);\n if (floored === 0) return \"0\";\n return Number(floored.toFixed(decimals)).toString();\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","intentClasses","import_jsx_runtime","import_jsx_runtime"]}
|