@openkeyai/ui 0.1.0 → 1.0.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.
- package/dist/index.cjs +134 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +138 -5
- package/dist/index.d.ts +138 -5
- package/dist/index.js +109 -4
- package/dist/index.js.map +1 -1
- package/dist/styles.css +351 -28
- package/dist/tailwind.cjs +139 -47
- package/dist/tailwind.cjs.map +1 -1
- package/dist/tailwind.d.cts +36 -19
- package/dist/tailwind.d.ts +36 -19
- package/dist/tailwind.js +139 -47
- package/dist/tailwind.js.map +1 -1
- package/dist/tokens.cjs +123 -44
- package/dist/tokens.cjs.map +1 -1
- package/dist/tokens.d.cts +387 -40
- package/dist/tokens.d.ts +387 -40
- package/dist/tokens.js +122 -45
- package/dist/tokens.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
require('react');
|
|
3
|
+
var React4 = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
|
|
6
|
+
function _interopNamespace(e) {
|
|
7
|
+
if (e && e.__esModule) return e;
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
|
|
25
|
+
|
|
6
26
|
// src/components/hub-header.tsx
|
|
7
27
|
var DEFAULT_HUB_URL = "https://openkeyai.com";
|
|
8
28
|
function getInitials(name) {
|
|
@@ -88,11 +108,123 @@ function HubHeader({
|
|
|
88
108
|
}
|
|
89
109
|
);
|
|
90
110
|
}
|
|
111
|
+
var cx = (...parts) => parts.filter(Boolean).join(" ");
|
|
112
|
+
var Button = React4__namespace.forwardRef(
|
|
113
|
+
function Button2({
|
|
114
|
+
variant = "primary",
|
|
115
|
+
size = "md",
|
|
116
|
+
iconOnly = false,
|
|
117
|
+
className,
|
|
118
|
+
type = "button",
|
|
119
|
+
...rest
|
|
120
|
+
}, ref) {
|
|
121
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
122
|
+
"button",
|
|
123
|
+
{
|
|
124
|
+
ref,
|
|
125
|
+
type,
|
|
126
|
+
className: cx(
|
|
127
|
+
"okai-btn",
|
|
128
|
+
`okai-btn--${variant}`,
|
|
129
|
+
`okai-btn--${size}`,
|
|
130
|
+
iconOnly && "okai-btn--icon",
|
|
131
|
+
className
|
|
132
|
+
),
|
|
133
|
+
...rest
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
var cx2 = (...parts) => parts.filter(Boolean).join(" ");
|
|
139
|
+
var Card = React4__namespace.forwardRef(function Card2({ level = 1, interactive = false, className, ...rest }, ref) {
|
|
140
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
141
|
+
"div",
|
|
142
|
+
{
|
|
143
|
+
ref,
|
|
144
|
+
className: cx2(
|
|
145
|
+
"okai-card",
|
|
146
|
+
`okai-card--level-${level}`,
|
|
147
|
+
interactive && "okai-card--interactive",
|
|
148
|
+
className
|
|
149
|
+
),
|
|
150
|
+
...rest
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
var cx3 = (...parts) => parts.filter(Boolean).join(" ");
|
|
155
|
+
var Input = React4__namespace.forwardRef(
|
|
156
|
+
function Input2({ className, mono, ...rest }, ref) {
|
|
157
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
158
|
+
"input",
|
|
159
|
+
{
|
|
160
|
+
ref,
|
|
161
|
+
className: cx3("okai-input", mono && "okai-input--mono", className),
|
|
162
|
+
...rest
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
var Select = React4__namespace.forwardRef(
|
|
168
|
+
function Select2({ className, ...rest }, ref) {
|
|
169
|
+
return /* @__PURE__ */ jsxRuntime.jsx("select", { ref, className: cx3("okai-select", className), ...rest });
|
|
170
|
+
}
|
|
171
|
+
);
|
|
172
|
+
var Textarea = React4__namespace.forwardRef(
|
|
173
|
+
function Textarea2({ className, ...rest }, ref) {
|
|
174
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
175
|
+
"textarea",
|
|
176
|
+
{
|
|
177
|
+
ref,
|
|
178
|
+
className: cx3("okai-textarea", className),
|
|
179
|
+
...rest
|
|
180
|
+
}
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
var cx4 = (...parts) => parts.filter(Boolean).join(" ");
|
|
185
|
+
function Badge({
|
|
186
|
+
variant = "default",
|
|
187
|
+
className,
|
|
188
|
+
...rest
|
|
189
|
+
}) {
|
|
190
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
191
|
+
"span",
|
|
192
|
+
{
|
|
193
|
+
className: cx4("okai-badge", `okai-badge--${variant}`, className),
|
|
194
|
+
...rest
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
var cx5 = (...parts) => parts.filter(Boolean).join(" ");
|
|
199
|
+
function Stat({
|
|
200
|
+
label,
|
|
201
|
+
value,
|
|
202
|
+
sub,
|
|
203
|
+
icon,
|
|
204
|
+
className,
|
|
205
|
+
...rest
|
|
206
|
+
}) {
|
|
207
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx5("okai-stat", className), ...rest, children: [
|
|
208
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "okai-stat__label", children: [
|
|
209
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, children: icon }) : null,
|
|
210
|
+
label
|
|
211
|
+
] }),
|
|
212
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "okai-stat__value", children: value }),
|
|
213
|
+
sub ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "okai-stat__sub", children: sub }) : null
|
|
214
|
+
] });
|
|
215
|
+
}
|
|
91
216
|
|
|
92
217
|
// src/index.ts
|
|
93
|
-
var UI_VERSION = "
|
|
218
|
+
var UI_VERSION = "1.0.0";
|
|
94
219
|
|
|
220
|
+
exports.Badge = Badge;
|
|
221
|
+
exports.Button = Button;
|
|
222
|
+
exports.Card = Card;
|
|
95
223
|
exports.HubHeader = HubHeader;
|
|
224
|
+
exports.Input = Input;
|
|
225
|
+
exports.Select = Select;
|
|
226
|
+
exports.Stat = Stat;
|
|
227
|
+
exports.Textarea = Textarea;
|
|
96
228
|
exports.UI_VERSION = UI_VERSION;
|
|
97
229
|
//# sourceMappingURL=index.cjs.map
|
|
98
230
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/hub-header.tsx","../src/index.ts"],"names":["jsxs","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as React from \"react\";\n\n/**\n * Mandatory shared header for every OpenKey AI tool.\n *\n * What it gives the user (consistent across every tool):\n * - The hub brand mark — clicking it returns to the hub\n * - The tool's name — so users know which tool they're in\n * - The signed-in user (avatar + display name) — clicking opens the hub\n * account page\n * - A sign-in CTA when no user is provided\n *\n * What it deliberately does NOT do (per docs/TOOL_CONTRACT.md):\n * - Provide props to hide the brand mark, tool name, or user/sign-in chip\n * - Theme the colours away from the hub palette\n * - Allow the tool to swap the brand text\n *\n * The header is fixed to the top of the viewport at `z-index:\n * var(--okai-z-header)` and is `var(--okai-header-h)` tall. Tools should\n * leave that much top padding on their root layout. The styles live in\n * `@openkeyai/ui/css` — import it once in the tool's global CSS.\n *\n * SSR-safe: pure render, no client-only APIs in the default path.\n */\nexport type HubHeaderUser = {\n /** Visible label on the chip. */\n displayName: string;\n /** Optional avatar; falls back to initials when missing. */\n avatarUrl?: string | null;\n /** Used as a tooltip and accessible label. Not displayed. */\n email?: string;\n};\n\nexport type HubHeaderProps = {\n /** Display name of the tool. Goes after the divider. */\n toolName: string;\n /** Signed-in user, or null/undefined to show the Sign in CTA. */\n user?: HubHeaderUser | null;\n /** Override the hub root URL. Defaults to https://openkeyai.com. */\n hubUrl?: string;\n /** Optional right-side slot — tool-specific controls (settings, help, …).\n * Rendered BEFORE the user chip so the chip always ends the row. */\n rightSlot?: React.ReactNode;\n /** Forwarded to the outer <header>. Avoid resetting position/z-index. */\n className?: string;\n /** Optional inline style override for the outer <header>. */\n style?: React.CSSProperties;\n};\n\nconst DEFAULT_HUB_URL = \"https://openkeyai.com\";\n\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n const first = parts[0];\n if (!first) return \"?\";\n if (parts.length === 1) return first.slice(0, 2).toUpperCase();\n const last = parts[parts.length - 1] ?? first;\n return ((first[0] ?? \"\") + (last[0] ?? \"\")).toUpperCase() || \"?\";\n}\n\n/**\n * `<HubHeader />` — the mandatory header. See module doc above.\n */\nexport function HubHeader({\n toolName,\n user,\n hubUrl = DEFAULT_HUB_URL,\n rightSlot,\n className,\n style,\n}: HubHeaderProps) {\n const hubHref = hubUrl;\n const accountHref = `${hubUrl.replace(/\\/$/, \"\")}/settings/account`;\n const signInHref = `${hubUrl.replace(/\\/$/, \"\")}/login`;\n\n return (\n <header\n className={\n className ? `okai-header ${className}` : \"okai-header\"\n }\n style={style}\n role=\"banner\"\n data-okai-component=\"hub-header\"\n >\n <a\n className=\"okai-header__brand\"\n href={hubHref}\n aria-label=\"Open OpenKey AI hub\"\n >\n <span className=\"okai-header__brand-mark\" aria-hidden=\"true\" />\n <span className=\"okai-header__brand-text\">OpenKey AI</span>\n </a>\n\n <span className=\"okai-header__divider\" aria-hidden=\"true\" />\n\n <span className=\"okai-header__tool-name\" title={toolName}>\n {toolName}\n </span>\n\n <span className=\"okai-header__spacer\" aria-hidden=\"true\" />\n\n {rightSlot != null ? (\n <div className=\"okai-header__right\">{rightSlot}</div>\n ) : null}\n\n {user ? (\n <a\n className=\"okai-header__user\"\n href={accountHref}\n title={user.email ?? user.displayName}\n aria-label={`Open account for ${user.displayName}`}\n >\n {user.avatarUrl ? (\n <span\n className=\"okai-header__user-avatar\"\n role=\"img\"\n aria-label={user.displayName}\n style={{ backgroundImage: `url(${user.avatarUrl})` }}\n />\n ) : (\n <span\n className=\"okai-header__user-fallback\"\n aria-hidden=\"true\"\n >\n {getInitials(user.displayName)}\n </span>\n )}\n <span className=\"okai-header__user-name\">{user.displayName}</span>\n </a>\n ) : (\n <a\n className=\"okai-header__signin\"\n href={signInHref}\n aria-label=\"Sign in to OpenKey AI\"\n >\n Sign in\n </a>\n )}\n </header>\n );\n}\n","/**\n * `@openkeyai/ui` — public entry.\n *\n * Every OpenKey AI tool installs this package and mounts <HubHeader /> in\n * its root layout. CI in `Scott-Builds-AI/.github` enforces the mounting\n * via an AST scanner (lands in Phase 9).\n *\n * Entry paths:\n * - \"@openkeyai/ui\" → React components + their types (this file)\n * - \"@openkeyai/ui/tokens\" → Design tokens as a JS object\n * - \"@openkeyai/ui/tailwind\" → Tailwind preset\n * - \"@openkeyai/ui/css\" → The global stylesheet (CSS custom\n * properties + scoped .okai-* classes).\n * MUST be imported once by the consumer.\n *\n * See README.md for the canonical mounting pattern.\n */\n\nexport { HubHeader } from \"./components/hub-header\";\nexport type {\n HubHeaderProps,\n HubHeaderUser,\n} from \"./components/hub-header\";\n\n/** Bumped on each release. Useful for tools to log which UI version they shipped against. */\nexport const UI_VERSION = \"0.1.0\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/hub-header.tsx","../src/components/button.tsx","../src/components/card.tsx","../src/components/input.tsx","../src/components/badge.tsx","../src/components/stat.tsx","../src/index.ts"],"names":["jsxs","jsx","React2","Button","cx","React3","Card","React4","Input","Select","Textarea"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as React from \"react\";\n\n/**\n * Mandatory shared header for every OpenKey AI tool.\n *\n * What it gives the user (consistent across every tool):\n * - The hub brand mark — clicking it returns to the hub\n * - The tool's name — so users know which tool they're in\n * - The signed-in user (avatar + display name) — clicking opens the hub\n * account page\n * - A sign-in CTA when no user is provided\n *\n * What it deliberately does NOT do (per docs/TOOL_CONTRACT.md):\n * - Provide props to hide the brand mark, tool name, or user/sign-in chip\n * - Theme the colours away from the hub palette\n * - Allow the tool to swap the brand text\n *\n * The header is fixed to the top of the viewport at `z-index:\n * var(--okai-z-header)` and is `var(--okai-header-h)` tall. Tools should\n * leave that much top padding on their root layout. The styles live in\n * `@openkeyai/ui/css` — import it once in the tool's global CSS.\n *\n * SSR-safe: pure render, no client-only APIs in the default path.\n */\nexport type HubHeaderUser = {\n /** Visible label on the chip. */\n displayName: string;\n /** Optional avatar; falls back to initials when missing. */\n avatarUrl?: string | null;\n /** Used as a tooltip and accessible label. Not displayed. */\n email?: string;\n};\n\nexport type HubHeaderProps = {\n /** Display name of the tool. Goes after the divider. */\n toolName: string;\n /** Signed-in user, or null/undefined to show the Sign in CTA. */\n user?: HubHeaderUser | null;\n /** Override the hub root URL. Defaults to https://openkeyai.com. */\n hubUrl?: string;\n /** Optional right-side slot — tool-specific controls (settings, help, …).\n * Rendered BEFORE the user chip so the chip always ends the row. */\n rightSlot?: React.ReactNode;\n /** Forwarded to the outer <header>. Avoid resetting position/z-index. */\n className?: string;\n /** Optional inline style override for the outer <header>. */\n style?: React.CSSProperties;\n};\n\nconst DEFAULT_HUB_URL = \"https://openkeyai.com\";\n\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n const first = parts[0];\n if (!first) return \"?\";\n if (parts.length === 1) return first.slice(0, 2).toUpperCase();\n const last = parts[parts.length - 1] ?? first;\n return ((first[0] ?? \"\") + (last[0] ?? \"\")).toUpperCase() || \"?\";\n}\n\n/**\n * `<HubHeader />` — the mandatory header. See module doc above.\n */\nexport function HubHeader({\n toolName,\n user,\n hubUrl = DEFAULT_HUB_URL,\n rightSlot,\n className,\n style,\n}: HubHeaderProps) {\n const hubHref = hubUrl;\n const accountHref = `${hubUrl.replace(/\\/$/, \"\")}/settings/account`;\n const signInHref = `${hubUrl.replace(/\\/$/, \"\")}/login`;\n\n return (\n <header\n className={\n className ? `okai-header ${className}` : \"okai-header\"\n }\n style={style}\n role=\"banner\"\n data-okai-component=\"hub-header\"\n >\n <a\n className=\"okai-header__brand\"\n href={hubHref}\n aria-label=\"Open OpenKey AI hub\"\n >\n <span className=\"okai-header__brand-mark\" aria-hidden=\"true\" />\n <span className=\"okai-header__brand-text\">OpenKey AI</span>\n </a>\n\n <span className=\"okai-header__divider\" aria-hidden=\"true\" />\n\n <span className=\"okai-header__tool-name\" title={toolName}>\n {toolName}\n </span>\n\n <span className=\"okai-header__spacer\" aria-hidden=\"true\" />\n\n {rightSlot != null ? (\n <div className=\"okai-header__right\">{rightSlot}</div>\n ) : null}\n\n {user ? (\n <a\n className=\"okai-header__user\"\n href={accountHref}\n title={user.email ?? user.displayName}\n aria-label={`Open account for ${user.displayName}`}\n >\n {user.avatarUrl ? (\n <span\n className=\"okai-header__user-avatar\"\n role=\"img\"\n aria-label={user.displayName}\n style={{ backgroundImage: `url(${user.avatarUrl})` }}\n />\n ) : (\n <span\n className=\"okai-header__user-fallback\"\n aria-hidden=\"true\"\n >\n {getInitials(user.displayName)}\n </span>\n )}\n <span className=\"okai-header__user-name\">{user.displayName}</span>\n </a>\n ) : (\n <a\n className=\"okai-header__signin\"\n href={signInHref}\n aria-label=\"Sign in to OpenKey AI\"\n >\n Sign in\n </a>\n )}\n </header>\n );\n}\n","import * as React from \"react\";\n\n/**\n * `<Button>` — base interaction primitive.\n *\n * Five variants × three sizes:\n * - `primary` — solid brand fill. Default CTAs.\n * - `secondary` — outlined. Pair with a primary, never alone as the\n * only action on a surface.\n * - `tonal` — Material 3 tonal: brand-tinted container with\n * readable foreground. Use for emphasised non-primary actions.\n * - `text` — no border, no fill. Inline links inside dense UI.\n * - `destructive` — danger color. Confirm-destruction dialogs.\n *\n * Pass `iconOnly` for square aspect-ratio buttons (toolbars, icon\n * pills). The label slot still acts as the accessible name.\n *\n * Renders a real `<button>` by default — pass `asChild` to render the\n * children as the root element (e.g. `<Link>` from your router).\n */\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"tonal\"\n | \"text\"\n | \"destructive\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\";\n\nexport type ButtonProps = Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"className\"\n> & {\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** Square button with no horizontal padding — children should be a single icon. */\n iconOnly?: boolean;\n /** Additional className stacked on top of `okai-btn` modifiers. */\n className?: string;\n};\n\nconst cx = (...parts: Array<string | false | null | undefined>) =>\n parts.filter(Boolean).join(\" \");\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n function Button(\n {\n variant = \"primary\",\n size = \"md\",\n iconOnly = false,\n className,\n type = \"button\",\n ...rest\n },\n ref,\n ) {\n return (\n <button\n ref={ref}\n type={type}\n className={cx(\n \"okai-btn\",\n `okai-btn--${variant}`,\n `okai-btn--${size}`,\n iconOnly && \"okai-btn--icon\",\n className,\n )}\n {...rest}\n />\n );\n },\n);\n","import * as React from \"react\";\n\n/**\n * `<Card>` — surface primitive.\n *\n * Four elevation levels matching the hub's Material 3 tonal model:\n *\n * - `0` — flat, inline with the page. No border, no shadow.\n * - `1` — default card. Single subtle shadow + surface lift.\n * - `2` — nested cards (inside another card). Stronger surface lift.\n * - `3` — floating elements (popovers, toasts). Visible shadow.\n *\n * `interactive` makes the card hover-aware (cursor pointer + background\n * shift). Wrap a router `<Link>` around it for click-through cards, or\n * use the `as` prop to render a custom element.\n */\nexport type CardLevel = 0 | 1 | 2 | 3;\n\nexport type CardProps = Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"className\"\n> & {\n level?: CardLevel;\n interactive?: boolean;\n className?: string;\n};\n\nconst cx = (...parts: Array<string | false | null | undefined>) =>\n parts.filter(Boolean).join(\" \");\n\nexport const Card = React.forwardRef<HTMLDivElement, CardProps>(function Card(\n { level = 1, interactive = false, className, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n className={cx(\n \"okai-card\",\n `okai-card--level-${level}`,\n interactive && \"okai-card--interactive\",\n className,\n )}\n {...rest}\n />\n );\n});\n","import * as React from \"react\";\n\n/**\n * Form controls — `<Input>`, `<Select>`, `<Textarea>`.\n *\n * Plain forwardable wrappers around the native elements with the\n * matching `okai-*` class. Use `mono` on `<Input>` for monospace fields\n * (slugs, ids, tokens).\n *\n * Validation + accessible labels are the consumer's responsibility — we\n * don't ship a `<Form />` wrapper.\n */\n\nconst cx = (...parts: Array<string | false | null | undefined>) =>\n parts.filter(Boolean).join(\" \");\n\nexport type InputProps = Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"className\"\n> & {\n className?: string;\n /** Use monospace face — for slugs, ids, tokens. */\n mono?: boolean;\n};\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n function Input({ className, mono, ...rest }, ref) {\n return (\n <input\n ref={ref}\n className={cx(\"okai-input\", mono && \"okai-input--mono\", className)}\n {...rest}\n />\n );\n },\n);\n\nexport type SelectProps = Omit<\n React.SelectHTMLAttributes<HTMLSelectElement>,\n \"className\"\n> & {\n className?: string;\n};\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(\n function Select({ className, ...rest }, ref) {\n return (\n <select ref={ref} className={cx(\"okai-select\", className)} {...rest} />\n );\n },\n);\n\nexport type TextareaProps = Omit<\n React.TextareaHTMLAttributes<HTMLTextAreaElement>,\n \"className\"\n> & {\n className?: string;\n};\n\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n function Textarea({ className, ...rest }, ref) {\n return (\n <textarea\n ref={ref}\n className={cx(\"okai-textarea\", className)}\n {...rest}\n />\n );\n },\n);\n","import * as React from \"react\";\n\n/**\n * `<Badge>` — pill for status, tags, identifiers.\n *\n * Six variants:\n * - `default` — neutral grey tint\n * - `brand` — brand-tinted (Material 3 container surface)\n * - `success` — sage. \\\"Operational\\\", \\\"Approved\\\".\n * - `warning` — amber. \\\"Monitoring\\\", \\\"Pending review\\\".\n * - `danger` — coral. \\\"Failed\\\", \\\"Suspended\\\".\n * - `monitoring` — slightly softer warning. \\\"Watching\\\".\n */\nexport type BadgeVariant =\n | \"default\"\n | \"brand\"\n | \"success\"\n | \"warning\"\n | \"danger\"\n | \"monitoring\";\n\nexport type BadgeProps = Omit<\n React.HTMLAttributes<HTMLSpanElement>,\n \"className\"\n> & {\n variant?: BadgeVariant;\n className?: string;\n};\n\nconst cx = (...parts: Array<string | false | null | undefined>) =>\n parts.filter(Boolean).join(\" \");\n\nexport function Badge({\n variant = \"default\",\n className,\n ...rest\n}: BadgeProps) {\n return (\n <span\n className={cx(\"okai-badge\", `okai-badge--${variant}`, className)}\n {...rest}\n />\n );\n}\n","import * as React from \"react\";\n\n/**\n * `<Stat>` — big numeric value + tiny uppercase label.\n *\n * Used in tool-owner dashboards, /status pages, admin counters. The\n * value renders in monospace + tabular-nums so digits don't shift\n * when the number ticks.\n *\n * <Stat label=\"Subscribers\" value=\"1,284\" />\n * <Stat label=\"Active 30d\" value=\"98\" sub=\"across 12 tools\" />\n * <Stat label=\"MRR\" value=\"£3,852\" icon={<TrendingUp />} />\n */\nexport type StatProps = Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"className\" | \"children\"\n> & {\n label: React.ReactNode;\n value: React.ReactNode;\n /** Optional smaller line under the value. */\n sub?: React.ReactNode;\n /** Optional icon rendered before the label. */\n icon?: React.ReactNode;\n className?: string;\n};\n\nconst cx = (...parts: Array<string | false | null | undefined>) =>\n parts.filter(Boolean).join(\" \");\n\nexport function Stat({\n label,\n value,\n sub,\n icon,\n className,\n ...rest\n}: StatProps) {\n return (\n <div className={cx(\"okai-stat\", className)} {...rest}>\n <span className=\"okai-stat__label\">\n {icon ? <span aria-hidden>{icon}</span> : null}\n {label}\n </span>\n <span className=\"okai-stat__value\">{value}</span>\n {sub ? <span className=\"okai-stat__sub\">{sub}</span> : null}\n </div>\n );\n}\n","/**\n * `@openkeyai/ui` — public entry.\n *\n * Every OpenKey AI tool installs this package and mounts <HubHeader /> in\n * its root layout. CI enforces the mounting via an AST scanner\n * (see Phase 9 in the hub's BUILD_PLAN.md).\n *\n * **v1.0.0** — Major version. Palette swap (cool indigo → warm coral),\n * Material 3 elevation, light + dark themes, Roboto Flex display, plus\n * base components: `<Button>`, `<Card>`, `<Input>`, `<Select>`,\n * `<Textarea>`, `<Badge>`, `<Stat>`. Existing v0.x token NAMES are\n * preserved — only color values shifted.\n *\n * Entry paths:\n * - \"@openkeyai/ui\" → React components + their types (this file)\n * - \"@openkeyai/ui/tokens\" → Design tokens as a JS object\n * (dark + light + shared)\n * - \"@openkeyai/ui/tailwind\" → Tailwind preset\n * - \"@openkeyai/ui/css\" → The global stylesheet (CSS custom\n * properties + scoped .okai-* classes).\n * MUST be imported once by the consumer.\n *\n * See README.md for the canonical mounting pattern + migration guide.\n */\n\nexport { HubHeader } from \"./components/hub-header\";\nexport type {\n HubHeaderProps,\n HubHeaderUser,\n} from \"./components/hub-header\";\n\nexport { Button } from \"./components/button\";\nexport type { ButtonProps, ButtonSize, ButtonVariant } from \"./components/button\";\n\nexport { Card } from \"./components/card\";\nexport type { CardLevel, CardProps } from \"./components/card\";\n\nexport { Input, Select, Textarea } from \"./components/input\";\nexport type {\n InputProps,\n SelectProps,\n TextareaProps,\n} from \"./components/input\";\n\nexport { Badge } from \"./components/badge\";\nexport type { BadgeProps, BadgeVariant } from \"./components/badge\";\n\nexport { Stat } from \"./components/stat\";\nexport type { StatProps } from \"./components/stat\";\n\n/** Bumped on each release. Useful for tools to log which UI version they shipped against. */\nexport const UI_VERSION = \"1.0.0\";\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -50,25 +50,158 @@ type HubHeaderProps = {
|
|
|
50
50
|
*/
|
|
51
51
|
declare function HubHeader({ toolName, user, hubUrl, rightSlot, className, style, }: HubHeaderProps): React.JSX.Element;
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* `<Button>` — base interaction primitive.
|
|
55
|
+
*
|
|
56
|
+
* Five variants × three sizes:
|
|
57
|
+
* - `primary` — solid brand fill. Default CTAs.
|
|
58
|
+
* - `secondary` — outlined. Pair with a primary, never alone as the
|
|
59
|
+
* only action on a surface.
|
|
60
|
+
* - `tonal` — Material 3 tonal: brand-tinted container with
|
|
61
|
+
* readable foreground. Use for emphasised non-primary actions.
|
|
62
|
+
* - `text` — no border, no fill. Inline links inside dense UI.
|
|
63
|
+
* - `destructive` — danger color. Confirm-destruction dialogs.
|
|
64
|
+
*
|
|
65
|
+
* Pass `iconOnly` for square aspect-ratio buttons (toolbars, icon
|
|
66
|
+
* pills). The label slot still acts as the accessible name.
|
|
67
|
+
*
|
|
68
|
+
* Renders a real `<button>` by default — pass `asChild` to render the
|
|
69
|
+
* children as the root element (e.g. `<Link>` from your router).
|
|
70
|
+
*/
|
|
71
|
+
type ButtonVariant = "primary" | "secondary" | "tonal" | "text" | "destructive";
|
|
72
|
+
type ButtonSize = "sm" | "md" | "lg";
|
|
73
|
+
type ButtonProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "className"> & {
|
|
74
|
+
variant?: ButtonVariant;
|
|
75
|
+
size?: ButtonSize;
|
|
76
|
+
/** Square button with no horizontal padding — children should be a single icon. */
|
|
77
|
+
iconOnly?: boolean;
|
|
78
|
+
/** Additional className stacked on top of `okai-btn` modifiers. */
|
|
79
|
+
className?: string;
|
|
80
|
+
};
|
|
81
|
+
declare const Button: React.ForwardRefExoticComponent<Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "className"> & {
|
|
82
|
+
variant?: ButtonVariant;
|
|
83
|
+
size?: ButtonSize;
|
|
84
|
+
/** Square button with no horizontal padding — children should be a single icon. */
|
|
85
|
+
iconOnly?: boolean;
|
|
86
|
+
/** Additional className stacked on top of `okai-btn` modifiers. */
|
|
87
|
+
className?: string;
|
|
88
|
+
} & React.RefAttributes<HTMLButtonElement>>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* `<Card>` — surface primitive.
|
|
92
|
+
*
|
|
93
|
+
* Four elevation levels matching the hub's Material 3 tonal model:
|
|
94
|
+
*
|
|
95
|
+
* - `0` — flat, inline with the page. No border, no shadow.
|
|
96
|
+
* - `1` — default card. Single subtle shadow + surface lift.
|
|
97
|
+
* - `2` — nested cards (inside another card). Stronger surface lift.
|
|
98
|
+
* - `3` — floating elements (popovers, toasts). Visible shadow.
|
|
99
|
+
*
|
|
100
|
+
* `interactive` makes the card hover-aware (cursor pointer + background
|
|
101
|
+
* shift). Wrap a router `<Link>` around it for click-through cards, or
|
|
102
|
+
* use the `as` prop to render a custom element.
|
|
103
|
+
*/
|
|
104
|
+
type CardLevel = 0 | 1 | 2 | 3;
|
|
105
|
+
type CardProps = Omit<React.HTMLAttributes<HTMLDivElement>, "className"> & {
|
|
106
|
+
level?: CardLevel;
|
|
107
|
+
interactive?: boolean;
|
|
108
|
+
className?: string;
|
|
109
|
+
};
|
|
110
|
+
declare const Card: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "className"> & {
|
|
111
|
+
level?: CardLevel;
|
|
112
|
+
interactive?: boolean;
|
|
113
|
+
className?: string;
|
|
114
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
115
|
+
|
|
116
|
+
type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, "className"> & {
|
|
117
|
+
className?: string;
|
|
118
|
+
/** Use monospace face — for slugs, ids, tokens. */
|
|
119
|
+
mono?: boolean;
|
|
120
|
+
};
|
|
121
|
+
declare const Input: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<HTMLInputElement>, "className"> & {
|
|
122
|
+
className?: string;
|
|
123
|
+
/** Use monospace face — for slugs, ids, tokens. */
|
|
124
|
+
mono?: boolean;
|
|
125
|
+
} & React.RefAttributes<HTMLInputElement>>;
|
|
126
|
+
type SelectProps = Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "className"> & {
|
|
127
|
+
className?: string;
|
|
128
|
+
};
|
|
129
|
+
declare const Select: React.ForwardRefExoticComponent<Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "className"> & {
|
|
130
|
+
className?: string;
|
|
131
|
+
} & React.RefAttributes<HTMLSelectElement>>;
|
|
132
|
+
type TextareaProps = Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "className"> & {
|
|
133
|
+
className?: string;
|
|
134
|
+
};
|
|
135
|
+
declare const Textarea: React.ForwardRefExoticComponent<Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "className"> & {
|
|
136
|
+
className?: string;
|
|
137
|
+
} & React.RefAttributes<HTMLTextAreaElement>>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* `<Badge>` — pill for status, tags, identifiers.
|
|
141
|
+
*
|
|
142
|
+
* Six variants:
|
|
143
|
+
* - `default` — neutral grey tint
|
|
144
|
+
* - `brand` — brand-tinted (Material 3 container surface)
|
|
145
|
+
* - `success` — sage. \"Operational\", \"Approved\".
|
|
146
|
+
* - `warning` — amber. \"Monitoring\", \"Pending review\".
|
|
147
|
+
* - `danger` — coral. \"Failed\", \"Suspended\".
|
|
148
|
+
* - `monitoring` — slightly softer warning. \"Watching\".
|
|
149
|
+
*/
|
|
150
|
+
type BadgeVariant = "default" | "brand" | "success" | "warning" | "danger" | "monitoring";
|
|
151
|
+
type BadgeProps = Omit<React.HTMLAttributes<HTMLSpanElement>, "className"> & {
|
|
152
|
+
variant?: BadgeVariant;
|
|
153
|
+
className?: string;
|
|
154
|
+
};
|
|
155
|
+
declare function Badge({ variant, className, ...rest }: BadgeProps): React.JSX.Element;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* `<Stat>` — big numeric value + tiny uppercase label.
|
|
159
|
+
*
|
|
160
|
+
* Used in tool-owner dashboards, /status pages, admin counters. The
|
|
161
|
+
* value renders in monospace + tabular-nums so digits don't shift
|
|
162
|
+
* when the number ticks.
|
|
163
|
+
*
|
|
164
|
+
* <Stat label="Subscribers" value="1,284" />
|
|
165
|
+
* <Stat label="Active 30d" value="98" sub="across 12 tools" />
|
|
166
|
+
* <Stat label="MRR" value="£3,852" icon={<TrendingUp />} />
|
|
167
|
+
*/
|
|
168
|
+
type StatProps = Omit<React.HTMLAttributes<HTMLDivElement>, "className" | "children"> & {
|
|
169
|
+
label: React.ReactNode;
|
|
170
|
+
value: React.ReactNode;
|
|
171
|
+
/** Optional smaller line under the value. */
|
|
172
|
+
sub?: React.ReactNode;
|
|
173
|
+
/** Optional icon rendered before the label. */
|
|
174
|
+
icon?: React.ReactNode;
|
|
175
|
+
className?: string;
|
|
176
|
+
};
|
|
177
|
+
declare function Stat({ label, value, sub, icon, className, ...rest }: StatProps): React.JSX.Element;
|
|
178
|
+
|
|
53
179
|
/**
|
|
54
180
|
* `@openkeyai/ui` — public entry.
|
|
55
181
|
*
|
|
56
182
|
* Every OpenKey AI tool installs this package and mounts <HubHeader /> in
|
|
57
|
-
* its root layout. CI
|
|
58
|
-
*
|
|
183
|
+
* its root layout. CI enforces the mounting via an AST scanner
|
|
184
|
+
* (see Phase 9 in the hub's BUILD_PLAN.md).
|
|
185
|
+
*
|
|
186
|
+
* **v1.0.0** — Major version. Palette swap (cool indigo → warm coral),
|
|
187
|
+
* Material 3 elevation, light + dark themes, Roboto Flex display, plus
|
|
188
|
+
* base components: `<Button>`, `<Card>`, `<Input>`, `<Select>`,
|
|
189
|
+
* `<Textarea>`, `<Badge>`, `<Stat>`. Existing v0.x token NAMES are
|
|
190
|
+
* preserved — only color values shifted.
|
|
59
191
|
*
|
|
60
192
|
* Entry paths:
|
|
61
193
|
* - "@openkeyai/ui" → React components + their types (this file)
|
|
62
194
|
* - "@openkeyai/ui/tokens" → Design tokens as a JS object
|
|
195
|
+
* (dark + light + shared)
|
|
63
196
|
* - "@openkeyai/ui/tailwind" → Tailwind preset
|
|
64
197
|
* - "@openkeyai/ui/css" → The global stylesheet (CSS custom
|
|
65
198
|
* properties + scoped .okai-* classes).
|
|
66
199
|
* MUST be imported once by the consumer.
|
|
67
200
|
*
|
|
68
|
-
* See README.md for the canonical mounting pattern.
|
|
201
|
+
* See README.md for the canonical mounting pattern + migration guide.
|
|
69
202
|
*/
|
|
70
203
|
|
|
71
204
|
/** Bumped on each release. Useful for tools to log which UI version they shipped against. */
|
|
72
|
-
declare const UI_VERSION = "
|
|
205
|
+
declare const UI_VERSION = "1.0.0";
|
|
73
206
|
|
|
74
|
-
export { HubHeader, type HubHeaderProps, type HubHeaderUser, UI_VERSION };
|
|
207
|
+
export { Badge, type BadgeProps, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, type CardLevel, type CardProps, HubHeader, type HubHeaderProps, type HubHeaderUser, Input, type InputProps, Select, type SelectProps, Stat, type StatProps, Textarea, type TextareaProps, UI_VERSION };
|
package/dist/index.d.ts
CHANGED
|
@@ -50,25 +50,158 @@ type HubHeaderProps = {
|
|
|
50
50
|
*/
|
|
51
51
|
declare function HubHeader({ toolName, user, hubUrl, rightSlot, className, style, }: HubHeaderProps): React.JSX.Element;
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* `<Button>` — base interaction primitive.
|
|
55
|
+
*
|
|
56
|
+
* Five variants × three sizes:
|
|
57
|
+
* - `primary` — solid brand fill. Default CTAs.
|
|
58
|
+
* - `secondary` — outlined. Pair with a primary, never alone as the
|
|
59
|
+
* only action on a surface.
|
|
60
|
+
* - `tonal` — Material 3 tonal: brand-tinted container with
|
|
61
|
+
* readable foreground. Use for emphasised non-primary actions.
|
|
62
|
+
* - `text` — no border, no fill. Inline links inside dense UI.
|
|
63
|
+
* - `destructive` — danger color. Confirm-destruction dialogs.
|
|
64
|
+
*
|
|
65
|
+
* Pass `iconOnly` for square aspect-ratio buttons (toolbars, icon
|
|
66
|
+
* pills). The label slot still acts as the accessible name.
|
|
67
|
+
*
|
|
68
|
+
* Renders a real `<button>` by default — pass `asChild` to render the
|
|
69
|
+
* children as the root element (e.g. `<Link>` from your router).
|
|
70
|
+
*/
|
|
71
|
+
type ButtonVariant = "primary" | "secondary" | "tonal" | "text" | "destructive";
|
|
72
|
+
type ButtonSize = "sm" | "md" | "lg";
|
|
73
|
+
type ButtonProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "className"> & {
|
|
74
|
+
variant?: ButtonVariant;
|
|
75
|
+
size?: ButtonSize;
|
|
76
|
+
/** Square button with no horizontal padding — children should be a single icon. */
|
|
77
|
+
iconOnly?: boolean;
|
|
78
|
+
/** Additional className stacked on top of `okai-btn` modifiers. */
|
|
79
|
+
className?: string;
|
|
80
|
+
};
|
|
81
|
+
declare const Button: React.ForwardRefExoticComponent<Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "className"> & {
|
|
82
|
+
variant?: ButtonVariant;
|
|
83
|
+
size?: ButtonSize;
|
|
84
|
+
/** Square button with no horizontal padding — children should be a single icon. */
|
|
85
|
+
iconOnly?: boolean;
|
|
86
|
+
/** Additional className stacked on top of `okai-btn` modifiers. */
|
|
87
|
+
className?: string;
|
|
88
|
+
} & React.RefAttributes<HTMLButtonElement>>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* `<Card>` — surface primitive.
|
|
92
|
+
*
|
|
93
|
+
* Four elevation levels matching the hub's Material 3 tonal model:
|
|
94
|
+
*
|
|
95
|
+
* - `0` — flat, inline with the page. No border, no shadow.
|
|
96
|
+
* - `1` — default card. Single subtle shadow + surface lift.
|
|
97
|
+
* - `2` — nested cards (inside another card). Stronger surface lift.
|
|
98
|
+
* - `3` — floating elements (popovers, toasts). Visible shadow.
|
|
99
|
+
*
|
|
100
|
+
* `interactive` makes the card hover-aware (cursor pointer + background
|
|
101
|
+
* shift). Wrap a router `<Link>` around it for click-through cards, or
|
|
102
|
+
* use the `as` prop to render a custom element.
|
|
103
|
+
*/
|
|
104
|
+
type CardLevel = 0 | 1 | 2 | 3;
|
|
105
|
+
type CardProps = Omit<React.HTMLAttributes<HTMLDivElement>, "className"> & {
|
|
106
|
+
level?: CardLevel;
|
|
107
|
+
interactive?: boolean;
|
|
108
|
+
className?: string;
|
|
109
|
+
};
|
|
110
|
+
declare const Card: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "className"> & {
|
|
111
|
+
level?: CardLevel;
|
|
112
|
+
interactive?: boolean;
|
|
113
|
+
className?: string;
|
|
114
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
115
|
+
|
|
116
|
+
type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, "className"> & {
|
|
117
|
+
className?: string;
|
|
118
|
+
/** Use monospace face — for slugs, ids, tokens. */
|
|
119
|
+
mono?: boolean;
|
|
120
|
+
};
|
|
121
|
+
declare const Input: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<HTMLInputElement>, "className"> & {
|
|
122
|
+
className?: string;
|
|
123
|
+
/** Use monospace face — for slugs, ids, tokens. */
|
|
124
|
+
mono?: boolean;
|
|
125
|
+
} & React.RefAttributes<HTMLInputElement>>;
|
|
126
|
+
type SelectProps = Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "className"> & {
|
|
127
|
+
className?: string;
|
|
128
|
+
};
|
|
129
|
+
declare const Select: React.ForwardRefExoticComponent<Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "className"> & {
|
|
130
|
+
className?: string;
|
|
131
|
+
} & React.RefAttributes<HTMLSelectElement>>;
|
|
132
|
+
type TextareaProps = Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "className"> & {
|
|
133
|
+
className?: string;
|
|
134
|
+
};
|
|
135
|
+
declare const Textarea: React.ForwardRefExoticComponent<Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "className"> & {
|
|
136
|
+
className?: string;
|
|
137
|
+
} & React.RefAttributes<HTMLTextAreaElement>>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* `<Badge>` — pill for status, tags, identifiers.
|
|
141
|
+
*
|
|
142
|
+
* Six variants:
|
|
143
|
+
* - `default` — neutral grey tint
|
|
144
|
+
* - `brand` — brand-tinted (Material 3 container surface)
|
|
145
|
+
* - `success` — sage. \"Operational\", \"Approved\".
|
|
146
|
+
* - `warning` — amber. \"Monitoring\", \"Pending review\".
|
|
147
|
+
* - `danger` — coral. \"Failed\", \"Suspended\".
|
|
148
|
+
* - `monitoring` — slightly softer warning. \"Watching\".
|
|
149
|
+
*/
|
|
150
|
+
type BadgeVariant = "default" | "brand" | "success" | "warning" | "danger" | "monitoring";
|
|
151
|
+
type BadgeProps = Omit<React.HTMLAttributes<HTMLSpanElement>, "className"> & {
|
|
152
|
+
variant?: BadgeVariant;
|
|
153
|
+
className?: string;
|
|
154
|
+
};
|
|
155
|
+
declare function Badge({ variant, className, ...rest }: BadgeProps): React.JSX.Element;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* `<Stat>` — big numeric value + tiny uppercase label.
|
|
159
|
+
*
|
|
160
|
+
* Used in tool-owner dashboards, /status pages, admin counters. The
|
|
161
|
+
* value renders in monospace + tabular-nums so digits don't shift
|
|
162
|
+
* when the number ticks.
|
|
163
|
+
*
|
|
164
|
+
* <Stat label="Subscribers" value="1,284" />
|
|
165
|
+
* <Stat label="Active 30d" value="98" sub="across 12 tools" />
|
|
166
|
+
* <Stat label="MRR" value="£3,852" icon={<TrendingUp />} />
|
|
167
|
+
*/
|
|
168
|
+
type StatProps = Omit<React.HTMLAttributes<HTMLDivElement>, "className" | "children"> & {
|
|
169
|
+
label: React.ReactNode;
|
|
170
|
+
value: React.ReactNode;
|
|
171
|
+
/** Optional smaller line under the value. */
|
|
172
|
+
sub?: React.ReactNode;
|
|
173
|
+
/** Optional icon rendered before the label. */
|
|
174
|
+
icon?: React.ReactNode;
|
|
175
|
+
className?: string;
|
|
176
|
+
};
|
|
177
|
+
declare function Stat({ label, value, sub, icon, className, ...rest }: StatProps): React.JSX.Element;
|
|
178
|
+
|
|
53
179
|
/**
|
|
54
180
|
* `@openkeyai/ui` — public entry.
|
|
55
181
|
*
|
|
56
182
|
* Every OpenKey AI tool installs this package and mounts <HubHeader /> in
|
|
57
|
-
* its root layout. CI
|
|
58
|
-
*
|
|
183
|
+
* its root layout. CI enforces the mounting via an AST scanner
|
|
184
|
+
* (see Phase 9 in the hub's BUILD_PLAN.md).
|
|
185
|
+
*
|
|
186
|
+
* **v1.0.0** — Major version. Palette swap (cool indigo → warm coral),
|
|
187
|
+
* Material 3 elevation, light + dark themes, Roboto Flex display, plus
|
|
188
|
+
* base components: `<Button>`, `<Card>`, `<Input>`, `<Select>`,
|
|
189
|
+
* `<Textarea>`, `<Badge>`, `<Stat>`. Existing v0.x token NAMES are
|
|
190
|
+
* preserved — only color values shifted.
|
|
59
191
|
*
|
|
60
192
|
* Entry paths:
|
|
61
193
|
* - "@openkeyai/ui" → React components + their types (this file)
|
|
62
194
|
* - "@openkeyai/ui/tokens" → Design tokens as a JS object
|
|
195
|
+
* (dark + light + shared)
|
|
63
196
|
* - "@openkeyai/ui/tailwind" → Tailwind preset
|
|
64
197
|
* - "@openkeyai/ui/css" → The global stylesheet (CSS custom
|
|
65
198
|
* properties + scoped .okai-* classes).
|
|
66
199
|
* MUST be imported once by the consumer.
|
|
67
200
|
*
|
|
68
|
-
* See README.md for the canonical mounting pattern.
|
|
201
|
+
* See README.md for the canonical mounting pattern + migration guide.
|
|
69
202
|
*/
|
|
70
203
|
|
|
71
204
|
/** Bumped on each release. Useful for tools to log which UI version they shipped against. */
|
|
72
|
-
declare const UI_VERSION = "
|
|
205
|
+
declare const UI_VERSION = "1.0.0";
|
|
73
206
|
|
|
74
|
-
export { HubHeader, type HubHeaderProps, type HubHeaderUser, UI_VERSION };
|
|
207
|
+
export { Badge, type BadgeProps, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, type CardLevel, type CardProps, HubHeader, type HubHeaderProps, type HubHeaderUser, Input, type InputProps, Select, type SelectProps, Stat, type StatProps, Textarea, type TextareaProps, UI_VERSION };
|