@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.
Files changed (55) hide show
  1. package/AGENTS.md +37 -1
  2. package/BREAKING.json +46 -0
  3. package/MIGRATION.md +45 -0
  4. package/dist/_chunks/emoji-suggestion.js +124 -0
  5. package/dist/_chunks/emoji-suggestion.js.map +1 -0
  6. package/dist/_chunks/emoji.js +1115 -0
  7. package/dist/_chunks/emoji.js.map +1 -0
  8. package/dist/_chunks/tiptap.js.map +1 -1
  9. package/dist/composed/emoji-picker.d.ts +19 -9
  10. package/dist/composed/emoji-picker.d.ts.map +1 -1
  11. package/dist/composed/emoji-picker.js +87 -68
  12. package/dist/composed/emoji-picker.js.map +1 -1
  13. package/dist/composed/extensions/emoji-data.d.ts +1 -14
  14. package/dist/composed/extensions/emoji-data.d.ts.map +1 -1
  15. package/dist/composed/extensions/emoji-node.d.ts +0 -3
  16. package/dist/composed/extensions/emoji-node.d.ts.map +1 -1
  17. package/dist/composed/extensions/emoji-node.js +9 -34
  18. package/dist/composed/extensions/emoji-node.js.map +1 -1
  19. package/dist/composed/extensions/emoji-suggestion.d.ts +2 -2
  20. package/dist/composed/extensions/emoji-suggestion.d.ts.map +1 -1
  21. package/dist/composed/extensions/emoji-suggestion.js +2 -116
  22. package/dist/composed/rich-chat-input.d.ts.map +1 -1
  23. package/dist/composed/rich-chat-input.js +554 -575
  24. package/dist/composed/rich-chat-input.js.map +1 -1
  25. package/dist/composed/rich-text-editor.d.ts.map +1 -1
  26. package/dist/composed/rich-text-editor.js +167 -190
  27. package/dist/composed/rich-text-editor.js.map +1 -1
  28. package/docs/components/composed/emoji-picker.md +19 -17
  29. package/docs/components/composed/rich-text-editor.md +1 -1
  30. package/docs/components/ui/table-row-link.md +1 -1
  31. package/docs/recipes/index.md +1 -1
  32. package/docs/recipes/install-astro.md +15 -12
  33. package/docs/recipes/install-next-app-router.md +20 -12
  34. package/docs/recipes/install-next-pages.md +3 -1
  35. package/docs/recipes/install-remix.md +16 -13
  36. package/docs/recipes/install-tanstack-start.md +108 -54
  37. package/docs/recipes/install-vite.md +18 -15
  38. package/docs/recipes/troubleshoot.md +7 -8
  39. package/llms.txt +2 -2
  40. package/mcp-manifest.json +54 -48
  41. package/mcp-manifest.schema.json +6 -0
  42. package/package.json +7 -10
  43. package/scripts/welcome.mjs +4 -2
  44. package/skill/SKILL.md +1 -1
  45. package/skill/references/components.md +2 -2
  46. package/skill/references/setup-astro.md +15 -12
  47. package/skill/references/setup-next-app-router.md +20 -12
  48. package/skill/references/setup-next-pages.md +3 -1
  49. package/skill/references/setup-remix.md +16 -13
  50. package/skill/references/setup-tanstack-start.md +108 -54
  51. package/skill/references/setup-vite.md +18 -15
  52. package/skill/references/troubleshoot.md +7 -8
  53. package/dist/_chunks/emoji-data.js +0 -45
  54. package/dist/_chunks/emoji-data.js.map +0 -1
  55. 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 Vinxi/Vite).
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
- - `app.config.{ts,js}` (Vinxi) exists at the project root
11
- - `app/router.tsx` and `app/routes/__root.tsx` exist
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** or the TanStack Start dev/build will fail with `Failed to resolve import`. Skip if you only use core components.
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… | Install |
31
- |-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
32
- | `@devalok/shilp-sutra/ui/charts/*` | `pnpm add d3-array d3-axis d3-format d3-interpolate d3-scale d3-selection d3-shape d3-time-format d3-transition` |
33
- | `@devalok/shilp-sutra/ui/data-table` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
34
- | `@devalok/shilp-sutra/composed/date-picker` (+ DateRange, DateTime, Calendar) | `pnpm add date-fns` |
35
- | `@devalok/shilp-sutra/composed/rich-text-editor` (+ RichChatInput, RichTextViewer) | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
36
- | `@devalok/shilp-sutra/ui/input-otp` | `pnpm add input-otp` |
37
- | `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
38
- | `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter` |
39
- | Any `Icon` / `IconButton` with Tabler icons | `pnpm add @tabler/icons-react` |
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 `app.config.ts`
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 "@tanstack/start/config";
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
- vite: {
49
- plugins: [tailwindcss()],
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 `app/styles/globals.css`:
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
- Import it from `app/routes/__root.tsx`:
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
- import "../styles/globals.css";
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
- If you prefer asset-URL imports the way Remix does it, use `import css from "../styles/globals.css?url"` and add `<link rel="stylesheet" href={css} />` to the `<head>` returned by `__root.tsx`.
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
- Create `public/theme-bootstrap.js` (a static asset served verbatim):
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 `app/routes/__root.tsx`:
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
- component: () => (
94
- <html lang="en" suppressHydrationWarning>
95
- <head>
96
- <script src="/theme-bootstrap.js" />
97
- </head>
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
- <Outlet />
118
- <Toaster />
119
- </>
165
+ <Outlet />
166
+ <Toaster />
167
+ <Scripts />
120
168
  ```
121
169
 
122
170
  ## 7. Verify
123
171
 
124
- Create or replace `app/routes/index.tsx`:
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. All shilp-sutra components SSR cleanly because they have no client-only side effects at module top-level.
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
- - **CSP.** The static `theme-bootstrap.js` asset complies with strict CSP (no inline scripts required).
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
- - ❌ Mount `<Toaster />` inside route componentsit should live once at the `__root`.
158
- - ❌ Mix `@tailwindcss/postcss` and `@tailwindcss/vite` pick one (Vite plugin recommended for TanStack Start).
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** or `vite dev` / `vite build` will fail with `Failed to resolve import`. Skip if you only use core components.
46
-
47
- | When you import… | Install |
48
- |-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
49
- | `@devalok/shilp-sutra/ui/charts/*` | `pnpm add d3-array d3-axis d3-format d3-interpolate d3-scale d3-selection d3-shape d3-time-format d3-transition` |
50
- | `@devalok/shilp-sutra/ui/data-table` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
51
- | `@devalok/shilp-sutra/composed/date-picker` (+ DateRange, DateTime, Calendar) | `pnpm add date-fns` |
52
- | `@devalok/shilp-sutra/composed/rich-text-editor` (+ RichChatInput, RichTextViewer) | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
53
- | `@devalok/shilp-sutra/ui/input-otp` | `pnpm add input-otp` |
54
- | `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
55
- | `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter` |
56
- | Any `Icon` / `IconButton` with Tabler icons | `pnpm add @tabler/icons-react` |
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 { App } from "./App";
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' / '@tiptap/react' / 'react-pdf' / 'react-markdown' / '@emoji-mart/react'`
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` | `pnpm add date-fns` |
107
- | `…/composed/emoji-picker` | `pnpm add @emoji-mart/data @emoji-mart/react` |
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-array d3-axis d3-format d3-interpolate d3-scale d3-selection d3-shape d3-time-format d3-transition` |
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.46.0.
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.0.0",
3
+ "manifestVersion": "1.1.0",
4
4
  "package": "@devalok/shilp-sutra",
5
- "packageVersion": "0.46.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=\"xs\" variant=\"ghost\" aria-label={`Actions for ${name}`} icon={<IconDots />} />\n </TableRowActions>\n </TableCell>\n</TableRow>"
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
- "theme": {
8707
+ "emojibaseUrl": {
8683
8708
  "type": {
8684
- "name": "enum",
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
- "defaultValue": "search"
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
- "**Wraps @emoji-mart/react**, lazy-loaded with a Skeleton placeholder while the ~200KB bundle fetches. Don't pre-import unless you need it eagerly.",
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(set?)` factory to create a TipTap suggestion plugin that opens the picker on typing `:emoji`. Works with RichChatInput and RichTextEditor.",
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} theme=\"dark\" />"
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
- "Wraps `@emoji-mart/react` which is lazy-loaded shows a Skeleton placeholder while loading",
8785
- "`theme=\"auto\"` reads the `.dark` class on `<html>` to pick light/dark",
8786
- "EmojiPickerPopover auto-closes after selection"
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** `set` prop on EmojiPicker and EmojiPickerPopover — `EmojiSet` type: 'native' | 'apple' | 'google' | 'twitter' | 'facebook'"
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 requires `@emoji-mart/react` + `@emoji-mart/data` peers",
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": {
@@ -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": {