@webmcpui/react 0.3.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/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # @webmcpui/react
2
+
3
+ Idiomatic, typed **React** components for [webmcpui](https://webmcpui.com) —
4
+ WebMCP-native, accessible, shadcn/Tailwind-aligned.
5
+
6
+ Each component wraps the corresponding [`@webmcpui/core`](https://www.npmjs.com/package/@webmcpui/core)
7
+ custom element via [`@lit/react`](https://www.npmjs.com/package/@lit/react), so
8
+ the WebMCP tool exposure, form association, and accessibility live **once** (in
9
+ core) and you get typed props, `ref` forwarding, and `on*` event handlers.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pnpm add @webmcpui/react @webmcpui/core react react-dom
15
+ # optional theme (shadcn-aligned):
16
+ pnpm add @webmcpui/tokens
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```tsx
22
+ import { Button, Input, Dialog, Tabs } from '@webmcpui/react';
23
+ import '@webmcpui/tokens/css'; // omit for an unstyled baseline (see below)
24
+
25
+ function Example() {
26
+ const [email, setEmail] = React.useState('');
27
+ const [open, setOpen] = React.useState(false);
28
+
29
+ return (
30
+ <>
31
+ <Button variant="primary" onClick={() => setOpen(true)}>Book</Button>
32
+
33
+ {/* form control — expose it and an agent can fill it */}
34
+ <Input label="Email" type="email" value={email}
35
+ onInput={(e) => setEmail(e.currentTarget.value)} expose />
36
+
37
+ {/* the agent opens it; the human confirms */}
38
+ <Dialog open={open} label="Confirm" onClose={() => setOpen(false)} expose>
39
+ <Button variant="primary" onClick={() => setOpen(false)}>Confirm</Button>
40
+ </Dialog>
41
+ </>
42
+ );
43
+ }
44
+ ```
45
+
46
+ Every component takes `expose` (+ optional `toolName` / `toolDescription`) to
47
+ register its [WebMCP](https://webmcpui.com/docs/webmcp) tool — a click, a fill,
48
+ an open — that an agent can call. With no agent present it's a no-op.
49
+
50
+ ## Components
51
+
52
+ `Button` · `Input` · `Dialog` · `Tabs` — more land each release as the core kit
53
+ grows. Props mirror the [element attributes](https://webmcpui.com/docs) (camelCased):
54
+ `variant`, `size`, `value`, `type`, `open`, `active`, `disabled`, `expose`, `toolName`, …
55
+
56
+ Imperative handles come through the `ref` — e.g. `dialogRef.current.show()`.
57
+
58
+ ## Styling
59
+
60
+ Themed through the [design tokens](https://www.npmjs.com/package/@webmcpui/tokens)
61
+ (CSS custom properties, shadcn-aligned, light + dark). Two modes:
62
+
63
+ - **Themed** — `import '@webmcpui/tokens/css'` once at your app root.
64
+ - **Unstyled** — don't import the tokens CSS. The elements render with neutral
65
+ inline fallbacks; style them yourself via the CSS custom properties or the
66
+ `::part()` selectors each element exposes.
67
+
68
+ ## Server rendering (Next.js, Remix, …)
69
+
70
+ These are **client-rendered custom elements** — importing them evaluates
71
+ `class extends HTMLElement`, which has no meaning on the server. In an SSR/RSC
72
+ framework, load them client-side:
73
+
74
+ ```tsx
75
+ 'use client';
76
+ import dynamic from 'next/dynamic';
77
+ const Button = dynamic(() => import('@webmcpui/react').then((m) => m.Button), {
78
+ ssr: false,
79
+ });
80
+ ```
81
+
82
+ (`'use client'` alone isn't enough — Next still renders client components on the
83
+ server. Use `ssr: false`, or add a DOM shim such as
84
+ [`@lit-labs/ssr-dom-shim`](https://www.npmjs.com/package/@lit-labs/ssr-dom-shim)
85
+ if you want them in the server render.) The elements upgrade and hydrate on the
86
+ client normally.
87
+
88
+ ## Docs
89
+
90
+ Full docs, live demos, and `llms.txt` at **[webmcpui.com](https://webmcpui.com)**.
@@ -0,0 +1,85 @@
1
+ import * as _lit_react from '@lit/react';
2
+ import { WmcpButton, WmcpInput, WmcpDialog, WmcpTabs, WmcpSwitch, WmcpBadge, WmcpSeparator, WmcpTooltip, WmcpAlert, WmcpProgress, WmcpAvatar } from '@webmcpui/core';
3
+ export { WmcpAlertVariant, WmcpBadgeVariant, WmcpButtonSize, WmcpButtonType, WmcpButtonVariant, WmcpInputType } from '@webmcpui/core';
4
+
5
+ /**
6
+ * `<Button>` — an idiomatic, typed React wrapper over `<wmcp-button>`.
7
+ *
8
+ * All the behavior (form-associated submit/reset, WebMCP action exposure, a11y)
9
+ * lives in `@webmcpui/core`; this adds React ergonomics: typed props
10
+ * (`variant`, `size`, `type`, `disabled`, `expose`, `toolName`, …), `ref`
11
+ * forwarding to the element, and the composed `click` surfaced as `onClick`.
12
+ *
13
+ * ```tsx
14
+ * import { Button } from '@webmcpui/react';
15
+ * import '@webmcpui/tokens/css';
16
+ *
17
+ * <Button variant="primary" onClick={save}>Save</Button>
18
+ * <Button expose toolName="book_appointment">Book</Button>
19
+ * ```
20
+ */
21
+ declare const Button: _lit_react.ReactWebComponent<WmcpButton, {
22
+ onClick: string;
23
+ }>;
24
+
25
+ /**
26
+ * `<Input>` — a typed React wrapper over `<wmcp-input>`. Form association,
27
+ * Standard Schema validation, and WebMCP `fill_*` exposure live in core; this
28
+ * surfaces the element's props (`value`, `type`, `label`, `required`, `schema`,
29
+ * `expose`, …) plus `onInput` / `onChange`. Control it with `value` + `onInput`.
30
+ */
31
+ declare const Input: _lit_react.ReactWebComponent<WmcpInput, {
32
+ onInput: string;
33
+ onChange: string;
34
+ }>;
35
+
36
+ /**
37
+ * `<Dialog>` — a typed React wrapper over `<wmcp-dialog>`. The modal behavior
38
+ * (native `<dialog>`, focus trap, WebMCP `open_*` exposure) lives in core.
39
+ * Drive it with the `open` prop or a `ref` (`ref.current.show()` / `.close()`);
40
+ * `onOpen` / `onClose` fire on state changes.
41
+ */
42
+ declare const Dialog: _lit_react.ReactWebComponent<WmcpDialog, {
43
+ onOpen: string;
44
+ onClose: string;
45
+ }>;
46
+
47
+ /**
48
+ * `<Tabs>` — a typed React wrapper over `<wmcp-tabs>`. Holds the persistent
49
+ * `active` tab and exposes the WebMCP `switch_*` tool (in core). Pass the
50
+ * panels as children (`<section tab="…" tab-label="…">`); read/track the active
51
+ * tab via the `active` prop and `onChange`.
52
+ */
53
+ declare const Tabs: _lit_react.ReactWebComponent<WmcpTabs, {
54
+ onChange: string;
55
+ }>;
56
+
57
+ /** `<Switch>` — a typed React wrapper over `<wmcp-switch>` (boolean form
58
+ * control, WebMCP `fill_*` exposure in core). Control with `checked` + `onChange`. */
59
+ declare const Switch: _lit_react.ReactWebComponent<WmcpSwitch, {
60
+ onInput: string;
61
+ onChange: string;
62
+ }>;
63
+
64
+ /** `<Badge>` — a presentational status pill (`variant` + children). No WebMCP tool. */
65
+ declare const Badge: _lit_react.ReactWebComponent<WmcpBadge, {}>;
66
+
67
+ /** `<Separator>` — a presentational divider (`orientation`). No WebMCP tool. */
68
+ declare const Separator: _lit_react.ReactWebComponent<WmcpSeparator, {}>;
69
+
70
+ /** `<Tooltip>` — a typed React wrapper over `<wmcp-Tooltip>`. */
71
+ declare const Tooltip: _lit_react.ReactWebComponent<WmcpTooltip, {
72
+ onOpen: string;
73
+ onClose: string;
74
+ }>;
75
+
76
+ /** `<Alert>` — a typed React wrapper over `<wmcp-Alert>`. */
77
+ declare const Alert: _lit_react.ReactWebComponent<WmcpAlert, {}>;
78
+
79
+ /** `<Progress>` — a typed React wrapper over `<wmcp-Progress>`. */
80
+ declare const Progress: _lit_react.ReactWebComponent<WmcpProgress, {}>;
81
+
82
+ /** `<Avatar>` — a typed React wrapper over `<wmcp-Avatar>`. */
83
+ declare const Avatar: _lit_react.ReactWebComponent<WmcpAvatar, {}>;
84
+
85
+ export { Alert, Avatar, Badge, Button, Dialog, Input, Progress, Separator, Switch, Tabs, Tooltip };
package/dist/index.js ADDED
@@ -0,0 +1,153 @@
1
+ // src/button.tsx
2
+ import * as React from "react";
3
+ import { createComponent } from "@lit/react";
4
+ import { WmcpButton } from "@webmcpui/core";
5
+
6
+ // src/define.ts
7
+ function defineOnce(tagName, elementClass) {
8
+ if (typeof customElements === "undefined") return;
9
+ if (!customElements.get(tagName)) {
10
+ customElements.define(tagName, elementClass);
11
+ }
12
+ }
13
+
14
+ // src/button.tsx
15
+ defineOnce(WmcpButton.tagName, WmcpButton);
16
+ var Button = createComponent({
17
+ tagName: WmcpButton.tagName,
18
+ elementClass: WmcpButton,
19
+ react: React,
20
+ events: {
21
+ onClick: "click"
22
+ }
23
+ });
24
+ Button.displayName = "Button";
25
+
26
+ // src/input.tsx
27
+ import * as React2 from "react";
28
+ import { createComponent as createComponent2 } from "@lit/react";
29
+ import { WmcpInput } from "@webmcpui/core";
30
+ defineOnce(WmcpInput.tagName, WmcpInput);
31
+ var Input = createComponent2({
32
+ tagName: WmcpInput.tagName,
33
+ elementClass: WmcpInput,
34
+ react: React2,
35
+ events: {
36
+ onInput: "input",
37
+ onChange: "change"
38
+ }
39
+ });
40
+ Input.displayName = "Input";
41
+
42
+ // src/dialog.tsx
43
+ import * as React3 from "react";
44
+ import { createComponent as createComponent3 } from "@lit/react";
45
+ import { WmcpDialog } from "@webmcpui/core";
46
+ defineOnce(WmcpDialog.tagName, WmcpDialog);
47
+ var Dialog = createComponent3({
48
+ tagName: WmcpDialog.tagName,
49
+ elementClass: WmcpDialog,
50
+ react: React3,
51
+ events: {
52
+ onOpen: "open",
53
+ onClose: "close"
54
+ }
55
+ });
56
+ Dialog.displayName = "Dialog";
57
+
58
+ // src/tabs.tsx
59
+ import * as React4 from "react";
60
+ import { createComponent as createComponent4 } from "@lit/react";
61
+ import { WmcpTabs } from "@webmcpui/core";
62
+ defineOnce(WmcpTabs.tagName, WmcpTabs);
63
+ var Tabs = createComponent4({
64
+ tagName: WmcpTabs.tagName,
65
+ elementClass: WmcpTabs,
66
+ react: React4,
67
+ events: {
68
+ onChange: "change"
69
+ }
70
+ });
71
+ Tabs.displayName = "Tabs";
72
+
73
+ // src/switch.tsx
74
+ import * as React5 from "react";
75
+ import { createComponent as createComponent5 } from "@lit/react";
76
+ import { WmcpSwitch } from "@webmcpui/core";
77
+ defineOnce(WmcpSwitch.tagName, WmcpSwitch);
78
+ var Switch = createComponent5({
79
+ tagName: WmcpSwitch.tagName,
80
+ elementClass: WmcpSwitch,
81
+ react: React5,
82
+ events: { onInput: "input", onChange: "change" }
83
+ });
84
+ Switch.displayName = "Switch";
85
+
86
+ // src/badge.tsx
87
+ import * as React6 from "react";
88
+ import { createComponent as createComponent6 } from "@lit/react";
89
+ import { WmcpBadge } from "@webmcpui/core";
90
+ defineOnce(WmcpBadge.tagName, WmcpBadge);
91
+ var Badge = createComponent6({
92
+ tagName: WmcpBadge.tagName,
93
+ elementClass: WmcpBadge,
94
+ react: React6
95
+ });
96
+ Badge.displayName = "Badge";
97
+
98
+ // src/separator.tsx
99
+ import * as React7 from "react";
100
+ import { createComponent as createComponent7 } from "@lit/react";
101
+ import { WmcpSeparator } from "@webmcpui/core";
102
+ defineOnce(WmcpSeparator.tagName, WmcpSeparator);
103
+ var Separator = createComponent7({
104
+ tagName: WmcpSeparator.tagName,
105
+ elementClass: WmcpSeparator,
106
+ react: React7
107
+ });
108
+ Separator.displayName = "Separator";
109
+
110
+ // src/tooltip.tsx
111
+ import * as React8 from "react";
112
+ import { createComponent as createComponent8 } from "@lit/react";
113
+ import { WmcpTooltip } from "@webmcpui/core";
114
+ defineOnce(WmcpTooltip.tagName, WmcpTooltip);
115
+ var Tooltip = createComponent8({ tagName: WmcpTooltip.tagName, elementClass: WmcpTooltip, react: React8, events: { onOpen: "open", onClose: "close" } });
116
+ Tooltip.displayName = "Tooltip";
117
+
118
+ // src/alert.tsx
119
+ import * as React9 from "react";
120
+ import { createComponent as createComponent9 } from "@lit/react";
121
+ import { WmcpAlert } from "@webmcpui/core";
122
+ defineOnce(WmcpAlert.tagName, WmcpAlert);
123
+ var Alert = createComponent9({ tagName: WmcpAlert.tagName, elementClass: WmcpAlert, react: React9 });
124
+ Alert.displayName = "Alert";
125
+
126
+ // src/progress.tsx
127
+ import * as React10 from "react";
128
+ import { createComponent as createComponent10 } from "@lit/react";
129
+ import { WmcpProgress } from "@webmcpui/core";
130
+ defineOnce(WmcpProgress.tagName, WmcpProgress);
131
+ var Progress = createComponent10({ tagName: WmcpProgress.tagName, elementClass: WmcpProgress, react: React10 });
132
+ Progress.displayName = "Progress";
133
+
134
+ // src/avatar.tsx
135
+ import * as React11 from "react";
136
+ import { createComponent as createComponent11 } from "@lit/react";
137
+ import { WmcpAvatar } from "@webmcpui/core";
138
+ defineOnce(WmcpAvatar.tagName, WmcpAvatar);
139
+ var Avatar = createComponent11({ tagName: WmcpAvatar.tagName, elementClass: WmcpAvatar, react: React11 });
140
+ Avatar.displayName = "Avatar";
141
+ export {
142
+ Alert,
143
+ Avatar,
144
+ Badge,
145
+ Button,
146
+ Dialog,
147
+ Input,
148
+ Progress,
149
+ Separator,
150
+ Switch,
151
+ Tabs,
152
+ Tooltip
153
+ };
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@webmcpui/react",
3
+ "version": "0.3.0",
4
+ "description": "Idiomatic, typed React components for webmcpui — WebMCP-native, accessible, shadcn/Tailwind-aligned. Wraps @webmcpui/core.",
5
+ "license": "MIT",
6
+ "author": "Gary Pfaff (Pfaff Digital)",
7
+ "homepage": "https://webmcpui.com",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/webmcpui/webmcpui.git",
11
+ "directory": "packages/react"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/webmcpui/webmcpui/issues"
15
+ },
16
+ "keywords": [
17
+ "webmcp",
18
+ "react",
19
+ "ai-agents",
20
+ "components",
21
+ "shadcn",
22
+ "web-components"
23
+ ],
24
+ "type": "module",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsup",
36
+ "typecheck": "tsc --noEmit",
37
+ "clean": "rm -rf dist"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "dependencies": {
43
+ "@lit/react": "^1.0.7"
44
+ },
45
+ "peerDependencies": {
46
+ "@webmcpui/core": ">=0.3.0",
47
+ "react": ">=18",
48
+ "react-dom": ">=18"
49
+ },
50
+ "devDependencies": {
51
+ "@types/react": "^19.0.0",
52
+ "@types/react-dom": "^19.0.0",
53
+ "@webmcpui/core": "workspace:*",
54
+ "react": "^19.0.0",
55
+ "react-dom": "^19.0.0",
56
+ "tsup": "^8.3.5",
57
+ "typescript": "^5.7.2"
58
+ }
59
+ }