@pollinations/ui 0.0.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 +219 -0
- package/dist/Button-CNzpisJf.d.cts +26 -0
- package/dist/Button-DMJ2K6Gr.d.ts +26 -0
- package/dist/Chip-BS8ronOu.d.ts +20 -0
- package/dist/Chip-DyqWrq0r.d.cts +20 -0
- package/dist/app.css +87 -0
- package/dist/assets/logo-wordmark.svg +1 -0
- package/dist/assets/logo.svg +4 -0
- package/dist/auth/index.cjs +225 -0
- package/dist/auth/index.cjs.map +1 -0
- package/dist/auth/index.d.cts +28 -0
- package/dist/auth/index.d.ts +28 -0
- package/dist/auth/index.js +194 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/sdk.cjs +220 -0
- package/dist/auth/sdk.cjs.map +1 -0
- package/dist/auth/sdk.d.cts +53 -0
- package/dist/auth/sdk.d.ts +53 -0
- package/dist/auth/sdk.js +187 -0
- package/dist/auth/sdk.js.map +1 -0
- package/dist/fonts/fraunces-soft-bold.woff2 +0 -0
- package/dist/fonts/lct-mogi-a.woff2 +0 -0
- package/dist/fonts/uncut-sans-variable.woff2 +0 -0
- package/dist/index.cjs +1771 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +340 -0
- package/dist/index.d.ts +340 -0
- package/dist/index.js +1706 -0
- package/dist/index.js.map +1 -0
- package/dist/licenses/Fraunces-OFL.txt +93 -0
- package/dist/licenses/LCT-Mogi-OFL.txt +93 -0
- package/dist/licenses/UncutSans-OFL.txt +94 -0
- package/dist/modality/index.cjs +115 -0
- package/dist/modality/index.cjs.map +1 -0
- package/dist/modality/index.d.cts +45 -0
- package/dist/modality/index.d.ts +45 -0
- package/dist/modality/index.js +87 -0
- package/dist/modality/index.js.map +1 -0
- package/dist/showcase/index.cjs +2851 -0
- package/dist/showcase/index.cjs.map +1 -0
- package/dist/showcase/index.d.cts +19 -0
- package/dist/showcase/index.d.ts +19 -0
- package/dist/showcase/index.js +2839 -0
- package/dist/showcase/index.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/theme-DfHMjWB7.d.cts +16 -0
- package/dist/theme-DfHMjWB7.d.ts +16 -0
- package/dist/wallet/index.cjs +190 -0
- package/dist/wallet/index.cjs.map +1 -0
- package/dist/wallet/index.d.cts +30 -0
- package/dist/wallet/index.d.ts +30 -0
- package/dist/wallet/index.js +157 -0
- package/dist/wallet/index.js.map +1 -0
- package/dist/wallet/sdk.cjs +203 -0
- package/dist/wallet/sdk.cjs.map +1 -0
- package/dist/wallet/sdk.d.cts +33 -0
- package/dist/wallet/sdk.d.ts +33 -0
- package/dist/wallet/sdk.js +172 -0
- package/dist/wallet/sdk.js.map +1 -0
- package/dist/wallet.css +73 -0
- package/package.json +105 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/modules/modality/index.ts
|
|
21
|
+
var modality_exports = {};
|
|
22
|
+
__export(modality_exports, {
|
|
23
|
+
ModalityButton: () => ModalityButton,
|
|
24
|
+
getModalityColors: () => getModalityColors
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(modality_exports);
|
|
27
|
+
|
|
28
|
+
// src/modules/modality/colors.ts
|
|
29
|
+
var MODALITY_COLORS = {
|
|
30
|
+
text: {
|
|
31
|
+
filled: "polli:bg-blue-200 polli:text-blue-900",
|
|
32
|
+
hover: "polli:hover:bg-blue-100 polli:hover:text-blue-900",
|
|
33
|
+
text: "polli:text-blue-800"
|
|
34
|
+
},
|
|
35
|
+
image: {
|
|
36
|
+
filled: "polli:bg-pink-200 polli:text-pink-900",
|
|
37
|
+
hover: "polli:hover:bg-pink-100 polli:hover:text-pink-900",
|
|
38
|
+
text: "polli:text-pink-800"
|
|
39
|
+
},
|
|
40
|
+
video: {
|
|
41
|
+
filled: "polli:bg-teal-200 polli:text-teal-900",
|
|
42
|
+
hover: "polli:hover:bg-teal-100 polli:hover:text-teal-900",
|
|
43
|
+
text: "polli:text-teal-800"
|
|
44
|
+
},
|
|
45
|
+
audio: {
|
|
46
|
+
filled: "polli:bg-violet-200 polli:text-violet-900",
|
|
47
|
+
hover: "polli:hover:bg-violet-100 polli:hover:text-violet-900",
|
|
48
|
+
text: "polli:text-violet-800"
|
|
49
|
+
},
|
|
50
|
+
realtime: {
|
|
51
|
+
filled: "polli:bg-green-200 polli:text-green-900",
|
|
52
|
+
hover: "polli:hover:bg-green-100 polli:hover:text-green-900",
|
|
53
|
+
text: "polli:text-green-800"
|
|
54
|
+
},
|
|
55
|
+
embedding: {
|
|
56
|
+
filled: "polli:bg-amber-200 polli:text-amber-900",
|
|
57
|
+
hover: "polli:hover:bg-amber-100 polli:hover:text-amber-900",
|
|
58
|
+
text: "polli:text-amber-800"
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
function normalize(category) {
|
|
62
|
+
const lower = category.toLowerCase();
|
|
63
|
+
if (lower === "images") return "image";
|
|
64
|
+
if (lower === "embeddings") return "embedding";
|
|
65
|
+
if (lower === "text" || lower === "image" || lower === "video" || lower === "audio" || lower === "realtime" || lower === "embedding") {
|
|
66
|
+
return lower;
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
function getModalityColors(category) {
|
|
71
|
+
const key = normalize(category);
|
|
72
|
+
return key ? MODALITY_COLORS[key] : null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/lib/cn.ts
|
|
76
|
+
var import_clsx = require("clsx");
|
|
77
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
78
|
+
var twMerge = (0, import_tailwind_merge.extendTailwindMerge)({ prefix: "polli" });
|
|
79
|
+
function cn(...inputs) {
|
|
80
|
+
return twMerge((0, import_clsx.clsx)(...inputs));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/modules/modality/ModalityButton.tsx
|
|
84
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
85
|
+
var ModalityButton = ({
|
|
86
|
+
category,
|
|
87
|
+
selected = true,
|
|
88
|
+
onClick,
|
|
89
|
+
disabled,
|
|
90
|
+
children
|
|
91
|
+
}) => {
|
|
92
|
+
const colors = getModalityColors(category ?? "");
|
|
93
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
94
|
+
"button",
|
|
95
|
+
{
|
|
96
|
+
type: "button",
|
|
97
|
+
onClick,
|
|
98
|
+
disabled,
|
|
99
|
+
"aria-pressed": selected,
|
|
100
|
+
className: cn(
|
|
101
|
+
"polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-full polli:px-3 polli:py-1 polli:text-left polli:text-sm polli:font-medium polli:leading-normal polli:transition-colors",
|
|
102
|
+
selected ? colors?.filled ?? "polli:bg-gray-200 polli:text-gray-900" : "polli:bg-gray-100 polli:text-gray-600",
|
|
103
|
+
!disabled && !selected && colors?.hover,
|
|
104
|
+
disabled ? "polli:cursor-not-allowed polli:opacity-50" : "polli:cursor-pointer"
|
|
105
|
+
),
|
|
106
|
+
children
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
111
|
+
0 && (module.exports = {
|
|
112
|
+
ModalityButton,
|
|
113
|
+
getModalityColors
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/modality/index.ts","../../src/modules/modality/colors.ts","../../src/lib/cn.ts","../../src/modules/modality/ModalityButton.tsx"],"sourcesContent":["export {\n getModalityColors,\n type Modality,\n type ModalityColorSet,\n} from \"./colors.ts\";\nexport { ModalityButton, type ModalityButtonProps } from \"./ModalityButton.tsx\";\n","/**\n * Single source of truth for modality colors.\n *\n * Each modality (text/image/video/audio/realtime/embedding) gets one\n * page-theme hue, applied at the soft `-200/-900/-400` chip recipe.\n * Used in two places:\n * 1. The model-selection buttons in the API key creation flow.\n * 2. The static modality chips on the OAuth authorize screen.\n *\n * Interactive selection (model-picker) renders as `rounded-full` pills\n * aligned to the canonical Button. Static display (authorize summary)\n * renders as `rounded-lg` chips. Page-theme hues only — no rogue\n * indigo/rose.\n */\nexport type Modality =\n | \"text\"\n | \"image\"\n | \"video\"\n | \"audio\"\n | \"realtime\"\n | \"embedding\";\n\nexport type ModalityColorSet = {\n /** Selected/filled state: `bg + text + border` classes. */\n filled: string;\n /** Hover hint shown on the unselected button (subtle tint). */\n hover: string;\n /** Heading text colour for the category label. */\n text: string;\n};\n\n// No borders — chips and buttons in this system are borderless.\nexport const MODALITY_COLORS: Record<Modality, ModalityColorSet> = {\n text: {\n filled: \"polli:bg-blue-200 polli:text-blue-900\",\n hover: \"polli:hover:bg-blue-100 polli:hover:text-blue-900\",\n text: \"polli:text-blue-800\",\n },\n image: {\n filled: \"polli:bg-pink-200 polli:text-pink-900\",\n hover: \"polli:hover:bg-pink-100 polli:hover:text-pink-900\",\n text: \"polli:text-pink-800\",\n },\n video: {\n filled: \"polli:bg-teal-200 polli:text-teal-900\",\n hover: \"polli:hover:bg-teal-100 polli:hover:text-teal-900\",\n text: \"polli:text-teal-800\",\n },\n audio: {\n filled: \"polli:bg-violet-200 polli:text-violet-900\",\n hover: \"polli:hover:bg-violet-100 polli:hover:text-violet-900\",\n text: \"polli:text-violet-800\",\n },\n realtime: {\n filled: \"polli:bg-green-200 polli:text-green-900\",\n hover: \"polli:hover:bg-green-100 polli:hover:text-green-900\",\n text: \"polli:text-green-800\",\n },\n embedding: {\n filled: \"polli:bg-amber-200 polli:text-amber-900\",\n hover: \"polli:hover:bg-amber-100 polli:hover:text-amber-900\",\n text: \"polli:text-amber-800\",\n },\n};\n\n/** Map any human-typed category string to the canonical `Modality` key. */\nfunction normalize(category: string): Modality | null {\n const lower = category.toLowerCase();\n if (lower === \"images\") return \"image\";\n if (lower === \"embeddings\") return \"embedding\";\n if (\n lower === \"text\" ||\n lower === \"image\" ||\n lower === \"video\" ||\n lower === \"audio\" ||\n lower === \"realtime\" ||\n lower === \"embedding\"\n ) {\n return lower;\n }\n return null;\n}\n\nexport function getModalityColors(category: string): ModalityColorSet | null {\n const key = normalize(category);\n return key ? MODALITY_COLORS[key] : null;\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, ReactNode } from \"react\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { getModalityColors } from \"./colors.ts\";\n\nexport type ModalityButtonProps = {\n /** Modality key or category string (\"Text\", \"Images\", etc). */\n category?: string;\n /** Filled (modality hue) when true, muted gray when false. */\n selected?: boolean;\n onClick?: () => void;\n disabled?: boolean;\n children: ReactNode;\n};\n\n/**\n * Rounded-full pill button colored by modality. Single source of truth\n * for every interactive modality affordance — model picker, design\n * showcase, etc. Shape and recipe live here; consumers only supply\n * content + state.\n */\nexport const ModalityButton: FC<ModalityButtonProps> = ({\n category,\n selected = true,\n onClick,\n disabled,\n children,\n}) => {\n const colors = getModalityColors(category ?? \"\");\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n aria-pressed={selected}\n className={cn(\n \"polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-full polli:px-3 polli:py-1 polli:text-left polli:text-sm polli:font-medium polli:leading-normal polli:transition-colors\",\n selected\n ? (colors?.filled ??\n \"polli:bg-gray-200 polli:text-gray-900\")\n : \"polli:bg-gray-100 polli:text-gray-600\",\n !disabled && !selected && colors?.hover,\n disabled\n ? \"polli:cursor-not-allowed polli:opacity-50\"\n : \"polli:cursor-pointer\",\n )}\n >\n {children}\n </button>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgCO,IAAM,kBAAsD;AAAA,EAC/D,MAAM;AAAA,IACF,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,OAAO;AAAA,IACH,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,OAAO;AAAA,IACH,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,OAAO;AAAA,IACH,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,UAAU;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,WAAW;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AACJ;AAGA,SAAS,UAAU,UAAmC;AAClD,QAAM,QAAQ,SAAS,YAAY;AACnC,MAAI,UAAU,SAAU,QAAO;AAC/B,MAAI,UAAU,aAAc,QAAO;AACnC,MACI,UAAU,UACV,UAAU,WACV,UAAU,WACV,UAAU,WACV,UAAU,cACV,UAAU,aACZ;AACE,WAAO;AAAA,EACX;AACA,SAAO;AACX;AAEO,SAAS,kBAAkB,UAA2C;AACzE,QAAM,MAAM,UAAU,QAAQ;AAC9B,SAAO,MAAM,gBAAgB,GAAG,IAAI;AACxC;;;ACtFA,kBAAqB;AACrB,4BAAoC;AAEpC,IAAM,cAAU,2CAAoB,EAAE,QAAQ,QAAQ,CAAC;AAGhD,SAAS,MAAM,QAA+C;AACjE,SAAO,YAAQ,kBAAK,GAAG,MAAM,CAAC;AAClC;;;ACqBQ;AATD,IAAM,iBAA0C,CAAC;AAAA,EACpD;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AACJ,MAAM;AACF,QAAM,SAAS,kBAAkB,YAAY,EAAE;AAC/C,SACI;AAAA,IAAC;AAAA;AAAA,MACG,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,gBAAc;AAAA,MACd,WAAW;AAAA,QACP;AAAA,QACA,WACO,QAAQ,UACL,0CACJ;AAAA,QACN,CAAC,YAAY,CAAC,YAAY,QAAQ;AAAA,QAClC,WACM,8CACA;AAAA,MACV;AAAA,MAEC;AAAA;AAAA,EACL;AAER;","names":[]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Single source of truth for modality colors.
|
|
5
|
+
*
|
|
6
|
+
* Each modality (text/image/video/audio/realtime/embedding) gets one
|
|
7
|
+
* page-theme hue, applied at the soft `-200/-900/-400` chip recipe.
|
|
8
|
+
* Used in two places:
|
|
9
|
+
* 1. The model-selection buttons in the API key creation flow.
|
|
10
|
+
* 2. The static modality chips on the OAuth authorize screen.
|
|
11
|
+
*
|
|
12
|
+
* Interactive selection (model-picker) renders as `rounded-full` pills
|
|
13
|
+
* aligned to the canonical Button. Static display (authorize summary)
|
|
14
|
+
* renders as `rounded-lg` chips. Page-theme hues only — no rogue
|
|
15
|
+
* indigo/rose.
|
|
16
|
+
*/
|
|
17
|
+
type Modality = "text" | "image" | "video" | "audio" | "realtime" | "embedding";
|
|
18
|
+
type ModalityColorSet = {
|
|
19
|
+
/** Selected/filled state: `bg + text + border` classes. */
|
|
20
|
+
filled: string;
|
|
21
|
+
/** Hover hint shown on the unselected button (subtle tint). */
|
|
22
|
+
hover: string;
|
|
23
|
+
/** Heading text colour for the category label. */
|
|
24
|
+
text: string;
|
|
25
|
+
};
|
|
26
|
+
declare function getModalityColors(category: string): ModalityColorSet | null;
|
|
27
|
+
|
|
28
|
+
type ModalityButtonProps = {
|
|
29
|
+
/** Modality key or category string ("Text", "Images", etc). */
|
|
30
|
+
category?: string;
|
|
31
|
+
/** Filled (modality hue) when true, muted gray when false. */
|
|
32
|
+
selected?: boolean;
|
|
33
|
+
onClick?: () => void;
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
children: ReactNode;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Rounded-full pill button colored by modality. Single source of truth
|
|
39
|
+
* for every interactive modality affordance — model picker, design
|
|
40
|
+
* showcase, etc. Shape and recipe live here; consumers only supply
|
|
41
|
+
* content + state.
|
|
42
|
+
*/
|
|
43
|
+
declare const ModalityButton: FC<ModalityButtonProps>;
|
|
44
|
+
|
|
45
|
+
export { type Modality, ModalityButton, type ModalityButtonProps, type ModalityColorSet, getModalityColors };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Single source of truth for modality colors.
|
|
5
|
+
*
|
|
6
|
+
* Each modality (text/image/video/audio/realtime/embedding) gets one
|
|
7
|
+
* page-theme hue, applied at the soft `-200/-900/-400` chip recipe.
|
|
8
|
+
* Used in two places:
|
|
9
|
+
* 1. The model-selection buttons in the API key creation flow.
|
|
10
|
+
* 2. The static modality chips on the OAuth authorize screen.
|
|
11
|
+
*
|
|
12
|
+
* Interactive selection (model-picker) renders as `rounded-full` pills
|
|
13
|
+
* aligned to the canonical Button. Static display (authorize summary)
|
|
14
|
+
* renders as `rounded-lg` chips. Page-theme hues only — no rogue
|
|
15
|
+
* indigo/rose.
|
|
16
|
+
*/
|
|
17
|
+
type Modality = "text" | "image" | "video" | "audio" | "realtime" | "embedding";
|
|
18
|
+
type ModalityColorSet = {
|
|
19
|
+
/** Selected/filled state: `bg + text + border` classes. */
|
|
20
|
+
filled: string;
|
|
21
|
+
/** Hover hint shown on the unselected button (subtle tint). */
|
|
22
|
+
hover: string;
|
|
23
|
+
/** Heading text colour for the category label. */
|
|
24
|
+
text: string;
|
|
25
|
+
};
|
|
26
|
+
declare function getModalityColors(category: string): ModalityColorSet | null;
|
|
27
|
+
|
|
28
|
+
type ModalityButtonProps = {
|
|
29
|
+
/** Modality key or category string ("Text", "Images", etc). */
|
|
30
|
+
category?: string;
|
|
31
|
+
/** Filled (modality hue) when true, muted gray when false. */
|
|
32
|
+
selected?: boolean;
|
|
33
|
+
onClick?: () => void;
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
children: ReactNode;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Rounded-full pill button colored by modality. Single source of truth
|
|
39
|
+
* for every interactive modality affordance — model picker, design
|
|
40
|
+
* showcase, etc. Shape and recipe live here; consumers only supply
|
|
41
|
+
* content + state.
|
|
42
|
+
*/
|
|
43
|
+
declare const ModalityButton: FC<ModalityButtonProps>;
|
|
44
|
+
|
|
45
|
+
export { type Modality, ModalityButton, type ModalityButtonProps, type ModalityColorSet, getModalityColors };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// src/modules/modality/colors.ts
|
|
2
|
+
var MODALITY_COLORS = {
|
|
3
|
+
text: {
|
|
4
|
+
filled: "polli:bg-blue-200 polli:text-blue-900",
|
|
5
|
+
hover: "polli:hover:bg-blue-100 polli:hover:text-blue-900",
|
|
6
|
+
text: "polli:text-blue-800"
|
|
7
|
+
},
|
|
8
|
+
image: {
|
|
9
|
+
filled: "polli:bg-pink-200 polli:text-pink-900",
|
|
10
|
+
hover: "polli:hover:bg-pink-100 polli:hover:text-pink-900",
|
|
11
|
+
text: "polli:text-pink-800"
|
|
12
|
+
},
|
|
13
|
+
video: {
|
|
14
|
+
filled: "polli:bg-teal-200 polli:text-teal-900",
|
|
15
|
+
hover: "polli:hover:bg-teal-100 polli:hover:text-teal-900",
|
|
16
|
+
text: "polli:text-teal-800"
|
|
17
|
+
},
|
|
18
|
+
audio: {
|
|
19
|
+
filled: "polli:bg-violet-200 polli:text-violet-900",
|
|
20
|
+
hover: "polli:hover:bg-violet-100 polli:hover:text-violet-900",
|
|
21
|
+
text: "polli:text-violet-800"
|
|
22
|
+
},
|
|
23
|
+
realtime: {
|
|
24
|
+
filled: "polli:bg-green-200 polli:text-green-900",
|
|
25
|
+
hover: "polli:hover:bg-green-100 polli:hover:text-green-900",
|
|
26
|
+
text: "polli:text-green-800"
|
|
27
|
+
},
|
|
28
|
+
embedding: {
|
|
29
|
+
filled: "polli:bg-amber-200 polli:text-amber-900",
|
|
30
|
+
hover: "polli:hover:bg-amber-100 polli:hover:text-amber-900",
|
|
31
|
+
text: "polli:text-amber-800"
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
function normalize(category) {
|
|
35
|
+
const lower = category.toLowerCase();
|
|
36
|
+
if (lower === "images") return "image";
|
|
37
|
+
if (lower === "embeddings") return "embedding";
|
|
38
|
+
if (lower === "text" || lower === "image" || lower === "video" || lower === "audio" || lower === "realtime" || lower === "embedding") {
|
|
39
|
+
return lower;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
function getModalityColors(category) {
|
|
44
|
+
const key = normalize(category);
|
|
45
|
+
return key ? MODALITY_COLORS[key] : null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/lib/cn.ts
|
|
49
|
+
import { clsx } from "clsx";
|
|
50
|
+
import { extendTailwindMerge } from "tailwind-merge";
|
|
51
|
+
var twMerge = extendTailwindMerge({ prefix: "polli" });
|
|
52
|
+
function cn(...inputs) {
|
|
53
|
+
return twMerge(clsx(...inputs));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/modules/modality/ModalityButton.tsx
|
|
57
|
+
import { jsx } from "react/jsx-runtime";
|
|
58
|
+
var ModalityButton = ({
|
|
59
|
+
category,
|
|
60
|
+
selected = true,
|
|
61
|
+
onClick,
|
|
62
|
+
disabled,
|
|
63
|
+
children
|
|
64
|
+
}) => {
|
|
65
|
+
const colors = getModalityColors(category ?? "");
|
|
66
|
+
return /* @__PURE__ */ jsx(
|
|
67
|
+
"button",
|
|
68
|
+
{
|
|
69
|
+
type: "button",
|
|
70
|
+
onClick,
|
|
71
|
+
disabled,
|
|
72
|
+
"aria-pressed": selected,
|
|
73
|
+
className: cn(
|
|
74
|
+
"polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-full polli:px-3 polli:py-1 polli:text-left polli:text-sm polli:font-medium polli:leading-normal polli:transition-colors",
|
|
75
|
+
selected ? colors?.filled ?? "polli:bg-gray-200 polli:text-gray-900" : "polli:bg-gray-100 polli:text-gray-600",
|
|
76
|
+
!disabled && !selected && colors?.hover,
|
|
77
|
+
disabled ? "polli:cursor-not-allowed polli:opacity-50" : "polli:cursor-pointer"
|
|
78
|
+
),
|
|
79
|
+
children
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
export {
|
|
84
|
+
ModalityButton,
|
|
85
|
+
getModalityColors
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/modality/colors.ts","../../src/lib/cn.ts","../../src/modules/modality/ModalityButton.tsx"],"sourcesContent":["/**\n * Single source of truth for modality colors.\n *\n * Each modality (text/image/video/audio/realtime/embedding) gets one\n * page-theme hue, applied at the soft `-200/-900/-400` chip recipe.\n * Used in two places:\n * 1. The model-selection buttons in the API key creation flow.\n * 2. The static modality chips on the OAuth authorize screen.\n *\n * Interactive selection (model-picker) renders as `rounded-full` pills\n * aligned to the canonical Button. Static display (authorize summary)\n * renders as `rounded-lg` chips. Page-theme hues only — no rogue\n * indigo/rose.\n */\nexport type Modality =\n | \"text\"\n | \"image\"\n | \"video\"\n | \"audio\"\n | \"realtime\"\n | \"embedding\";\n\nexport type ModalityColorSet = {\n /** Selected/filled state: `bg + text + border` classes. */\n filled: string;\n /** Hover hint shown on the unselected button (subtle tint). */\n hover: string;\n /** Heading text colour for the category label. */\n text: string;\n};\n\n// No borders — chips and buttons in this system are borderless.\nexport const MODALITY_COLORS: Record<Modality, ModalityColorSet> = {\n text: {\n filled: \"polli:bg-blue-200 polli:text-blue-900\",\n hover: \"polli:hover:bg-blue-100 polli:hover:text-blue-900\",\n text: \"polli:text-blue-800\",\n },\n image: {\n filled: \"polli:bg-pink-200 polli:text-pink-900\",\n hover: \"polli:hover:bg-pink-100 polli:hover:text-pink-900\",\n text: \"polli:text-pink-800\",\n },\n video: {\n filled: \"polli:bg-teal-200 polli:text-teal-900\",\n hover: \"polli:hover:bg-teal-100 polli:hover:text-teal-900\",\n text: \"polli:text-teal-800\",\n },\n audio: {\n filled: \"polli:bg-violet-200 polli:text-violet-900\",\n hover: \"polli:hover:bg-violet-100 polli:hover:text-violet-900\",\n text: \"polli:text-violet-800\",\n },\n realtime: {\n filled: \"polli:bg-green-200 polli:text-green-900\",\n hover: \"polli:hover:bg-green-100 polli:hover:text-green-900\",\n text: \"polli:text-green-800\",\n },\n embedding: {\n filled: \"polli:bg-amber-200 polli:text-amber-900\",\n hover: \"polli:hover:bg-amber-100 polli:hover:text-amber-900\",\n text: \"polli:text-amber-800\",\n },\n};\n\n/** Map any human-typed category string to the canonical `Modality` key. */\nfunction normalize(category: string): Modality | null {\n const lower = category.toLowerCase();\n if (lower === \"images\") return \"image\";\n if (lower === \"embeddings\") return \"embedding\";\n if (\n lower === \"text\" ||\n lower === \"image\" ||\n lower === \"video\" ||\n lower === \"audio\" ||\n lower === \"realtime\" ||\n lower === \"embedding\"\n ) {\n return lower;\n }\n return null;\n}\n\nexport function getModalityColors(category: string): ModalityColorSet | null {\n const key = normalize(category);\n return key ? MODALITY_COLORS[key] : null;\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, ReactNode } from \"react\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { getModalityColors } from \"./colors.ts\";\n\nexport type ModalityButtonProps = {\n /** Modality key or category string (\"Text\", \"Images\", etc). */\n category?: string;\n /** Filled (modality hue) when true, muted gray when false. */\n selected?: boolean;\n onClick?: () => void;\n disabled?: boolean;\n children: ReactNode;\n};\n\n/**\n * Rounded-full pill button colored by modality. Single source of truth\n * for every interactive modality affordance — model picker, design\n * showcase, etc. Shape and recipe live here; consumers only supply\n * content + state.\n */\nexport const ModalityButton: FC<ModalityButtonProps> = ({\n category,\n selected = true,\n onClick,\n disabled,\n children,\n}) => {\n const colors = getModalityColors(category ?? \"\");\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n aria-pressed={selected}\n className={cn(\n \"polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-full polli:px-3 polli:py-1 polli:text-left polli:text-sm polli:font-medium polli:leading-normal polli:transition-colors\",\n selected\n ? (colors?.filled ??\n \"polli:bg-gray-200 polli:text-gray-900\")\n : \"polli:bg-gray-100 polli:text-gray-600\",\n !disabled && !selected && colors?.hover,\n disabled\n ? \"polli:cursor-not-allowed polli:opacity-50\"\n : \"polli:cursor-pointer\",\n )}\n >\n {children}\n </button>\n );\n};\n"],"mappings":";AAgCO,IAAM,kBAAsD;AAAA,EAC/D,MAAM;AAAA,IACF,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,OAAO;AAAA,IACH,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,OAAO;AAAA,IACH,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,OAAO;AAAA,IACH,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,UAAU;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AAAA,EACA,WAAW;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACV;AACJ;AAGA,SAAS,UAAU,UAAmC;AAClD,QAAM,QAAQ,SAAS,YAAY;AACnC,MAAI,UAAU,SAAU,QAAO;AAC/B,MAAI,UAAU,aAAc,QAAO;AACnC,MACI,UAAU,UACV,UAAU,WACV,UAAU,WACV,UAAU,WACV,UAAU,cACV,UAAU,aACZ;AACE,WAAO;AAAA,EACX;AACA,SAAO;AACX;AAEO,SAAS,kBAAkB,UAA2C;AACzE,QAAM,MAAM,UAAU,QAAQ;AAC9B,SAAO,MAAM,gBAAgB,GAAG,IAAI;AACxC;;;ACtFA,SAAS,YAAY;AACrB,SAAS,2BAA2B;AAEpC,IAAM,UAAU,oBAAoB,EAAE,QAAQ,QAAQ,CAAC;AAGhD,SAAS,MAAM,QAA+C;AACjE,SAAO,QAAQ,KAAK,GAAG,MAAM,CAAC;AAClC;;;ACqBQ;AATD,IAAM,iBAA0C,CAAC;AAAA,EACpD;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AACJ,MAAM;AACF,QAAM,SAAS,kBAAkB,YAAY,EAAE;AAC/C,SACI;AAAA,IAAC;AAAA;AAAA,MACG,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,gBAAc;AAAA,MACd,WAAW;AAAA,QACP;AAAA,QACA,WACO,QAAQ,UACL,0CACJ;AAAA,QACN,CAAC,YAAY,CAAC,YAAY,QAAQ;AAAA,QAClC,WACM,8CACA;AAAA,MACV;AAAA,MAEC;AAAA;AAAA,EACL;AAER;","names":[]}
|