@devalok/shilp-sutra 0.46.0 → 0.48.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/AGENTS.md +37 -1
- package/BREAKING.json +46 -0
- package/MIGRATION.md +45 -0
- package/dist/_chunks/emoji-suggestion.js +124 -0
- package/dist/_chunks/emoji-suggestion.js.map +1 -0
- package/dist/_chunks/emoji.js +1115 -0
- package/dist/_chunks/emoji.js.map +1 -0
- package/dist/_chunks/tiptap.js.map +1 -1
- package/dist/composed/emoji-picker.d.ts +19 -9
- package/dist/composed/emoji-picker.d.ts.map +1 -1
- package/dist/composed/emoji-picker.js +87 -68
- package/dist/composed/emoji-picker.js.map +1 -1
- package/dist/composed/extensions/emoji-data.d.ts +1 -14
- package/dist/composed/extensions/emoji-data.d.ts.map +1 -1
- package/dist/composed/extensions/emoji-node.d.ts +0 -3
- package/dist/composed/extensions/emoji-node.d.ts.map +1 -1
- package/dist/composed/extensions/emoji-node.js +9 -34
- package/dist/composed/extensions/emoji-node.js.map +1 -1
- package/dist/composed/extensions/emoji-suggestion.d.ts +2 -2
- package/dist/composed/extensions/emoji-suggestion.d.ts.map +1 -1
- package/dist/composed/extensions/emoji-suggestion.js +2 -116
- package/dist/composed/rich-chat-input.d.ts.map +1 -1
- package/dist/composed/rich-chat-input.js +554 -575
- package/dist/composed/rich-chat-input.js.map +1 -1
- package/dist/composed/rich-text-editor.d.ts.map +1 -1
- package/dist/composed/rich-text-editor.js +167 -190
- package/dist/composed/rich-text-editor.js.map +1 -1
- package/docs/components/composed/emoji-picker.md +19 -17
- package/docs/components/composed/rich-text-editor.md +1 -1
- package/docs/components/ui/table-row-link.md +1 -1
- package/docs/recipes/index.md +1 -1
- package/docs/recipes/install-astro.md +15 -12
- package/docs/recipes/install-next-app-router.md +20 -12
- package/docs/recipes/install-next-pages.md +3 -1
- package/docs/recipes/install-remix.md +16 -13
- package/docs/recipes/install-tanstack-start.md +108 -54
- package/docs/recipes/install-vite.md +18 -15
- package/docs/recipes/troubleshoot.md +7 -8
- package/llms.txt +2 -2
- package/mcp-manifest.json +54 -48
- package/mcp-manifest.schema.json +6 -0
- package/package.json +7 -10
- package/scripts/welcome.mjs +4 -2
- package/skill/SKILL.md +1 -1
- package/skill/references/components.md +2 -2
- package/skill/references/setup-astro.md +15 -12
- package/skill/references/setup-next-app-router.md +20 -12
- package/skill/references/setup-next-pages.md +3 -1
- package/skill/references/setup-remix.md +16 -13
- package/skill/references/setup-tanstack-start.md +108 -54
- package/skill/references/setup-vite.md +18 -15
- package/skill/references/troubleshoot.md +7 -8
- package/dist/_chunks/emoji-data.js +0 -45
- package/dist/_chunks/emoji-data.js.map +0 -1
- package/dist/composed/extensions/emoji-suggestion.js.map +0 -1
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
# Install: TanStack Start
|
|
2
2
|
|
|
3
|
-
> Setup recipe for adding `@devalok/shilp-sutra` to a TanStack Start project (the React full-stack framework built on
|
|
3
|
+
> Setup recipe for adding `@devalok/shilp-sutra` to a TanStack Start project (the React full-stack framework built on Vite).
|
|
4
|
+
|
|
5
|
+
> **Updated 2026-07-10 for the Vite-plugin era.** TanStack Start moved off Vinxi: the package is now `@tanstack/react-start` (not `@tanstack/start`), config lives in `vite.config.ts` (not `app.config.ts`), and the app root is `src/` (not `app/`). If you are on an old Vinxi-based project (`app.config.ts`, `@tanstack/start`), migrate to the Vite plugin first — see the TanStack Start docs.
|
|
4
6
|
|
|
5
7
|
## 1. Detect
|
|
6
8
|
|
|
7
9
|
You are in this recipe if:
|
|
8
10
|
|
|
9
|
-
- `package.json` lists `"@tanstack/start"` and `"@tanstack/react-router"`
|
|
10
|
-
- `
|
|
11
|
-
- `
|
|
11
|
+
- `package.json` lists `"@tanstack/react-start"` and `"@tanstack/react-router"`
|
|
12
|
+
- `vite.config.{ts,js}` exists and uses the `tanstackStart` plugin from `@tanstack/react-start/plugin/vite`
|
|
13
|
+
- `src/router.tsx` and `src/routes/__root.tsx` exist (a `src/routeTree.gen.ts` is generated on first run)
|
|
14
|
+
|
|
15
|
+
If instead you see `app.config.ts` + `@tanstack/start`, that is the legacy Vinxi setup — this recipe does not apply until you migrate.
|
|
16
|
+
|
|
17
|
+
> **Scaffolded with `create-start` and got a Router SPA?** As of `@tanstack/create-start` 0.59, the default template is a TanStack **Router** SPA — Vite + `@tanstack/react-router` + an `index.html` + `src/main.tsx` (client `createRoot`), with **no** `@tanstack/react-start` and no SSR server entry. That is NOT the Start SSR setup this recipe covers — use [install-vite.md](./install-vite.md) instead (it is router-agnostic and covers TanStack Router SPAs cleanly). This recipe applies only when `@tanstack/react-start` is a dependency.
|
|
12
18
|
|
|
13
19
|
## 2. Install
|
|
14
20
|
|
|
15
21
|
```bash
|
|
22
|
+
# pnpm
|
|
16
23
|
pnpm add @devalok/shilp-sutra framer-motion
|
|
17
24
|
pnpm add -D tailwindcss@^4 @tailwindcss/vite
|
|
25
|
+
|
|
26
|
+
# npm
|
|
27
|
+
npm install @devalok/shilp-sutra framer-motion
|
|
28
|
+
npm install -D tailwindcss@^4 @tailwindcss/vite
|
|
18
29
|
```
|
|
19
30
|
|
|
20
31
|
Optional:
|
|
@@ -25,52 +36,97 @@ pnpm add sonner # only if rendering <Toaster />
|
|
|
25
36
|
|
|
26
37
|
### 2a. Optional peer dependencies (install ONLY when importing the matching subpath)
|
|
27
38
|
|
|
28
|
-
Some components ship hard peers as optional. **Install BEFORE first import
|
|
39
|
+
Some components ship hard peers as optional. **Install BEFORE first import.** ⚠ On Vite 8 / Rolldown a missing peer does **not** fail the build — Rolldown silently replaces the import with a stub that throws `Could not resolve "…"` in the browser at runtime, while the build still exits 0. A green build is therefore **not** proof the app works. Confirm coverage with the MCP `verify_setup` / `preflight` tools or the table below. Skip only if you use core components.
|
|
29
40
|
|
|
30
|
-
| When you import…
|
|
31
|
-
|
|
32
|
-
| `@devalok/shilp-sutra/
|
|
33
|
-
| `@devalok/shilp-sutra/
|
|
34
|
-
| `@devalok/shilp-sutra/composed/
|
|
35
|
-
| `@devalok/shilp-sutra/composed/
|
|
36
|
-
| `@devalok/shilp-sutra/ui/
|
|
37
|
-
| `@devalok/shilp-sutra/
|
|
38
|
-
| `@devalok/shilp-sutra/
|
|
39
|
-
|
|
|
41
|
+
| When you import… | Install |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `@devalok/shilp-sutra/composed/date-picker` | `pnpm add date-fns` |
|
|
44
|
+
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
45
|
+
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter remark-gfm` |
|
|
46
|
+
| `@devalok/shilp-sutra/composed/schedule-view` | `pnpm add date-fns` |
|
|
47
|
+
| `@devalok/shilp-sutra/ui/charts` | `pnpm add d3-axis d3-scale d3-selection d3-shape` |
|
|
48
|
+
| `@devalok/shilp-sutra/ui/data-table` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
|
|
49
|
+
| `@devalok/shilp-sutra/ui/data-table-toolbar` | `pnpm add @tanstack/react-table` |
|
|
50
|
+
| `@devalok/shilp-sutra/ui/input-otp` | `pnpm add input-otp` |
|
|
51
|
+
| `@devalok/shilp-sutra/ui/toast` | `pnpm add sonner` |
|
|
52
|
+
| `@devalok/shilp-sutra/ui/toaster` | `pnpm add sonner` |
|
|
53
|
+
| Any `Icon` / `IconButton` with Tabler icons (near-universal — most components use icons internally, so it is a base-install peer) | `pnpm add @tabler/icons-react` |
|
|
40
54
|
|
|
41
|
-
## 3. Wire Tailwind 4 in `
|
|
55
|
+
## 3. Wire Tailwind 4 in `vite.config.ts`
|
|
56
|
+
|
|
57
|
+
Add `@tailwindcss/vite` to the existing plugins array. `tanstackStart()` must come before `viteReact()`; `tailwindcss()` can go first so tokens are processed early.
|
|
42
58
|
|
|
43
59
|
```ts
|
|
44
|
-
import { defineConfig } from "
|
|
60
|
+
import { defineConfig } from "vite";
|
|
61
|
+
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
|
62
|
+
import viteReact from "@vitejs/plugin-react";
|
|
45
63
|
import tailwindcss from "@tailwindcss/vite";
|
|
46
64
|
|
|
47
65
|
export default defineConfig({
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
plugins: [
|
|
67
|
+
tailwindcss(),
|
|
68
|
+
tanstackStart(),
|
|
69
|
+
viteReact(),
|
|
70
|
+
],
|
|
51
71
|
});
|
|
52
72
|
```
|
|
53
73
|
|
|
74
|
+
Do **not** add a `tailwind.config.{ts,js}` — Tailwind 4 is CSS-first.
|
|
75
|
+
|
|
54
76
|
## 4. Wire tokens
|
|
55
77
|
|
|
56
|
-
Create `
|
|
78
|
+
Create `src/styles/globals.css`:
|
|
57
79
|
|
|
58
80
|
```css
|
|
59
81
|
@import "tailwindcss";
|
|
60
82
|
@import "@devalok/shilp-sutra/css";
|
|
61
83
|
```
|
|
62
84
|
|
|
63
|
-
|
|
85
|
+
Wire it as an asset-URL stylesheet from the root route's `head` (the TanStack Start idiom — the `?url` suffix emits the file as an asset instead of inlining it):
|
|
64
86
|
|
|
65
87
|
```tsx
|
|
66
|
-
|
|
88
|
+
// src/routes/__root.tsx
|
|
89
|
+
import {
|
|
90
|
+
createRootRoute,
|
|
91
|
+
HeadContent,
|
|
92
|
+
Outlet,
|
|
93
|
+
Scripts,
|
|
94
|
+
} from "@tanstack/react-router";
|
|
95
|
+
import globalsCss from "../styles/globals.css?url";
|
|
96
|
+
|
|
97
|
+
export const Route = createRootRoute({
|
|
98
|
+
head: () => ({
|
|
99
|
+
meta: [
|
|
100
|
+
{ charSet: "utf-8" },
|
|
101
|
+
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
|
102
|
+
],
|
|
103
|
+
links: [{ rel: "stylesheet", href: globalsCss }],
|
|
104
|
+
}),
|
|
105
|
+
component: RootComponent,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
function RootComponent() {
|
|
109
|
+
return (
|
|
110
|
+
<html lang="en" suppressHydrationWarning>
|
|
111
|
+
<head>
|
|
112
|
+
<HeadContent />
|
|
113
|
+
</head>
|
|
114
|
+
<body>
|
|
115
|
+
<Outlet />
|
|
116
|
+
<Scripts />
|
|
117
|
+
</body>
|
|
118
|
+
</html>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
67
121
|
```
|
|
68
122
|
|
|
69
|
-
|
|
123
|
+
> **Newer scaffolds use `shellComponent`.** As of `@tanstack/create-start` 0.59 the generated `__root.tsx` uses `shellComponent: RootDocument` (which receives `{ children }`) instead of `component: RootComponent` with `<Outlet />`. Both wire up the same way for shilp-sutra — put the `{ rel: "stylesheet", href: appCss }` link in `head()` and keep `<HeadContent />` + `<Scripts />`. If your `__root.tsx` already has a `shellComponent`, add the stylesheet link to its existing `head()` rather than replacing the component. (Verified cold: shilp-sutra components — Button, Text, MarkdownViewer, EmojiPickerPopover — SSR-render cleanly under TanStack Start, HTTP 200.)
|
|
70
124
|
|
|
71
125
|
## 5. Theme toggle
|
|
72
126
|
|
|
73
|
-
|
|
127
|
+
Add a pre-hydration bootstrap so there is no flash of the wrong theme. The cleanest place is a `scripts` entry on the root route (runs before hydration); a static `public/theme-bootstrap.js` referenced from `<head>` also works and is CSP-friendly.
|
|
128
|
+
|
|
129
|
+
Static-asset approach — create `public/theme-bootstrap.js`:
|
|
74
130
|
|
|
75
131
|
```js
|
|
76
132
|
(function () {
|
|
@@ -84,44 +140,36 @@ Create `public/theme-bootstrap.js` (a static asset served verbatim):
|
|
|
84
140
|
})();
|
|
85
141
|
```
|
|
86
142
|
|
|
87
|
-
Reference it from `
|
|
143
|
+
Reference it from the root route's `head` scripts:
|
|
88
144
|
|
|
89
145
|
```tsx
|
|
90
|
-
import { createRootRoute, Outlet } from "@tanstack/react-router";
|
|
91
|
-
|
|
92
146
|
export const Route = createRootRoute({
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<body>
|
|
99
|
-
<Outlet />
|
|
100
|
-
</body>
|
|
101
|
-
</html>
|
|
102
|
-
),
|
|
147
|
+
head: () => ({
|
|
148
|
+
// ...meta, links as above...
|
|
149
|
+
scripts: [{ src: "/theme-bootstrap.js" }],
|
|
150
|
+
}),
|
|
151
|
+
component: RootComponent,
|
|
103
152
|
});
|
|
104
153
|
```
|
|
105
154
|
|
|
106
|
-
For runtime toggling, use the `useColorMode` hook — see [install-vite.md § 5](./install-vite.md#5-theme-toggle-no-next-themes-here).
|
|
155
|
+
For runtime toggling inside components, use the `useColorMode` hook — see [install-vite.md § 5](./install-vite.md#5-theme-toggle-no-next-themes-here).
|
|
107
156
|
|
|
108
157
|
## 6. Toaster (optional)
|
|
109
158
|
|
|
110
|
-
Mount in `__root.tsx` next to `<Outlet />`:
|
|
159
|
+
Mount once in `__root.tsx`'s `RootComponent`, next to `<Outlet />`:
|
|
111
160
|
|
|
112
161
|
```tsx
|
|
113
162
|
import { Toaster } from "@devalok/shilp-sutra/ui/toaster";
|
|
114
163
|
|
|
115
164
|
// inside <body>
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
</>
|
|
165
|
+
<Outlet />
|
|
166
|
+
<Toaster />
|
|
167
|
+
<Scripts />
|
|
120
168
|
```
|
|
121
169
|
|
|
122
170
|
## 7. Verify
|
|
123
171
|
|
|
124
|
-
Create or replace `
|
|
172
|
+
Create or replace `src/routes/index.tsx`:
|
|
125
173
|
|
|
126
174
|
```tsx
|
|
127
175
|
import { createFileRoute } from "@tanstack/react-router";
|
|
@@ -130,7 +178,11 @@ import { Stack } from "@devalok/shilp-sutra/ui/stack";
|
|
|
130
178
|
import { Text } from "@devalok/shilp-sutra/ui/text";
|
|
131
179
|
|
|
132
180
|
export const Route = createFileRoute("/")({
|
|
133
|
-
component:
|
|
181
|
+
component: Home,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
function Home() {
|
|
185
|
+
return (
|
|
134
186
|
<Stack className="p-ds-08" gap="ds-04">
|
|
135
187
|
<Text variant="heading-2xl">Hello, Shilp Sutra</Text>
|
|
136
188
|
<Stack direction="row" gap="ds-03">
|
|
@@ -138,21 +190,23 @@ export const Route = createFileRoute("/")({
|
|
|
138
190
|
<Button variant="soft">Soft</Button>
|
|
139
191
|
</Stack>
|
|
140
192
|
</Stack>
|
|
141
|
-
)
|
|
142
|
-
}
|
|
193
|
+
);
|
|
194
|
+
}
|
|
143
195
|
```
|
|
144
196
|
|
|
145
|
-
Run `pnpm dev` and open the URL.
|
|
197
|
+
Run `pnpm dev` and open the printed URL. Expected output matches [Next App Router § 7](./install-next-app-router.md#7-verify-the-install).
|
|
146
198
|
|
|
147
199
|
## 8. TanStack Start specifics
|
|
148
200
|
|
|
201
|
+
- **No `transpilePackages` equivalent — and you do not need one.** TanStack Start's Vite resolves `@devalok/shilp-sutra` from `node_modules` as native ESM.
|
|
149
202
|
- **Server functions** (`createServerFn`) — do not import shilp-sutra components inside server functions; they run server-only.
|
|
150
|
-
- **Streaming SSR** is the default.
|
|
203
|
+
- **Streaming SSR** is the default. Shilp Sutra components SSR cleanly (no client-only side effects at module top-level).
|
|
151
204
|
- **`framer-motion` SSR** — animations gracefully degrade on the initial render.
|
|
152
|
-
- **
|
|
205
|
+
- **`routeTree.gen.ts` is generated** — do not edit it by hand; it regenerates on dev/build.
|
|
153
206
|
|
|
154
207
|
## 9. What NOT to do
|
|
155
208
|
|
|
156
|
-
- ❌ Add `tailwind.config.{ts,js}` — Tailwind 4 is CSS-first.
|
|
157
|
-
- ❌
|
|
158
|
-
- ❌
|
|
209
|
+
- ❌ Add a `tailwind.config.{ts,js}` — Tailwind 4 is CSS-first.
|
|
210
|
+
- ❌ Use `@tanstack/start` / `app.config.ts` / `@tanstack/start/config` — that is the retired Vinxi setup. Current TanStack Start is `@tanstack/react-start` + `vite.config.ts`.
|
|
211
|
+
- ❌ Mount `<Toaster />` inside route components — it lives once at the `__root`.
|
|
212
|
+
- ❌ Mix `@tailwindcss/postcss` and `@tailwindcss/vite` — pick the Vite plugin.
|
|
@@ -42,18 +42,21 @@ pnpm add sonner
|
|
|
42
42
|
|
|
43
43
|
### 2a. Optional peer dependencies (install ONLY when importing the matching subpath)
|
|
44
44
|
|
|
45
|
-
Some components ship hard peers as optional. **Install BEFORE first import**
|
|
46
|
-
|
|
47
|
-
| When you import…
|
|
48
|
-
|
|
49
|
-
| `@devalok/shilp-sutra/
|
|
50
|
-
| `@devalok/shilp-sutra/
|
|
51
|
-
| `@devalok/shilp-sutra/composed/
|
|
52
|
-
| `@devalok/shilp-sutra/composed/
|
|
53
|
-
| `@devalok/shilp-sutra/ui/
|
|
54
|
-
| `@devalok/shilp-sutra/
|
|
55
|
-
| `@devalok/shilp-sutra/
|
|
56
|
-
|
|
|
45
|
+
Some components ship hard peers as optional. **Install BEFORE first import.** ⚠ On Vite 8 / Rolldown a missing peer does **not** fail the build — Rolldown silently replaces the import with a stub that throws `Could not resolve "…"` in the browser at runtime, while `vite build` still exits 0. A green build is therefore **not** proof the app works. Confirm coverage with the MCP `verify_setup` / `preflight` tools or the table below. Skip only if you use core components.
|
|
46
|
+
|
|
47
|
+
| When you import… | Install |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `@devalok/shilp-sutra/composed/date-picker` | `pnpm add date-fns` |
|
|
50
|
+
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
51
|
+
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter remark-gfm` |
|
|
52
|
+
| `@devalok/shilp-sutra/composed/schedule-view` | `pnpm add date-fns` |
|
|
53
|
+
| `@devalok/shilp-sutra/ui/charts` | `pnpm add d3-axis d3-scale d3-selection d3-shape` |
|
|
54
|
+
| `@devalok/shilp-sutra/ui/data-table` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
|
|
55
|
+
| `@devalok/shilp-sutra/ui/data-table-toolbar` | `pnpm add @tanstack/react-table` |
|
|
56
|
+
| `@devalok/shilp-sutra/ui/input-otp` | `pnpm add input-otp` |
|
|
57
|
+
| `@devalok/shilp-sutra/ui/toast` | `pnpm add sonner` |
|
|
58
|
+
| `@devalok/shilp-sutra/ui/toaster` | `pnpm add sonner` |
|
|
59
|
+
| Any `Icon` / `IconButton` with Tabler icons (near-universal — most components use icons internally, so it is a base-install peer) | `pnpm add @tabler/icons-react` |
|
|
57
60
|
|
|
58
61
|
## 3. Wire Tailwind 4 in `vite.config.ts`
|
|
59
62
|
|
|
@@ -136,7 +139,7 @@ If you installed `sonner`, mount the Toaster once near the app root:
|
|
|
136
139
|
import { StrictMode } from "react";
|
|
137
140
|
import { createRoot } from "react-dom/client";
|
|
138
141
|
import { Toaster } from "@devalok/shilp-sutra/ui/toaster";
|
|
139
|
-
import
|
|
142
|
+
import App from "./App";
|
|
140
143
|
import "./index.css";
|
|
141
144
|
|
|
142
145
|
createRoot(document.getElementById("root")!).render(
|
|
@@ -149,14 +152,14 @@ createRoot(document.getElementById("root")!).render(
|
|
|
149
152
|
|
|
150
153
|
## 7. Verify
|
|
151
154
|
|
|
152
|
-
Replace `src/App.tsx
|
|
155
|
+
Replace `src/App.tsx` (keep the **default export** — the `create-vite` template's `main.tsx` imports it as `import App from "./App"`, so a named export would break the build with `TS2613: Module has no default export`):
|
|
153
156
|
|
|
154
157
|
```tsx
|
|
155
158
|
import { Button } from "@devalok/shilp-sutra/ui/button";
|
|
156
159
|
import { Stack } from "@devalok/shilp-sutra/ui/stack";
|
|
157
160
|
import { Text } from "@devalok/shilp-sutra/ui/text";
|
|
158
161
|
|
|
159
|
-
export function App() {
|
|
162
|
+
export default function App() {
|
|
160
163
|
return (
|
|
161
164
|
<Stack className="p-ds-08" gap="ds-04">
|
|
162
165
|
<Text variant="heading-2xl">Hello, Shilp Sutra</Text>
|
|
@@ -95,26 +95,25 @@ Add:
|
|
|
95
95
|
transpilePackages: ["@devalok/shilp-sutra"],
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
## Symptom: Build error `Cannot find module 'sonner' / 'input-otp' / 'date-fns' / '
|
|
98
|
+
## Symptom: Build error `Cannot find module 'sonner' / 'input-otp' / 'date-fns' / 'react-pdf' / 'react-markdown'` — OR (on Vite 8) a runtime `Could not resolve "…"` from a green build
|
|
99
99
|
|
|
100
|
-
**Diagnosis:** an optional peer dependency is missing. Each component below has a peer it pulls only when imported. Install the matching peer (always BEFORE the first import)
|
|
100
|
+
**Diagnosis:** an optional peer dependency is missing. Each component below has a peer it pulls only when imported. Install the matching peer (always BEFORE the first import). On Vite 8 / Rolldown this does **not** fail the build — it throws at runtime — so run the MCP `verify_setup` tool to catch it early.
|
|
101
101
|
|
|
102
102
|
| You imported (per-component subpath) | Install |
|
|
103
103
|
|--------------------------------------|-----------------------------------------------------------------------------------------------|
|
|
104
104
|
| `…/ui/toaster` or `…/ui/toast` | `pnpm add sonner` |
|
|
105
105
|
| `…/ui/input-otp` | `pnpm add input-otp` |
|
|
106
|
-
| `…/composed/date-picker`
|
|
107
|
-
| `…/
|
|
108
|
-
| `…/composed/extensions/emoji-node` or `…/extensions/emoji-suggestion` | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
109
|
-
| `…/composed/rich-text-editor` | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
110
|
-
| `…/composed/rich-chat-input` | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
106
|
+
| `…/composed/date-picker` or `…/composed/schedule-view` | `pnpm add date-fns` |
|
|
107
|
+
| `…/ui/data-table` or `…/ui/data-table-toolbar` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
|
|
111
108
|
| `…/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
112
109
|
| `…/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter remark-gfm` |
|
|
113
110
|
| `…/ai/block-renderer`, `…/ai/blocks/text`, `…/ai/blocks/error` | `pnpm add react-markdown remark-gfm` |
|
|
114
|
-
| Any `…/ui/charts/*` | `pnpm add d3-
|
|
111
|
+
| Any `…/ui/charts/*` | `pnpm add d3-axis d3-scale d3-selection d3-shape` |
|
|
115
112
|
|
|
116
113
|
These ship as **optional** peers so consumers who never render the matching component don't pay the install cost. Once you import the component, the peer becomes required. Each affected component's JSDoc carries the same install hint — hover the import in your editor to see it inline.
|
|
117
114
|
|
|
115
|
+
**No longer peers (bundled since the frimousse migration):** the emoji picker (`…/composed/emoji-picker`) and the rich-text editors (`…/composed/rich-text-editor`, `…/composed/rich-chat-input`) bundle their dependencies (frimousse, `@emoji-mart/data`, TipTap) into a lazy chunk — you do **not** install anything for them. `@tabler/icons-react` is a required peer that most package managers auto-install.
|
|
116
|
+
|
|
118
117
|
**Catch this at edit time, not build time:** install `@devalok/eslint-plugin-shilp-sutra` (`pnpm add -D @devalok/eslint-plugin-shilp-sutra`, then `shilpSutra.configs['flat/recommended']`). Its `prefer-per-component-import` rule flags peer-cliff symbols imported from a barrel and autofixes the path — surfacing the cliff in your editor before the bundler ever fails.
|
|
119
118
|
|
|
120
119
|
For the full table in your framework's install recipe, see `install-<framework>.md → §2a. Optional peer dependencies`.
|
package/llms.txt
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# @devalok/shilp-sutra
|
|
2
2
|
|
|
3
|
-
> Radix UI + Tailwind 4 (CSS-first) + CVA design system for Devalok apps, v0.
|
|
3
|
+
> Radix UI + Tailwind 4 (CSS-first) + CVA design system for Devalok apps, v0.48.0.
|
|
4
4
|
> Built on the same primitives as shadcn/ui but with DIFFERENT prop APIs — never guess from shadcn knowledge; verify every prop.
|
|
5
5
|
> This file is a ROUTER: it tells you what exists and where to get details. Do not look for prop tables here — fetch them per component (MCP tool or per-component doc file below).
|
|
6
6
|
|
|
7
7
|
## How to get component details (in priority order)
|
|
8
8
|
|
|
9
|
-
1. **shilp-sutra MCP** (if connected): `get_component(name)` — version-exact props/variants/examples/composition as JSON. Also: `find_component(query)`, `get_tokens(category)`, `get_setup(framework)`, `upgrade(from, to)`, `search_docs(query)`. Pass your installed version (`node_modules/@devalok/shilp-sutra/package.json`) as `version` on every call.
|
|
9
|
+
1. **shilp-sutra MCP** (if connected): `get_component(name)` — version-exact props/variants/examples/composition as JSON. Also: `find_component(query)`, `get_tokens(category)`, `get_setup(framework)`, `upgrade(from, to)`, `search_docs(query)`. **Setting up in a project?** `detect_framework(packageJson)` → `get_setup(framework)` → `preflight(framework, imports)` (peer installs) → `validate_snippet(code)` before writing → `verify_setup(...)`. Pass your installed version (`node_modules/@devalok/shilp-sutra/package.json`) as `version` on every call.
|
|
10
10
|
Connect: `claude mcp add --transport http shilp-sutra https://shilp-sutra.devalok.in/mcp`
|
|
11
11
|
2. **No MCP?** Read the single per-component file linked in the index below (`node_modules/@devalok/shilp-sutra/docs/components/...`, ~3K tokens each). Read only the components you need — never bulk-read the directory.
|
|
12
12
|
3. **Machine-readable everything**: `mcp-manifest.json` at the package root (all props/tokens/composition as JSON, react-docgen shape). Prefer targeted reads of it over any prose.
|
package/mcp-manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./mcp-manifest.schema.json",
|
|
3
|
-
"manifestVersion": "1.
|
|
3
|
+
"manifestVersion": "1.1.0",
|
|
4
4
|
"package": "@devalok/shilp-sutra",
|
|
5
|
-
"packageVersion": "0.
|
|
5
|
+
"packageVersion": "0.48.0",
|
|
6
6
|
"components": {
|
|
7
7
|
"accordion": {
|
|
8
8
|
"displayName": "Accordion",
|
|
@@ -1780,6 +1780,12 @@
|
|
|
1780
1780
|
"version": "0.1.0",
|
|
1781
1781
|
"summary": "**Added** Initial release"
|
|
1782
1782
|
}
|
|
1783
|
+
],
|
|
1784
|
+
"peers": [
|
|
1785
|
+
"d3-axis",
|
|
1786
|
+
"d3-scale",
|
|
1787
|
+
"d3-selection",
|
|
1788
|
+
"d3-shape"
|
|
1783
1789
|
]
|
|
1784
1790
|
},
|
|
1785
1791
|
"chat": {
|
|
@@ -2787,6 +2793,10 @@
|
|
|
2787
2793
|
"version": "0.1.0",
|
|
2788
2794
|
"summary": "**Added** Initial release"
|
|
2789
2795
|
}
|
|
2796
|
+
],
|
|
2797
|
+
"peers": [
|
|
2798
|
+
"@tanstack/react-table",
|
|
2799
|
+
"@tanstack/react-virtual"
|
|
2790
2800
|
]
|
|
2791
2801
|
},
|
|
2792
2802
|
"data-table-body": {
|
|
@@ -3001,6 +3011,9 @@
|
|
|
3001
3011
|
"version": "0.1.0",
|
|
3002
3012
|
"summary": "**Added** Initial release"
|
|
3003
3013
|
}
|
|
3014
|
+
],
|
|
3015
|
+
"peers": [
|
|
3016
|
+
"@tanstack/react-table"
|
|
3004
3017
|
]
|
|
3005
3018
|
},
|
|
3006
3019
|
"devalok-grain": {
|
|
@@ -4038,6 +4051,9 @@
|
|
|
4038
4051
|
"version": "0.1.0",
|
|
4039
4052
|
"summary": "**Added** Initial release"
|
|
4040
4053
|
}
|
|
4054
|
+
],
|
|
4055
|
+
"peers": [
|
|
4056
|
+
"input-otp"
|
|
4041
4057
|
]
|
|
4042
4058
|
},
|
|
4043
4059
|
"label": {
|
|
@@ -6723,7 +6739,7 @@
|
|
|
6723
6739
|
},
|
|
6724
6740
|
"docPath": "docs/components/ui/table-row-link.md",
|
|
6725
6741
|
"examples": [
|
|
6726
|
-
"<TableRow>\n <TableCell className=\"relative\">\n <TableRowLink href={`/projects/${id}`}>{name}</TableRowLink>\n </TableCell>\n <TableCell><Badge color=\"success\">Active</Badge></TableCell>\n <TableCell>\n <TableRowActions>\n <IconButton className=\"relative z-[1]\" size=\"
|
|
6742
|
+
"<TableRow>\n <TableCell className=\"relative\">\n <TableRowLink href={`/projects/${id}`}>{name}</TableRowLink>\n </TableCell>\n <TableCell><Badge color=\"success\">Active</Badge></TableCell>\n <TableCell>\n <TableRowActions>\n <IconButton className=\"relative z-[1]\" size=\"sm\" variant=\"ghost\" aria-label={`Actions for ${name}`} icon={<IconDots />} />\n </TableRowActions>\n </TableCell>\n</TableRow>"
|
|
6727
6743
|
],
|
|
6728
6744
|
"gotchas": [
|
|
6729
6745
|
"The stretched overlay blocks text selection inside the row — use `stretch={false}` (GitHub-style title link) when row text must stay selectable",
|
|
@@ -7047,6 +7063,9 @@
|
|
|
7047
7063
|
"version": "0.1.0",
|
|
7048
7064
|
"summary": "**Added** Initial release"
|
|
7049
7065
|
}
|
|
7066
|
+
],
|
|
7067
|
+
"peers": [
|
|
7068
|
+
"sonner"
|
|
7050
7069
|
]
|
|
7051
7070
|
},
|
|
7052
7071
|
"toaster": {
|
|
@@ -7124,6 +7143,9 @@
|
|
|
7124
7143
|
"version": "0.1.0",
|
|
7125
7144
|
"summary": "**Added** Initial release"
|
|
7126
7145
|
}
|
|
7146
|
+
],
|
|
7147
|
+
"peers": [
|
|
7148
|
+
"sonner"
|
|
7127
7149
|
]
|
|
7128
7150
|
},
|
|
7129
7151
|
"toggle": {
|
|
@@ -8587,6 +8609,9 @@
|
|
|
8587
8609
|
"version": "0.1.0",
|
|
8588
8610
|
"summary": "**Added** Initial release"
|
|
8589
8611
|
}
|
|
8612
|
+
],
|
|
8613
|
+
"peers": [
|
|
8614
|
+
"date-fns"
|
|
8590
8615
|
]
|
|
8591
8616
|
},
|
|
8592
8617
|
"deadline-indicator": {
|
|
@@ -8679,41 +8704,12 @@
|
|
|
8679
8704
|
},
|
|
8680
8705
|
"required": false
|
|
8681
8706
|
},
|
|
8682
|
-
"
|
|
8707
|
+
"emojibaseUrl": {
|
|
8683
8708
|
"type": {
|
|
8684
|
-
"name": "
|
|
8685
|
-
"value": [
|
|
8686
|
-
"auto",
|
|
8687
|
-
"light",
|
|
8688
|
-
"dark"
|
|
8689
|
-
]
|
|
8690
|
-
},
|
|
8691
|
-
"required": false,
|
|
8692
|
-
"defaultValue": "auto"
|
|
8693
|
-
},
|
|
8694
|
-
"previewPosition": {
|
|
8695
|
-
"type": {
|
|
8696
|
-
"name": "enum",
|
|
8697
|
-
"value": [
|
|
8698
|
-
"top",
|
|
8699
|
-
"bottom",
|
|
8700
|
-
"none"
|
|
8701
|
-
]
|
|
8702
|
-
},
|
|
8703
|
-
"required": false,
|
|
8704
|
-
"defaultValue": "none"
|
|
8705
|
-
},
|
|
8706
|
-
"skinTonePosition": {
|
|
8707
|
-
"type": {
|
|
8708
|
-
"name": "enum",
|
|
8709
|
-
"value": [
|
|
8710
|
-
"search",
|
|
8711
|
-
"preview",
|
|
8712
|
-
"none"
|
|
8713
|
-
]
|
|
8709
|
+
"name": "string"
|
|
8714
8710
|
},
|
|
8715
8711
|
"required": false,
|
|
8716
|
-
"
|
|
8712
|
+
"description": "base URL for the emoji dataset; default = frimousse's jsdelivr CDN"
|
|
8717
8713
|
},
|
|
8718
8714
|
"className": {
|
|
8719
8715
|
"type": {
|
|
@@ -8763,32 +8759,30 @@
|
|
|
8763
8759
|
"composition": {
|
|
8764
8760
|
"notes": [
|
|
8765
8761
|
"**Two exports:** `EmojiPicker` (inline grid, no trigger) and `EmojiPickerPopover` (trigger + popover wrapper). Use EmojiPickerPopover 95% of the time — trigger-on-click is the standard UX.",
|
|
8766
|
-
"**
|
|
8762
|
+
"**Built on frimousse**, bundled and lazy-loaded (own `emoji` chunk, incl. the dataset). Needs no consumer peer install and no React-19 peer workaround. Don't pre-import unless you need it eagerly.",
|
|
8763
|
+
"**Native emoji only.** Each platform renders its own glyphs. Theme follows the surrounding `.dark` class via DS tokens automatically — no theme prop.",
|
|
8764
|
+
"**Built-in footer:** a live preview of the hovered/active emoji (frimousse `ActiveEmoji`) plus a skin-tone selector (`SkinToneSelector`) — no props needed.",
|
|
8765
|
+
"**Dataset source / CSP:** frimousse fetches the emoji dataset from jsdelivr at runtime. To remove the CDN dependency (strict CSP, offline, air-gapped), copy `node_modules/emojibase-data` into your app's `public/emojibase` and pass `emojibaseUrl=\"/emojibase\"`.",
|
|
8767
8766
|
"**Trigger composition:** EmojiPickerPopover's `children` is the trigger — wrap any Button/IconButton. Typical pairing is an icon-only IconButton with a 😀 label.",
|
|
8768
|
-
"**TipTap integration:** Use `createEmojiSuggestion(
|
|
8769
|
-
"**Theme matching:** `theme=\"auto\"` reads the `.dark` class on `<html>` — matches the DS dark mode toggle automatically. Override with explicit light/dark.",
|
|
8770
|
-
"**Emoji sets:** Pass `set=\"apple\" | \"google\" | ...` for consistent cross-platform emoji art (defaults to native OS glyphs)."
|
|
8767
|
+
"**TipTap integration:** Use `createEmojiSuggestion()` (from `./extensions/emoji-suggestion`) to open a `:shortcode:` suggestion list. Works with RichChatInput and RichTextEditor."
|
|
8771
8768
|
]
|
|
8772
8769
|
},
|
|
8773
8770
|
"docPath": "docs/components/composed/emoji-picker.md",
|
|
8774
8771
|
"defaults": {
|
|
8775
|
-
"theme": "auto",
|
|
8776
|
-
"previewPosition": "none",
|
|
8777
|
-
"skinTonePosition": "search",
|
|
8778
8772
|
"align": "start"
|
|
8779
8773
|
},
|
|
8780
8774
|
"examples": [
|
|
8781
|
-
"<EmojiPickerPopover onSelect={(emoji) => insertEmoji(emoji.native)}>\n <Button variant=\"ghost\" size=\"icon-sm\">😀</Button>\n</EmojiPickerPopover>\n\n<EmojiPicker onSelect={handleEmoji}
|
|
8775
|
+
"<EmojiPickerPopover onSelect={(emoji) => insertEmoji(emoji.native)}>\n <Button variant=\"ghost\" size=\"icon-sm\">😀</Button>\n</EmojiPickerPopover>\n\n<EmojiPicker onSelect={handleEmoji} />"
|
|
8782
8776
|
],
|
|
8783
8777
|
"gotchas": [
|
|
8784
|
-
"
|
|
8785
|
-
"
|
|
8786
|
-
"
|
|
8778
|
+
"Client-only (fetches its emoji dataset on first open) — not server-safe.",
|
|
8779
|
+
"EmojiPickerPopover auto-closes after selection.",
|
|
8780
|
+
"The `set` / `theme` / `previewPosition` / `skinTonePosition` props are deprecated no-ops kept for source compatibility; the picker is native-only."
|
|
8787
8781
|
],
|
|
8788
8782
|
"changes": [
|
|
8789
8783
|
{
|
|
8790
8784
|
"version": "0.33.0",
|
|
8791
|
-
"summary": "**Added** `
|
|
8785
|
+
"summary": "**Added** `EmojiNode` TipTap extension and `createEmojiSuggestion()` factory."
|
|
8792
8786
|
}
|
|
8793
8787
|
]
|
|
8794
8788
|
},
|
|
@@ -9037,6 +9031,10 @@
|
|
|
9037
9031
|
"All types have error fallback with download link",
|
|
9038
9032
|
"Embed URLs auto-converted to embed format",
|
|
9039
9033
|
"Audio player doesn't show separate Download button (integrated in card)"
|
|
9034
|
+
],
|
|
9035
|
+
"peers": [
|
|
9036
|
+
"react-pdf",
|
|
9037
|
+
"react-zoom-pan-pinch"
|
|
9040
9038
|
]
|
|
9041
9039
|
},
|
|
9042
9040
|
"filter-bar": {
|
|
@@ -9487,6 +9485,11 @@
|
|
|
9487
9485
|
"GFM (tables, strikethrough, task lists) is supported via `remark-gfm`",
|
|
9488
9486
|
"Raw HTML is stripped by default — only enable `allowHtml` for trusted content",
|
|
9489
9487
|
"Links open in a new tab by default (`target=\"_blank\"` with `rel=\"noopener noreferrer\"`)"
|
|
9488
|
+
],
|
|
9489
|
+
"peers": [
|
|
9490
|
+
"react-markdown",
|
|
9491
|
+
"react-syntax-highlighter",
|
|
9492
|
+
"remark-gfm"
|
|
9490
9493
|
]
|
|
9491
9494
|
},
|
|
9492
9495
|
"master-detail": {
|
|
@@ -10299,7 +10302,7 @@
|
|
|
10299
10302
|
],
|
|
10300
10303
|
"gotchas": [
|
|
10301
10304
|
"Tiptap is bundled — no need to install `@tiptap/*` packages separately",
|
|
10302
|
-
"Emoji picker
|
|
10305
|
+
"Emoji picker (frimousse) + its dataset are bundled too — no emoji peers to install (native-only since the frimousse migration)",
|
|
10303
10306
|
"Images without `onImageUpload` are stored as base64 in HTML — large images bloat content",
|
|
10304
10307
|
"Mention rendering in viewer always works (no mention props needed, just the HTML)",
|
|
10305
10308
|
"Features: bold, italic, underline, strikethrough, highlight, headings, blockquote, lists, task lists, code, links, images, file attachments, mentions, emoji, text alignment, horizontal rule"
|
|
@@ -10433,6 +10436,9 @@
|
|
|
10433
10436
|
"version": "0.1.0",
|
|
10434
10437
|
"summary": "**Added** Initial release"
|
|
10435
10438
|
}
|
|
10439
|
+
],
|
|
10440
|
+
"peers": [
|
|
10441
|
+
"date-fns"
|
|
10436
10442
|
]
|
|
10437
10443
|
},
|
|
10438
10444
|
"simple-tooltip": {
|
package/mcp-manifest.schema.json
CHANGED
|
@@ -81,6 +81,12 @@
|
|
|
81
81
|
"items": { "type": "string" },
|
|
82
82
|
"description": "Known-misuse bullets, verbatim, DO-NOT phrasing preferred."
|
|
83
83
|
},
|
|
84
|
+
"peers": {
|
|
85
|
+
"type": "array",
|
|
86
|
+
"items": { "type": "string" },
|
|
87
|
+
"description": "Optional peer dependencies this component imports. Absent for core components (no extra install). Importing the component without these installed fails the build with 'Failed to resolve import'. Mirrors the recipe optional-peer table; read by the MCP preflight/verify_setup tools.",
|
|
88
|
+
"examples": [["@tanstack/react-table", "@tanstack/react-virtual"]]
|
|
89
|
+
},
|
|
84
90
|
"changes": {
|
|
85
91
|
"type": "array",
|
|
86
92
|
"items": {
|