@pollinations/ui 0.0.2 → 0.1.0-alpha.0

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 (48) hide show
  1. package/README.md +10 -6
  2. package/dist/{Button-CWUBCiIc.d.cts → Button-BvLF_Km2.d.cts} +3 -3
  3. package/dist/{Button-Bn8pGg6N.d.ts → Button-DQAZzvyQ.d.ts} +3 -3
  4. package/dist/auth/index.cjs +77 -62
  5. package/dist/auth/index.cjs.map +1 -1
  6. package/dist/auth/index.js +77 -62
  7. package/dist/auth/index.js.map +1 -1
  8. package/dist/auth/sdk.cjs +7 -6
  9. package/dist/auth/sdk.cjs.map +1 -1
  10. package/dist/auth/sdk.d.cts +1 -1
  11. package/dist/auth/sdk.d.ts +1 -1
  12. package/dist/auth/sdk.js +7 -6
  13. package/dist/auth/sdk.js.map +1 -1
  14. package/dist/compositions/app-user.cjs +497 -0
  15. package/dist/compositions/app-user.cjs.map +1 -0
  16. package/dist/compositions/app-user.d.cts +18 -0
  17. package/dist/compositions/app-user.d.ts +18 -0
  18. package/dist/compositions/app-user.js +469 -0
  19. package/dist/compositions/app-user.js.map +1 -0
  20. package/dist/index.cjs +932 -270
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +101 -6
  23. package/dist/index.d.ts +101 -6
  24. package/dist/index.js +891 -247
  25. package/dist/index.js.map +1 -1
  26. package/dist/modality/index.cjs +21 -18
  27. package/dist/modality/index.cjs.map +1 -1
  28. package/dist/modality/index.d.cts +6 -5
  29. package/dist/modality/index.d.ts +6 -5
  30. package/dist/modality/index.js +21 -18
  31. package/dist/modality/index.js.map +1 -1
  32. package/dist/models/index.cjs +508 -0
  33. package/dist/models/index.cjs.map +1 -0
  34. package/dist/models/index.d.cts +22 -0
  35. package/dist/models/index.d.ts +22 -0
  36. package/dist/models/index.js +486 -0
  37. package/dist/models/index.js.map +1 -0
  38. package/dist/styles.css +1 -1
  39. package/dist/wallet/index.cjs +13 -4
  40. package/dist/wallet/index.cjs.map +1 -1
  41. package/dist/wallet/index.js +13 -4
  42. package/dist/wallet/index.js.map +1 -1
  43. package/dist/wallet/sdk.cjs +2 -2
  44. package/dist/wallet/sdk.cjs.map +1 -1
  45. package/dist/wallet/sdk.js +2 -2
  46. package/dist/wallet/sdk.js.map +1 -1
  47. package/package.json +17 -5
  48. package/dist/wallet.css +0 -73
package/README.md CHANGED
@@ -6,8 +6,15 @@ core primitives and display recipes stay SDK-free.
6
6
 
7
7
  ## Install
8
8
 
9
+ > [!WARNING]
10
+ > **The `alpha` line (`0.1.0-alpha.x`) is unstable and breakage-prone.** It ships the in-progress design-system rebuild (new `--polli-color-*` token system, new primitives, renamed size props `sm|md|lg`) and its API may change between alpha versions without notice. The stable `latest` line is `0.0.2`. Opt into the alpha deliberately, and pin an exact version.
11
+
9
12
  ```bash
13
+ # stable (recommended)
10
14
  npm install @pollinations/ui
15
+
16
+ # alpha (in-progress rebuild — pin exactly)
17
+ npm install @pollinations/ui@alpha
11
18
  ```
12
19
 
13
20
  Install `@pollinations/sdk` too when using `@pollinations/ui/*/sdk`
@@ -87,11 +94,8 @@ The SVG sources use `currentColor`. Apps control the rendered color by inlining
87
94
  them or using them as masks. Root-level favicon, PWA icon, and SEO files stay
88
95
  app-owned.
89
96
 
90
- Wallet-specific colors and utilities live in a separate stylesheet:
91
-
92
- ```css
93
- @import "@pollinations/ui/wallet.css";
94
- ```
97
+ Wallet colors and utilities are bundled into the main stylesheet
98
+ (`@pollinations/ui/styles.css`) — no separate import needed.
95
99
 
96
100
  ## What's exported
97
101
 
@@ -185,7 +189,7 @@ with host app tokens.
185
189
  | `--polli-text-base` | Base text size. |
186
190
  | `--polli-color-surface-white` | Translucent white surface. |
187
191
 
188
- Wallet tokens are public when `@pollinations/ui/wallet.css` is imported:
192
+ Wallet tokens are public (bundled into `@pollinations/ui/styles.css`):
189
193
 
190
194
  | Token | Purpose |
191
195
  | ----------------------------- | --------------------------------------------- |
@@ -5,9 +5,9 @@ import { T as ThemeName } from './theme-VMRlhqST.cjs';
5
5
  /** Button only supports `danger`. Label/status color recipes live on Chip. */
6
6
  type ButtonIntent = "danger";
7
7
  declare const sizes: {
8
- readonly small: "polli:px-2 polli:pt-0.5 polli:pb-1";
9
- readonly medium: "polli:px-4 polli:pt-1.5 polli:pb-2";
10
- readonly large: "polli:px-6 polli:py-3";
8
+ readonly sm: "polli:px-2 polli:pt-0.5 polli:pb-1";
9
+ readonly md: "polli:px-4 polli:pt-1.5 polli:pb-2";
10
+ readonly lg: "polli:px-6 polli:py-3";
11
11
  };
12
12
  type BaseButtonProps = {
13
13
  /** Override the cascade theme for this button's subtree. Ignored when `intent` is set. */
@@ -5,9 +5,9 @@ import { T as ThemeName } from './theme-VMRlhqST.js';
5
5
  /** Button only supports `danger`. Label/status color recipes live on Chip. */
6
6
  type ButtonIntent = "danger";
7
7
  declare const sizes: {
8
- readonly small: "polli:px-2 polli:pt-0.5 polli:pb-1";
9
- readonly medium: "polli:px-4 polli:pt-1.5 polli:pb-2";
10
- readonly large: "polli:px-6 polli:py-3";
8
+ readonly sm: "polli:px-2 polli:pt-0.5 polli:pb-1";
9
+ readonly md: "polli:px-4 polli:pt-1.5 polli:pb-2";
10
+ readonly lg: "polli:px-6 polli:py-3";
11
11
  };
12
12
  type BaseButtonProps = {
13
13
  /** Override the cascade theme for this button's subtree. Ignored when `intent` is set. */
@@ -34,6 +34,7 @@ var logo_default = 'data:image/svg+xml,<?xml version="1.0" encoding="utf-8"?>%0A
34
34
  // src/primitives/Dialog.tsx
35
35
  var import_dialog = require("@ark-ui/react/dialog");
36
36
  var import_portal = require("@ark-ui/react/portal");
37
+ var import_react = require("react");
37
38
 
38
39
  // src/lib/cn.ts
39
40
  var import_clsx = require("clsx");
@@ -67,76 +68,89 @@ var Dialog = ({
67
68
  positionerClassName,
68
69
  contentClassName,
69
70
  children
70
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
71
- import_dialog.Dialog.Root,
72
- {
73
- open,
74
- onOpenChange: (details) => onOpenChange?.(details.open),
75
- children: [
76
- trigger && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
77
- import_dialog.Dialog.Trigger,
78
- {
79
- asChild: triggerAsChild,
80
- className: triggerClassName,
81
- children: trigger
82
- }
83
- ),
84
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_portal.Portal, { children: [
85
- showBackdrop && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
86
- import_dialog.Dialog.Backdrop,
71
+ }) => {
72
+ const contentRef = (0, import_react.useRef)(null);
73
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
74
+ import_dialog.Dialog.Root,
75
+ {
76
+ open,
77
+ initialFocusEl: () => contentRef.current,
78
+ onOpenChange: (details) => onOpenChange?.(details.open),
79
+ children: [
80
+ trigger && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
81
+ import_dialog.Dialog.Trigger,
87
82
  {
88
- className: cn(
89
- "polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50",
90
- backdropClassName
91
- )
83
+ asChild: triggerAsChild,
84
+ className: triggerClassName,
85
+ children: trigger
92
86
  }
93
87
  ),
94
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
95
- import_dialog.Dialog.Positioner,
96
- {
97
- className: cn(
98
- "polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4",
99
- positionerClassName
100
- ),
101
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
102
- import_dialog.Dialog.Content,
103
- {
104
- "data-theme": theme,
105
- "aria-label": ariaLabel,
106
- "aria-labelledby": labelledBy,
107
- className: cn(
108
- "polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg",
109
- sizeClasses[size],
110
- contentClassName
111
- ),
112
- children: [
113
- title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
114
- DialogTitle,
115
- {
116
- className: cn(
117
- "polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong",
118
- titleClassName
119
- ),
120
- children: title
121
- }
88
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_portal.Portal, { children: [
89
+ showBackdrop && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
90
+ import_dialog.Dialog.Backdrop,
91
+ {
92
+ className: cn(
93
+ "polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50",
94
+ backdropClassName
95
+ )
96
+ }
97
+ ),
98
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
99
+ import_dialog.Dialog.Positioner,
100
+ {
101
+ "data-theme": theme,
102
+ className: cn(
103
+ "polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4",
104
+ positionerClassName
105
+ ),
106
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
107
+ import_dialog.Dialog.Content,
108
+ {
109
+ ref: contentRef,
110
+ "data-theme": theme,
111
+ "aria-label": ariaLabel,
112
+ "aria-labelledby": labelledBy,
113
+ className: cn(
114
+ "polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg polli:outline-none polli:focus:outline-none polli:focus-visible:outline-none",
115
+ sizeClasses[size],
116
+ contentClassName
122
117
  ),
123
- children
124
- ]
125
- }
126
- )
127
- }
128
- )
129
- ] })
130
- ]
131
- }
132
- );
118
+ children: [
119
+ title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
120
+ DialogTitle,
121
+ {
122
+ className: cn(
123
+ "polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong",
124
+ titleClassName
125
+ ),
126
+ children: title
127
+ }
128
+ ),
129
+ children
130
+ ]
131
+ }
132
+ )
133
+ }
134
+ )
135
+ ] })
136
+ ]
137
+ }
138
+ );
139
+ };
133
140
  var DialogTitle = import_dialog.Dialog.Title;
134
141
 
135
142
  // src/modules/auth/AuthModal.tsx
136
143
  var import_jsx_runtime2 = require("react/jsx-runtime");
144
+ var authLogoMaskUrl = `url('${logo_default}')`;
137
145
  var authLogoMask = {
138
- WebkitMask: `url(${logo_default}) center / contain no-repeat`,
139
- mask: `url(${logo_default}) center / contain no-repeat`
146
+ WebkitMaskImage: authLogoMaskUrl,
147
+ WebkitMaskPosition: "center",
148
+ WebkitMaskRepeat: "no-repeat",
149
+ WebkitMaskSize: "contain",
150
+ maskImage: authLogoMaskUrl,
151
+ maskPosition: "center",
152
+ maskRepeat: "no-repeat",
153
+ maskSize: "contain"
140
154
  };
141
155
  function AuthModal({
142
156
  children,
@@ -165,7 +179,8 @@ function AuthModalHeader({ children }) {
165
179
  href: "https://pollinations.ai",
166
180
  target: "_blank",
167
181
  rel: "noopener noreferrer",
168
- className: "polli:block polli:shrink-0 polli:text-theme-text-strong",
182
+ tabIndex: -1,
183
+ className: "polli:block polli:shrink-0 polli:text-theme-text-strong polli:focus:outline-none",
169
184
  "aria-label": "pollinations.ai",
170
185
  children: [
171
186
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "polli:sr-only", children: "pollinations.ai" }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/modules/auth/index.ts","../../src/primitives/Dialog.tsx","../../src/lib/cn.ts","../../src/modules/auth/AuthModal.tsx"],"sourcesContent":["export {\n AuthInfoCard,\n type AuthInfoCardProps,\n AuthModal,\n AuthModalHeader,\n type AuthModalHeaderProps,\n AuthModalLoading,\n type AuthModalProps,\n ErrorBanner,\n} from \"./AuthModal.tsx\";\n","import { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst sizeClasses = {\n sm: \"polli:max-w-md\",\n md: \"polli:max-w-xl\",\n lg: \"polli:max-w-2xl\",\n} as const;\n\nexport type DialogProps = {\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: ReactNode;\n triggerAsChild?: boolean;\n triggerClassName?: string;\n title?: ReactNode;\n titleClassName?: string;\n ariaLabel?: string;\n labelledBy?: string;\n theme?: ThemeName;\n size?: keyof typeof sizeClasses;\n showBackdrop?: boolean;\n backdropClassName?: string;\n positionerClassName?: string;\n contentClassName?: string;\n children: ReactNode;\n};\n\nexport const Dialog: FC<DialogProps> = ({\n open,\n onOpenChange,\n trigger,\n triggerAsChild = false,\n triggerClassName,\n title,\n titleClassName,\n ariaLabel,\n labelledBy,\n theme = \"blue\",\n size = \"md\",\n showBackdrop = true,\n backdropClassName,\n positionerClassName,\n contentClassName,\n children,\n}) => (\n <ArkDialog.Root\n open={open}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n >\n {trigger && (\n <ArkDialog.Trigger\n asChild={triggerAsChild}\n className={triggerClassName}\n >\n {trigger}\n </ArkDialog.Trigger>\n )}\n <Portal>\n {showBackdrop && (\n <ArkDialog.Backdrop\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50\",\n backdropClassName,\n )}\n />\n )}\n <ArkDialog.Positioner\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4\",\n positionerClassName,\n )}\n >\n <ArkDialog.Content\n data-theme={theme}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n className={cn(\n \"polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg\",\n sizeClasses[size],\n contentClassName,\n )}\n >\n {title && (\n <DialogTitle\n className={cn(\n \"polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong\",\n titleClassName,\n )}\n >\n {title}\n </DialogTitle>\n )}\n {children}\n </ArkDialog.Content>\n </ArkDialog.Positioner>\n </Portal>\n </ArkDialog.Root>\n);\n\nexport const DialogTitle = ArkDialog.Title;\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 { CSSProperties, ReactNode } from \"react\";\nimport logoUrl from \"../../assets/logo.svg\";\nimport { Dialog } from \"../../primitives/Dialog.tsx\";\n\nconst authLogoMask: CSSProperties = {\n WebkitMask: `url(${logoUrl}) center / contain no-repeat`,\n mask: `url(${logoUrl}) center / contain no-repeat`,\n};\n\nexport type AuthModalProps = {\n children: ReactNode;\n dialog?: {\n label?: string;\n labelledBy?: string;\n };\n tone?: \"default\" | \"error\";\n};\n\nexport function AuthModal({\n children,\n dialog,\n tone = \"default\",\n}: AuthModalProps) {\n const borderClass =\n tone === \"error\"\n ? \"polli:border-intent-danger-border\"\n : \"polli:border-theme-border\";\n return (\n <Dialog\n open\n theme=\"amber\"\n showBackdrop={false}\n ariaLabel={dialog?.label}\n labelledBy={dialog?.labelledBy}\n positionerClassName=\"polli:items-start polli:overflow-y-auto polli:bg-theme-bg-pale\"\n contentClassName={`polli:bg-surface-white polli:border-2 ${borderClass} polli:rounded-lg polli:shadow-lg polli:max-w-xl polli:w-full polli:my-auto`}\n >\n {children}\n </Dialog>\n );\n}\n\nexport type AuthModalHeaderProps = {\n children?: ReactNode;\n};\n\nexport function AuthModalHeader({ children }: AuthModalHeaderProps) {\n const logo = (\n <a\n href=\"https://pollinations.ai\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"polli:block polli:shrink-0 polli:text-theme-text-strong\"\n aria-label=\"pollinations.ai\"\n >\n <span className=\"polli:sr-only\">pollinations.ai</span>\n <span\n aria-hidden=\"true\"\n className=\"polli:block polli:h-8 polli:w-8 polli:bg-current\"\n style={authLogoMask}\n />\n </a>\n );\n if (!children) {\n return (\n <div className=\"polli:flex polli:justify-start polli:px-6 polli:pt-6\">\n {logo}\n </div>\n );\n }\n return (\n <div className=\"polli:px-6 polli:pt-6 polli:pb-2\">\n <div className=\"polli:flex polli:items-center polli:justify-between polli:gap-3\">\n {logo}\n {children}\n </div>\n </div>\n );\n}\n\nexport function AuthModalLoading() {\n return (\n <AuthModal>\n <AuthModalHeader />\n <div className=\"polli:px-8 polli:pt-2 polli:pb-8 polli:text-center\">\n <p className=\"polli:text-theme-text-strong\">Loading...</p>\n </div>\n </AuthModal>\n );\n}\n\nexport function ErrorBanner({ children }: { children: ReactNode }) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:p-4\">\n <p className=\"polli:text-sm polli:text-intent-danger-text\">\n {children}\n </p>\n </div>\n );\n}\n\nexport type AuthInfoCardProps = {\n title?: string;\n children: ReactNode;\n};\n\nexport function AuthInfoCard({\n title = \"Authorize\",\n children,\n}: AuthInfoCardProps) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-theme-bg-pale polli:p-4\">\n <p className=\"polli:mb-2 polli:font-body polli:text-xs polli:font-semibold polli:tracking-wide polli:text-theme-text-soft\">\n {title}\n </p>\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":["ArkDialog","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/modules/auth/index.ts","../../src/primitives/Dialog.tsx","../../src/lib/cn.ts","../../src/modules/auth/AuthModal.tsx"],"sourcesContent":["export {\n AuthInfoCard,\n type AuthInfoCardProps,\n AuthModal,\n AuthModalHeader,\n type AuthModalHeaderProps,\n AuthModalLoading,\n type AuthModalProps,\n ErrorBanner,\n} from \"./AuthModal.tsx\";\n","import { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { useRef } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst sizeClasses = {\n sm: \"polli:max-w-md\",\n md: \"polli:max-w-xl\",\n lg: \"polli:max-w-2xl\",\n} as const;\n\nexport type DialogProps = {\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: ReactNode;\n triggerAsChild?: boolean;\n triggerClassName?: string;\n title?: ReactNode;\n titleClassName?: string;\n ariaLabel?: string;\n labelledBy?: string;\n theme?: ThemeName;\n size?: keyof typeof sizeClasses;\n showBackdrop?: boolean;\n backdropClassName?: string;\n positionerClassName?: string;\n contentClassName?: string;\n children: ReactNode;\n};\n\nexport const Dialog: FC<DialogProps> = ({\n open,\n onOpenChange,\n trigger,\n triggerAsChild = false,\n triggerClassName,\n title,\n titleClassName,\n ariaLabel,\n labelledBy,\n theme = \"blue\",\n size = \"md\",\n showBackdrop = true,\n backdropClassName,\n positionerClassName,\n contentClassName,\n children,\n}) => {\n const contentRef = useRef<HTMLDivElement>(null);\n\n return (\n <ArkDialog.Root\n open={open}\n initialFocusEl={() => contentRef.current}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n >\n {trigger && (\n <ArkDialog.Trigger\n asChild={triggerAsChild}\n className={triggerClassName}\n >\n {trigger}\n </ArkDialog.Trigger>\n )}\n <Portal>\n {showBackdrop && (\n <ArkDialog.Backdrop\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50\",\n backdropClassName,\n )}\n />\n )}\n <ArkDialog.Positioner\n data-theme={theme}\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4\",\n positionerClassName,\n )}\n >\n <ArkDialog.Content\n ref={contentRef}\n data-theme={theme}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n className={cn(\n \"polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg polli:outline-none polli:focus:outline-none polli:focus-visible:outline-none\",\n sizeClasses[size],\n contentClassName,\n )}\n >\n {title && (\n <DialogTitle\n className={cn(\n \"polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong\",\n titleClassName,\n )}\n >\n {title}\n </DialogTitle>\n )}\n {children}\n </ArkDialog.Content>\n </ArkDialog.Positioner>\n </Portal>\n </ArkDialog.Root>\n );\n};\n\nexport const DialogTitle = ArkDialog.Title;\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 { CSSProperties, ReactNode } from \"react\";\nimport logoUrl from \"../../assets/logo.svg\";\nimport { Dialog } from \"../../primitives/Dialog.tsx\";\n\nconst authLogoMaskUrl = `url('${logoUrl}')`;\n\nconst authLogoMask: CSSProperties = {\n WebkitMaskImage: authLogoMaskUrl,\n WebkitMaskPosition: \"center\",\n WebkitMaskRepeat: \"no-repeat\",\n WebkitMaskSize: \"contain\",\n maskImage: authLogoMaskUrl,\n maskPosition: \"center\",\n maskRepeat: \"no-repeat\",\n maskSize: \"contain\",\n};\n\nexport type AuthModalProps = {\n children: ReactNode;\n dialog?: {\n label?: string;\n labelledBy?: string;\n };\n tone?: \"default\" | \"error\";\n};\n\nexport function AuthModal({\n children,\n dialog,\n tone = \"default\",\n}: AuthModalProps) {\n const borderClass =\n tone === \"error\"\n ? \"polli:border-intent-danger-border\"\n : \"polli:border-theme-border\";\n return (\n <Dialog\n open\n theme=\"amber\"\n showBackdrop={false}\n ariaLabel={dialog?.label}\n labelledBy={dialog?.labelledBy}\n positionerClassName=\"polli:items-start polli:overflow-y-auto polli:bg-theme-bg-pale\"\n contentClassName={`polli:bg-surface-white polli:border-2 ${borderClass} polli:rounded-lg polli:shadow-lg polli:max-w-xl polli:w-full polli:my-auto`}\n >\n {children}\n </Dialog>\n );\n}\n\nexport type AuthModalHeaderProps = {\n children?: ReactNode;\n};\n\nexport function AuthModalHeader({ children }: AuthModalHeaderProps) {\n const logo = (\n <a\n href=\"https://pollinations.ai\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n tabIndex={-1}\n className=\"polli:block polli:shrink-0 polli:text-theme-text-strong polli:focus:outline-none\"\n aria-label=\"pollinations.ai\"\n >\n <span className=\"polli:sr-only\">pollinations.ai</span>\n <span\n aria-hidden=\"true\"\n className=\"polli:block polli:h-8 polli:w-8 polli:bg-current\"\n style={authLogoMask}\n />\n </a>\n );\n if (!children) {\n return (\n <div className=\"polli:flex polli:justify-start polli:px-6 polli:pt-6\">\n {logo}\n </div>\n );\n }\n return (\n <div className=\"polli:px-6 polli:pt-6 polli:pb-2\">\n <div className=\"polli:flex polli:items-center polli:justify-between polli:gap-3\">\n {logo}\n {children}\n </div>\n </div>\n );\n}\n\nexport function AuthModalLoading() {\n return (\n <AuthModal>\n <AuthModalHeader />\n <div className=\"polli:px-8 polli:pt-2 polli:pb-8 polli:text-center\">\n <p className=\"polli:text-theme-text-strong\">Loading...</p>\n </div>\n </AuthModal>\n );\n}\n\nexport function ErrorBanner({ children }: { children: ReactNode }) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:p-4\">\n <p className=\"polli:text-sm polli:text-intent-danger-text\">\n {children}\n </p>\n </div>\n );\n}\n\nexport type AuthInfoCardProps = {\n title?: string;\n children: ReactNode;\n};\n\nexport function AuthInfoCard({\n title = \"Authorize\",\n children,\n}: AuthInfoCardProps) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-theme-bg-pale polli:p-4\">\n <p className=\"polli:mb-2 polli:font-body polli:text-xs polli:font-semibold polli:tracking-wide polli:text-theme-text-soft\">\n {title}\n </p>\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":["ArkDialog","import_jsx_runtime"]}
@@ -4,6 +4,7 @@ var logo_default = 'data:image/svg+xml,<?xml version="1.0" encoding="utf-8"?>%0A
4
4
  // src/primitives/Dialog.tsx
5
5
  import { Dialog as ArkDialog } from "@ark-ui/react/dialog";
6
6
  import { Portal } from "@ark-ui/react/portal";
7
+ import { useRef } from "react";
7
8
 
8
9
  // src/lib/cn.ts
9
10
  import { clsx } from "clsx";
@@ -37,76 +38,89 @@ var Dialog = ({
37
38
  positionerClassName,
38
39
  contentClassName,
39
40
  children
40
- }) => /* @__PURE__ */ jsxs(
41
- ArkDialog.Root,
42
- {
43
- open,
44
- onOpenChange: (details) => onOpenChange?.(details.open),
45
- children: [
46
- trigger && /* @__PURE__ */ jsx(
47
- ArkDialog.Trigger,
48
- {
49
- asChild: triggerAsChild,
50
- className: triggerClassName,
51
- children: trigger
52
- }
53
- ),
54
- /* @__PURE__ */ jsxs(Portal, { children: [
55
- showBackdrop && /* @__PURE__ */ jsx(
56
- ArkDialog.Backdrop,
41
+ }) => {
42
+ const contentRef = useRef(null);
43
+ return /* @__PURE__ */ jsxs(
44
+ ArkDialog.Root,
45
+ {
46
+ open,
47
+ initialFocusEl: () => contentRef.current,
48
+ onOpenChange: (details) => onOpenChange?.(details.open),
49
+ children: [
50
+ trigger && /* @__PURE__ */ jsx(
51
+ ArkDialog.Trigger,
57
52
  {
58
- className: cn(
59
- "polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50",
60
- backdropClassName
61
- )
53
+ asChild: triggerAsChild,
54
+ className: triggerClassName,
55
+ children: trigger
62
56
  }
63
57
  ),
64
- /* @__PURE__ */ jsx(
65
- ArkDialog.Positioner,
66
- {
67
- className: cn(
68
- "polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4",
69
- positionerClassName
70
- ),
71
- children: /* @__PURE__ */ jsxs(
72
- ArkDialog.Content,
73
- {
74
- "data-theme": theme,
75
- "aria-label": ariaLabel,
76
- "aria-labelledby": labelledBy,
77
- className: cn(
78
- "polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg",
79
- sizeClasses[size],
80
- contentClassName
81
- ),
82
- children: [
83
- title && /* @__PURE__ */ jsx(
84
- DialogTitle,
85
- {
86
- className: cn(
87
- "polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong",
88
- titleClassName
89
- ),
90
- children: title
91
- }
58
+ /* @__PURE__ */ jsxs(Portal, { children: [
59
+ showBackdrop && /* @__PURE__ */ jsx(
60
+ ArkDialog.Backdrop,
61
+ {
62
+ className: cn(
63
+ "polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50",
64
+ backdropClassName
65
+ )
66
+ }
67
+ ),
68
+ /* @__PURE__ */ jsx(
69
+ ArkDialog.Positioner,
70
+ {
71
+ "data-theme": theme,
72
+ className: cn(
73
+ "polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4",
74
+ positionerClassName
75
+ ),
76
+ children: /* @__PURE__ */ jsxs(
77
+ ArkDialog.Content,
78
+ {
79
+ ref: contentRef,
80
+ "data-theme": theme,
81
+ "aria-label": ariaLabel,
82
+ "aria-labelledby": labelledBy,
83
+ className: cn(
84
+ "polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg polli:outline-none polli:focus:outline-none polli:focus-visible:outline-none",
85
+ sizeClasses[size],
86
+ contentClassName
92
87
  ),
93
- children
94
- ]
95
- }
96
- )
97
- }
98
- )
99
- ] })
100
- ]
101
- }
102
- );
88
+ children: [
89
+ title && /* @__PURE__ */ jsx(
90
+ DialogTitle,
91
+ {
92
+ className: cn(
93
+ "polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong",
94
+ titleClassName
95
+ ),
96
+ children: title
97
+ }
98
+ ),
99
+ children
100
+ ]
101
+ }
102
+ )
103
+ }
104
+ )
105
+ ] })
106
+ ]
107
+ }
108
+ );
109
+ };
103
110
  var DialogTitle = ArkDialog.Title;
104
111
 
105
112
  // src/modules/auth/AuthModal.tsx
106
113
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
114
+ var authLogoMaskUrl = `url('${logo_default}')`;
107
115
  var authLogoMask = {
108
- WebkitMask: `url(${logo_default}) center / contain no-repeat`,
109
- mask: `url(${logo_default}) center / contain no-repeat`
116
+ WebkitMaskImage: authLogoMaskUrl,
117
+ WebkitMaskPosition: "center",
118
+ WebkitMaskRepeat: "no-repeat",
119
+ WebkitMaskSize: "contain",
120
+ maskImage: authLogoMaskUrl,
121
+ maskPosition: "center",
122
+ maskRepeat: "no-repeat",
123
+ maskSize: "contain"
110
124
  };
111
125
  function AuthModal({
112
126
  children,
@@ -135,7 +149,8 @@ function AuthModalHeader({ children }) {
135
149
  href: "https://pollinations.ai",
136
150
  target: "_blank",
137
151
  rel: "noopener noreferrer",
138
- className: "polli:block polli:shrink-0 polli:text-theme-text-strong",
152
+ tabIndex: -1,
153
+ className: "polli:block polli:shrink-0 polli:text-theme-text-strong polli:focus:outline-none",
139
154
  "aria-label": "pollinations.ai",
140
155
  children: [
141
156
  /* @__PURE__ */ jsx2("span", { className: "polli:sr-only", children: "pollinations.ai" }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/primitives/Dialog.tsx","../../src/lib/cn.ts","../../src/modules/auth/AuthModal.tsx"],"sourcesContent":["import { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst sizeClasses = {\n sm: \"polli:max-w-md\",\n md: \"polli:max-w-xl\",\n lg: \"polli:max-w-2xl\",\n} as const;\n\nexport type DialogProps = {\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: ReactNode;\n triggerAsChild?: boolean;\n triggerClassName?: string;\n title?: ReactNode;\n titleClassName?: string;\n ariaLabel?: string;\n labelledBy?: string;\n theme?: ThemeName;\n size?: keyof typeof sizeClasses;\n showBackdrop?: boolean;\n backdropClassName?: string;\n positionerClassName?: string;\n contentClassName?: string;\n children: ReactNode;\n};\n\nexport const Dialog: FC<DialogProps> = ({\n open,\n onOpenChange,\n trigger,\n triggerAsChild = false,\n triggerClassName,\n title,\n titleClassName,\n ariaLabel,\n labelledBy,\n theme = \"blue\",\n size = \"md\",\n showBackdrop = true,\n backdropClassName,\n positionerClassName,\n contentClassName,\n children,\n}) => (\n <ArkDialog.Root\n open={open}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n >\n {trigger && (\n <ArkDialog.Trigger\n asChild={triggerAsChild}\n className={triggerClassName}\n >\n {trigger}\n </ArkDialog.Trigger>\n )}\n <Portal>\n {showBackdrop && (\n <ArkDialog.Backdrop\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50\",\n backdropClassName,\n )}\n />\n )}\n <ArkDialog.Positioner\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4\",\n positionerClassName,\n )}\n >\n <ArkDialog.Content\n data-theme={theme}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n className={cn(\n \"polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg\",\n sizeClasses[size],\n contentClassName,\n )}\n >\n {title && (\n <DialogTitle\n className={cn(\n \"polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong\",\n titleClassName,\n )}\n >\n {title}\n </DialogTitle>\n )}\n {children}\n </ArkDialog.Content>\n </ArkDialog.Positioner>\n </Portal>\n </ArkDialog.Root>\n);\n\nexport const DialogTitle = ArkDialog.Title;\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 { CSSProperties, ReactNode } from \"react\";\nimport logoUrl from \"../../assets/logo.svg\";\nimport { Dialog } from \"../../primitives/Dialog.tsx\";\n\nconst authLogoMask: CSSProperties = {\n WebkitMask: `url(${logoUrl}) center / contain no-repeat`,\n mask: `url(${logoUrl}) center / contain no-repeat`,\n};\n\nexport type AuthModalProps = {\n children: ReactNode;\n dialog?: {\n label?: string;\n labelledBy?: string;\n };\n tone?: \"default\" | \"error\";\n};\n\nexport function AuthModal({\n children,\n dialog,\n tone = \"default\",\n}: AuthModalProps) {\n const borderClass =\n tone === \"error\"\n ? \"polli:border-intent-danger-border\"\n : \"polli:border-theme-border\";\n return (\n <Dialog\n open\n theme=\"amber\"\n showBackdrop={false}\n ariaLabel={dialog?.label}\n labelledBy={dialog?.labelledBy}\n positionerClassName=\"polli:items-start polli:overflow-y-auto polli:bg-theme-bg-pale\"\n contentClassName={`polli:bg-surface-white polli:border-2 ${borderClass} polli:rounded-lg polli:shadow-lg polli:max-w-xl polli:w-full polli:my-auto`}\n >\n {children}\n </Dialog>\n );\n}\n\nexport type AuthModalHeaderProps = {\n children?: ReactNode;\n};\n\nexport function AuthModalHeader({ children }: AuthModalHeaderProps) {\n const logo = (\n <a\n href=\"https://pollinations.ai\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"polli:block polli:shrink-0 polli:text-theme-text-strong\"\n aria-label=\"pollinations.ai\"\n >\n <span className=\"polli:sr-only\">pollinations.ai</span>\n <span\n aria-hidden=\"true\"\n className=\"polli:block polli:h-8 polli:w-8 polli:bg-current\"\n style={authLogoMask}\n />\n </a>\n );\n if (!children) {\n return (\n <div className=\"polli:flex polli:justify-start polli:px-6 polli:pt-6\">\n {logo}\n </div>\n );\n }\n return (\n <div className=\"polli:px-6 polli:pt-6 polli:pb-2\">\n <div className=\"polli:flex polli:items-center polli:justify-between polli:gap-3\">\n {logo}\n {children}\n </div>\n </div>\n );\n}\n\nexport function AuthModalLoading() {\n return (\n <AuthModal>\n <AuthModalHeader />\n <div className=\"polli:px-8 polli:pt-2 polli:pb-8 polli:text-center\">\n <p className=\"polli:text-theme-text-strong\">Loading...</p>\n </div>\n </AuthModal>\n );\n}\n\nexport function ErrorBanner({ children }: { children: ReactNode }) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:p-4\">\n <p className=\"polli:text-sm polli:text-intent-danger-text\">\n {children}\n </p>\n </div>\n );\n}\n\nexport type AuthInfoCardProps = {\n title?: string;\n children: ReactNode;\n};\n\nexport function AuthInfoCard({\n title = \"Authorize\",\n children,\n}: AuthInfoCardProps) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-theme-bg-pale polli:p-4\">\n <p className=\"polli:mb-2 polli:font-body polli:text-xs polli:font-semibold polli:tracking-wide polli:text-theme-text-soft\">\n {title}\n </p>\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
1
+ {"version":3,"sources":["../../src/primitives/Dialog.tsx","../../src/lib/cn.ts","../../src/modules/auth/AuthModal.tsx"],"sourcesContent":["import { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { useRef } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst sizeClasses = {\n sm: \"polli:max-w-md\",\n md: \"polli:max-w-xl\",\n lg: \"polli:max-w-2xl\",\n} as const;\n\nexport type DialogProps = {\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: ReactNode;\n triggerAsChild?: boolean;\n triggerClassName?: string;\n title?: ReactNode;\n titleClassName?: string;\n ariaLabel?: string;\n labelledBy?: string;\n theme?: ThemeName;\n size?: keyof typeof sizeClasses;\n showBackdrop?: boolean;\n backdropClassName?: string;\n positionerClassName?: string;\n contentClassName?: string;\n children: ReactNode;\n};\n\nexport const Dialog: FC<DialogProps> = ({\n open,\n onOpenChange,\n trigger,\n triggerAsChild = false,\n triggerClassName,\n title,\n titleClassName,\n ariaLabel,\n labelledBy,\n theme = \"blue\",\n size = \"md\",\n showBackdrop = true,\n backdropClassName,\n positionerClassName,\n contentClassName,\n children,\n}) => {\n const contentRef = useRef<HTMLDivElement>(null);\n\n return (\n <ArkDialog.Root\n open={open}\n initialFocusEl={() => contentRef.current}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n >\n {trigger && (\n <ArkDialog.Trigger\n asChild={triggerAsChild}\n className={triggerClassName}\n >\n {trigger}\n </ArkDialog.Trigger>\n )}\n <Portal>\n {showBackdrop && (\n <ArkDialog.Backdrop\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50\",\n backdropClassName,\n )}\n />\n )}\n <ArkDialog.Positioner\n data-theme={theme}\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4\",\n positionerClassName,\n )}\n >\n <ArkDialog.Content\n ref={contentRef}\n data-theme={theme}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n className={cn(\n \"polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg polli:outline-none polli:focus:outline-none polli:focus-visible:outline-none\",\n sizeClasses[size],\n contentClassName,\n )}\n >\n {title && (\n <DialogTitle\n className={cn(\n \"polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong\",\n titleClassName,\n )}\n >\n {title}\n </DialogTitle>\n )}\n {children}\n </ArkDialog.Content>\n </ArkDialog.Positioner>\n </Portal>\n </ArkDialog.Root>\n );\n};\n\nexport const DialogTitle = ArkDialog.Title;\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 { CSSProperties, ReactNode } from \"react\";\nimport logoUrl from \"../../assets/logo.svg\";\nimport { Dialog } from \"../../primitives/Dialog.tsx\";\n\nconst authLogoMaskUrl = `url('${logoUrl}')`;\n\nconst authLogoMask: CSSProperties = {\n WebkitMaskImage: authLogoMaskUrl,\n WebkitMaskPosition: \"center\",\n WebkitMaskRepeat: \"no-repeat\",\n WebkitMaskSize: \"contain\",\n maskImage: authLogoMaskUrl,\n maskPosition: \"center\",\n maskRepeat: \"no-repeat\",\n maskSize: \"contain\",\n};\n\nexport type AuthModalProps = {\n children: ReactNode;\n dialog?: {\n label?: string;\n labelledBy?: string;\n };\n tone?: \"default\" | \"error\";\n};\n\nexport function AuthModal({\n children,\n dialog,\n tone = \"default\",\n}: AuthModalProps) {\n const borderClass =\n tone === \"error\"\n ? \"polli:border-intent-danger-border\"\n : \"polli:border-theme-border\";\n return (\n <Dialog\n open\n theme=\"amber\"\n showBackdrop={false}\n ariaLabel={dialog?.label}\n labelledBy={dialog?.labelledBy}\n positionerClassName=\"polli:items-start polli:overflow-y-auto polli:bg-theme-bg-pale\"\n contentClassName={`polli:bg-surface-white polli:border-2 ${borderClass} polli:rounded-lg polli:shadow-lg polli:max-w-xl polli:w-full polli:my-auto`}\n >\n {children}\n </Dialog>\n );\n}\n\nexport type AuthModalHeaderProps = {\n children?: ReactNode;\n};\n\nexport function AuthModalHeader({ children }: AuthModalHeaderProps) {\n const logo = (\n <a\n href=\"https://pollinations.ai\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n tabIndex={-1}\n className=\"polli:block polli:shrink-0 polli:text-theme-text-strong polli:focus:outline-none\"\n aria-label=\"pollinations.ai\"\n >\n <span className=\"polli:sr-only\">pollinations.ai</span>\n <span\n aria-hidden=\"true\"\n className=\"polli:block polli:h-8 polli:w-8 polli:bg-current\"\n style={authLogoMask}\n />\n </a>\n );\n if (!children) {\n return (\n <div className=\"polli:flex polli:justify-start polli:px-6 polli:pt-6\">\n {logo}\n </div>\n );\n }\n return (\n <div className=\"polli:px-6 polli:pt-6 polli:pb-2\">\n <div className=\"polli:flex polli:items-center polli:justify-between polli:gap-3\">\n {logo}\n {children}\n </div>\n </div>\n );\n}\n\nexport function AuthModalLoading() {\n return (\n <AuthModal>\n <AuthModalHeader />\n <div className=\"polli:px-8 polli:pt-2 polli:pb-8 polli:text-center\">\n <p className=\"polli:text-theme-text-strong\">Loading...</p>\n </div>\n </AuthModal>\n );\n}\n\nexport function ErrorBanner({ children }: { children: ReactNode }) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:p-4\">\n <p className=\"polli:text-sm polli:text-intent-danger-text\">\n {children}\n </p>\n </div>\n );\n}\n\nexport type AuthInfoCardProps = {\n title?: string;\n children: ReactNode;\n};\n\nexport function AuthInfoCard({\n title = \"Authorize\",\n children,\n}: AuthInfoCardProps) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-theme-bg-pale polli:p-4\">\n <p className=\"polli:mb-2 polli:font-body polli:text-xs polli:font-semibold polli:tracking-wide polli:text-theme-text-soft\">\n {title}\n </p>\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
package/dist/auth/sdk.cjs CHANGED
@@ -44,13 +44,13 @@ function cn(...inputs) {
44
44
  // src/primitives/Button.tsx
45
45
  var import_jsx_runtime = require("react/jsx-runtime");
46
46
  var sizes = {
47
- small: "polli:px-2 polli:pt-0.5 polli:pb-1",
48
- medium: "polli:px-4 polli:pt-1.5 polli:pb-2",
49
- large: "polli:px-6 polli:py-3"
47
+ sm: "polli:px-2 polli:pt-0.5 polli:pb-1",
48
+ md: "polli:px-4 polli:pt-1.5 polli:pb-2",
49
+ lg: "polli:px-6 polli:py-3"
50
50
  };
51
51
  var themeClasses = "polli:bg-theme-bg-active polli:text-theme-text-base polli:hover:bg-theme-bg-hover polli:transition-colors";
52
52
  var intentClasses = {
53
- danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-[oklch(0.88_0.075_25)] polli:transition-colors"
53
+ danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text polli:hover:bg-intent-danger-bg-hover polli:transition-colors"
54
54
  };
55
55
  var buttonClasses = ({
56
56
  theme: _theme,
@@ -61,10 +61,10 @@ var buttonClasses = ({
61
61
  }) => {
62
62
  const colorClasses = intent ? intentClasses[intent] : themeClasses;
63
63
  return cn(
64
- "polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:placeholder-green-950 polli:font-medium polli:leading-normal polli:box-border",
64
+ "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",
65
65
  disabled ? "polli:opacity-50 polli:cursor-not-allowed" : "polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer",
66
66
  colorClasses,
67
- sizes[size || "medium"],
67
+ sizes[size || "md"],
68
68
  className
69
69
  );
70
70
  };
@@ -83,6 +83,7 @@ function Button({
83
83
  Component,
84
84
  {
85
85
  "data-theme": intent ? void 0 : theme,
86
+ "data-intent": intent,
86
87
  className: buttonClasses({
87
88
  theme,
88
89
  intent,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/modules/auth/sdk.ts","../../src/modules/auth/LoginButton.tsx","../../src/lib/cn.ts","../../src/primitives/Button.tsx","../../src/modules/auth/LogoutButton.tsx","../../src/modules/auth/UserAvatar.tsx","../../src/modules/auth/UserEmail.tsx","../../src/modules/auth/UserName.tsx","../../src/modules/auth/WhenLoggedIn.tsx","../../src/modules/auth/WhenLoggedOut.tsx"],"sourcesContent":["export { LoginButton, type LoginButtonProps } from \"./LoginButton.tsx\";\nexport { LogoutButton, type LogoutButtonProps } from \"./LogoutButton.tsx\";\nexport { UserAvatar, type UserAvatarProps } from \"./UserAvatar.tsx\";\nexport { UserEmail, type UserEmailProps } from \"./UserEmail.tsx\";\nexport { UserName, type UserNameProps } from \"./UserName.tsx\";\nexport { WhenLoggedIn, type WhenLoggedInProps } from \"./WhenLoggedIn.tsx\";\nexport { WhenLoggedOut, type WhenLoggedOutProps } from \"./WhenLoggedOut.tsx\";\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 { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Button only supports `danger`. Label/status color recipes live on Chip. */\ntype ButtonIntent = \"danger\";\n\nconst sizes = {\n small: \"polli:px-2 polli:pt-0.5 polli:pb-1\",\n medium: \"polli:px-4 polli:pt-1.5 polli:pb-2\",\n large: \"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-[oklch(0.88_0.075_25)] 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:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:placeholder-green-950 polli:font-medium polli:leading-normal polli:box-border\",\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 || \"medium\"],\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 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 { useAuthActions, useAuthState } from \"@pollinations/sdk/react\";\nimport type { ReactNode } from \"react\";\nimport { Button, type ButtonProps } from \"../../primitives/Button.tsx\";\n\nexport type LogoutButtonProps = Omit<\n ButtonProps<\"button\">,\n \"as\" | \"onClick\" | \"children\"\n> & {\n children: ReactNode;\n};\n\n/** Button that clears the session. `null` when logged out. */\nexport function LogoutButton({ children, ...buttonProps }: LogoutButtonProps) {\n const { isLoggedIn } = useAuthState();\n const { logout } = useAuthActions();\n if (!isLoggedIn) return null;\n return (\n <Button {...buttonProps} onClick={() => logout()}>\n {children}\n </Button>\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 UserEmailProps = { className?: string };\n\n/** Renders `profile.email`. `null` when logged out or the key lacks `profile` scope. */\nexport function UserEmail({ className }: UserEmailProps) {\n const { isLoggedIn } = useAuthState();\n const { data: profile } = useAccountProfile({ enabled: isLoggedIn });\n if (!isLoggedIn || !profile?.email) return null;\n return (\n <span data-polli=\"user-email\" className={className}>\n {profile.email}\n </span>\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAA6C;;;ACA7C,kBAAqB;AACrB,4BAAoC;AAEpC,IAAM,cAAU,2CAAoB,EAAE,QAAQ,QAAQ,CAAC;AAGhD,SAAS,MAAM,QAA+C;AACjE,SAAO,YAAQ,kBAAK,GAAG,MAAM,CAAC;AAClC;;;ACiEQ;AAlER,IAAM,QAAQ;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACX;AAGA,IAAM,eACF;AAKJ,IAAM,gBAA8C;AAAA,EAChD,QACI;AAER;AAYA,IAAM,gBAAgB,CAAC;AAAA,EACnB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,MAAgD;AAC5C,QAAM,eAAe,SAAS,cAAc,MAAM,IAAI;AACtD,SAAO;AAAA,IACH;AAAA,IACA,WACM,8CACA;AAAA,IACN;AAAA,IACA,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EACJ;AACJ;AAOO,SAAS,OAA+C;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACP,GAAmB;AACf,QAAM,YAA+B,MAAM;AAE3C,SACI;AAAA,IAAC;AAAA;AAAA,MAEG,cAAY,SAAS,SAAY;AAAA,MACjC,WAAW,cAAc;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACJ,CAAC;AAAA,MACD;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACL;AAER;;;AFxEQ,IAAAA,sBAAA;AALD,SAAS,YAAY,EAAE,UAAU,GAAG,YAAY,GAAqB;AACxE,QAAM,EAAE,WAAW,QAAI,2BAAa;AACpC,QAAM,EAAE,MAAM,QAAI,6BAAe;AACjC,MAAI,WAAY,QAAO;AACvB,SACI,6CAAC,UAAQ,GAAG,aAAa,SAAS,MAAM,MAAM,GACzC,UACL;AAER;;;AGrBA,IAAAC,gBAA6C;AAiBrC,IAAAC,sBAAA;AALD,SAAS,aAAa,EAAE,UAAU,GAAG,YAAY,GAAsB;AAC1E,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,QAAM,EAAE,OAAO,QAAI,8BAAe;AAClC,MAAI,CAAC,WAAY,QAAO;AACxB,SACI,6CAAC,UAAQ,GAAG,aAAa,SAAS,MAAM,OAAO,GAC1C,UACL;AAER;;;ACrBA,IAAAC,gBAAgD;AAqCpC,IAAAC,sBAAA;AA7BZ,IAAM,YAAY;AAAA,EACd,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACR;AAEA,SAAS,SAAS,MAA6B;AAC3C,QAAM,QAAQ,KAAK,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO;AACrD,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,YAAY,KAAK;AACrE,QAAM,QAAQ,MAAM,CAAC,EAAE,CAAC,KAAK;AAC7B,QAAM,OAAO,MAAM,MAAM,SAAS,CAAC,EAAE,CAAC,KAAK;AAC3C,UAAQ,QAAQ,MAAM,YAAY,KAAK;AAC3C;AAGO,SAAS,WAAW,EAAE,OAAO,MAAM,UAAU,GAAoB;AACpE,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,QAAM,EAAE,MAAM,QAAQ,QAAI,iCAAkB,EAAE,SAAS,WAAW,CAAC;AACnE,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,OAAO;AAAA,IACT;AAAA,IACA,UAAU,IAAI;AAAA,IACd;AAAA,EACJ;AAEA,MAAI,SAAS,OAAO;AAChB,WACI;AAAA,MAAC;AAAA;AAAA,QACG,cAAW;AAAA,QACX,KAAK,QAAQ;AAAA,QACb,KAAK,QAAQ,QAAQ;AAAA,QACrB,WAAW;AAAA;AAAA,IACf;AAAA,EAER;AACA,QAAM,QAAQ,SAAS,OAAO,SAAS,QAAQ,IAAI,IAAI;AACvD,MAAI,CAAC,MAAO,QAAO;AACnB,SACI;AAAA,IAAC;AAAA;AAAA,MACG,cAAW;AAAA,MACX,MAAK;AAAA,MACL,cAAY,SAAS,QAAQ;AAAA,MAC7B,WAAW;AAAA,MAEV;AAAA;AAAA,EACL;AAER;;;ACzDA,IAAAC,gBAAgD;AAUxC,IAAAC,sBAAA;AALD,SAAS,UAAU,EAAE,UAAU,GAAmB;AACrD,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,QAAM,EAAE,MAAM,QAAQ,QAAI,iCAAkB,EAAE,SAAS,WAAW,CAAC;AACnE,MAAI,CAAC,cAAc,CAAC,SAAS,MAAO,QAAO;AAC3C,SACI,6CAAC,UAAK,cAAW,cAAa,WACzB,kBAAQ,OACb;AAER;;;ACdA,IAAAC,gBAAgD;AAgBxC,IAAAC,sBAAA;AAPD,SAAS,SAAS,EAAE,UAAU,GAAkB;AACnD,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,QAAM,EAAE,MAAM,QAAQ,QAAI,iCAAkB,EAAE,SAAS,WAAW,CAAC;AACnE,MAAI,CAAC,cAAc,CAAC,QAAS,QAAO;AACpC,QAAM,UAAU,QAAQ,QAAQ,QAAQ;AACxC,MAAI,CAAC,QAAS,QAAO;AACrB,SACI,6CAAC,UAAK,cAAW,aAAY,WACxB,mBACL;AAER;;;ACpBA,IAAAC,gBAA6B;AAC7B,IAAAA,gBAAyC;AAQ9B,IAAAC,sBAAA;AAHJ,SAAS,aAAa,EAAE,SAAS,GAAsB;AAC1D,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,6CAAC,0BAAU,UAAS;AAC/B;;;ACVA,IAAAC,gBAA6B;AAC7B,IAAAA,gBAAyC;AAQ9B,IAAAC,sBAAA;AAHJ,SAAS,cAAc,EAAE,SAAS,GAAuB;AAC5D,QAAM,EAAE,WAAW,QAAI,4BAAa;AACpC,MAAI,WAAY,QAAO;AACvB,SAAO,6CAAC,0BAAU,UAAS;AAC/B;","names":["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","import_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/modules/auth/sdk.ts","../../src/modules/auth/LoginButton.tsx","../../src/lib/cn.ts","../../src/primitives/Button.tsx","../../src/modules/auth/LogoutButton.tsx","../../src/modules/auth/UserAvatar.tsx","../../src/modules/auth/UserEmail.tsx","../../src/modules/auth/UserName.tsx","../../src/modules/auth/WhenLoggedIn.tsx","../../src/modules/auth/WhenLoggedOut.tsx"],"sourcesContent":["export { LoginButton, type LoginButtonProps } from \"./LoginButton.tsx\";\nexport { LogoutButton, type LogoutButtonProps } from \"./LogoutButton.tsx\";\nexport { UserAvatar, type UserAvatarProps } from \"./UserAvatar.tsx\";\nexport { UserEmail, type UserEmailProps } from \"./UserEmail.tsx\";\nexport { UserName, type UserNameProps } from \"./UserName.tsx\";\nexport { WhenLoggedIn, type WhenLoggedInProps } from \"./WhenLoggedIn.tsx\";\nexport { WhenLoggedOut, type WhenLoggedOutProps } from \"./WhenLoggedOut.tsx\";\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 { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Button only supports `danger`. Label/status color recipes live on Chip. */\ntype ButtonIntent = \"danger\";\n\nconst sizes = {\n sm: \"polli:px-2 polli:pt-0.5 polli:pb-1\",\n md: \"polli:px-4 polli:pt-1.5 polli:pb-2\",\n lg: \"polli:px-6 polli:py-3\",\n} as const;\n\n// Cascade-driven base — reads [data-theme] vars.\nconst themeClasses =\n \"polli:bg-theme-bg-active polli:text-theme-text-base \" +\n \"polli:hover:bg-theme-bg-hover polli:transition-colors\";\n\n// Single intent: danger. Soft recipe — light tile + deep text, slightly\n// deeper bg on hover. No filled CTAs anywhere.\nconst intentClasses: Record<ButtonIntent, string> = {\n danger:\n \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text \" +\n \"polli:hover:bg-intent-danger-bg-hover polli:transition-colors\",\n};\n\ntype BaseButtonProps = {\n /** Override the cascade theme for this button's subtree. Ignored when `intent` is set. */\n theme?: ThemeName;\n /** Only `\"danger\"` for now. */\n intent?: ButtonIntent;\n size?: keyof typeof sizes;\n className?: string;\n disabled?: boolean;\n};\n\nconst buttonClasses = ({\n theme: _theme,\n intent,\n size,\n className,\n disabled,\n}: BaseButtonProps & { disabled?: boolean }) => {\n const colorClasses = intent ? intentClasses[intent] : themeClasses;\n return cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:font-medium polli:leading-normal polli:box-border\",\n disabled\n ? \"polli:opacity-50 polli:cursor-not-allowed\"\n : \"polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer\",\n colorClasses,\n sizes[size || \"md\"],\n className,\n );\n};\n\nexport type ButtonProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseButtonProps> & {\n as?: T;\n } & Omit<React.ComponentPropsWithoutRef<T>, keyof BaseButtonProps | \"as\">;\n\nexport function Button<T extends React.ElementType = \"button\">({\n as,\n children,\n theme,\n intent,\n size,\n className,\n disabled,\n ...buttonProps\n}: ButtonProps<T>) {\n const Component: React.ElementType = as || \"button\";\n\n return (\n <Component\n // Cascade override only applies when `intent` is unset.\n data-theme={intent ? undefined : theme}\n data-intent={intent}\n className={buttonClasses({\n theme,\n intent,\n size,\n className,\n disabled,\n })}\n disabled={disabled}\n {...buttonProps}\n >\n {children}\n </Component>\n );\n}\n","import { useAuthActions, useAuthState } from \"@pollinations/sdk/react\";\nimport type { ReactNode } from \"react\";\nimport { Button, type ButtonProps } from \"../../primitives/Button.tsx\";\n\nexport type LogoutButtonProps = Omit<\n ButtonProps<\"button\">,\n \"as\" | \"onClick\" | \"children\"\n> & {\n children: ReactNode;\n};\n\n/** Button that clears the session. `null` when logged out. */\nexport function LogoutButton({ children, ...buttonProps }: LogoutButtonProps) {\n const { isLoggedIn } = useAuthState();\n const { logout } = useAuthActions();\n if (!isLoggedIn) return null;\n return (\n <Button {...buttonProps} onClick={() => logout()}>\n {children}\n </Button>\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 UserEmailProps = { className?: string };\n\n/** Renders `profile.email`. `null` when logged out or the key lacks `profile` scope. */\nexport function UserEmail({ className }: UserEmailProps) {\n const { isLoggedIn } = useAuthState();\n const { data: profile } = useAccountProfile({ enabled: isLoggedIn });\n if (!isLoggedIn || !profile?.email) return null;\n return (\n <span data-polli=\"user-email\" className={className}>\n {profile.email}\n </span>\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"],"mappings":"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","names":["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","import_react","import_jsx_runtime"]}