@devalok/shilp-sutra 0.37.1 → 0.39.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/MIGRATION.md +185 -0
- package/dist/_chunks/badge-group.js +4 -4
- package/dist/_chunks/badge-group.js.map +1 -1
- package/dist/_chunks/chat.js +14 -14
- package/dist/_chunks/chat.js.map +1 -1
- package/dist/_chunks/date-picker.js +9 -9
- package/dist/_chunks/date-picker.js.map +1 -1
- package/dist/_chunks/document-preview.js +2 -2
- package/dist/_chunks/document-preview.js.map +1 -1
- package/dist/_chunks/file-preview.js +11 -11
- package/dist/_chunks/file-preview.js.map +1 -1
- package/dist/_chunks/image-preview.js +2 -2
- package/dist/_chunks/image-preview.js.map +1 -1
- package/dist/_chunks/mention-suggestion.js +5 -5
- package/dist/_chunks/mention-suggestion.js.map +1 -1
- package/dist/_chunks/popover.js +3 -3
- package/dist/_chunks/popover.js.map +1 -1
- package/dist/_chunks/rich-chat-input.js +33 -33
- package/dist/_chunks/rich-chat-input.js.map +1 -1
- package/dist/_chunks/shared.js +5 -5
- package/dist/_chunks/shared.js.map +1 -1
- package/dist/_chunks/text.js +2 -2
- package/dist/_chunks/text.js.map +1 -1
- package/dist/_chunks/tiptap.js +977 -968
- package/dist/_chunks/tiptap.js.map +1 -1
- package/dist/_chunks/tree-view.js +1 -1
- package/dist/_chunks/tree-view.js.map +1 -1
- package/dist/_chunks/use-calendar.js +5 -5
- package/dist/_chunks/use-calendar.js.map +1 -1
- package/dist/ai/command-bar.js +10 -10
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.js +4 -4
- package/dist/ai/conversation.js.map +1 -1
- package/dist/composed/activity-feed.js +5 -5
- package/dist/composed/activity-feed.js.map +1 -1
- package/dist/composed/avatar-group.js +4 -4
- package/dist/composed/avatar-group.js.map +1 -1
- package/dist/composed/bulk-action-bar.js +1 -1
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/command-palette.js +5 -5
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/content-card.js +1 -1
- package/dist/composed/content-card.js.map +1 -1
- package/dist/composed/emoji-picker.js +4 -4
- package/dist/composed/emoji-picker.js.map +1 -1
- package/dist/composed/empty-state.js +1 -1
- package/dist/composed/empty-state.js.map +1 -1
- package/dist/composed/error-boundary.js +3 -3
- package/dist/composed/error-boundary.js.map +1 -1
- package/dist/composed/filter-bar.js +1 -1
- package/dist/composed/filter-bar.js.map +1 -1
- package/dist/composed/index.d.ts +0 -2
- package/dist/composed/index.d.ts.map +1 -1
- package/dist/composed/index.js +5 -6
- package/dist/composed/inline-edit.js +1 -1
- package/dist/composed/inline-edit.js.map +1 -1
- package/dist/composed/loading-skeleton.js +9 -9
- package/dist/composed/loading-skeleton.js.map +1 -1
- package/dist/composed/markdown-viewer.js +3 -3
- package/dist/composed/markdown-viewer.js.map +1 -1
- package/dist/composed/multi-select-popover.js +1 -1
- package/dist/composed/multi-select-popover.js.map +1 -1
- package/dist/composed/page-header.js +1 -1
- package/dist/composed/page-header.js.map +1 -1
- package/dist/composed/page-skeletons.js +15 -15
- package/dist/composed/page-skeletons.js.map +1 -1
- package/dist/composed/priority-indicator.js +3 -3
- package/dist/composed/priority-indicator.js.map +1 -1
- package/dist/composed/rich-text-editor.js +11 -11
- package/dist/composed/rich-text-editor.js.map +1 -1
- package/dist/composed/schedule-view.js +3 -3
- package/dist/composed/schedule-view.js.map +1 -1
- package/dist/composed/status-badge.js +3 -3
- package/dist/composed/status-badge.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +0 -1
- package/dist/shell/bottom-navbar.js +6 -6
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/shell/notification-center.js +8 -8
- package/dist/shell/notification-center.js.map +1 -1
- package/dist/shell/notification-preferences.js +1 -1
- package/dist/shell/notification-preferences.js.map +1 -1
- package/dist/shell/sidebar.js +6 -6
- package/dist/shell/sidebar.js.map +1 -1
- package/dist/shell/top-bar.js +4 -4
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/tokens/semantic.css +82 -9
- package/dist/ui/accordion.js +1 -1
- package/dist/ui/accordion.js.map +1 -1
- package/dist/ui/alert-dialog.js +3 -3
- package/dist/ui/alert-dialog.js.map +1 -1
- package/dist/ui/alert.d.ts +1 -2
- package/dist/ui/alert.d.ts.map +1 -1
- package/dist/ui/alert.js +3 -29
- package/dist/ui/alert.js.map +1 -1
- package/dist/ui/autocomplete.js +2 -2
- package/dist/ui/autocomplete.js.map +1 -1
- package/dist/ui/avatar.js +11 -11
- package/dist/ui/avatar.js.map +1 -1
- package/dist/ui/badge-indicator.js +1 -1
- package/dist/ui/badge-indicator.js.map +1 -1
- package/dist/ui/banner.d.ts +3 -5
- package/dist/ui/banner.d.ts.map +1 -1
- package/dist/ui/banner.js +14 -14
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/breadcrumb.js +1 -1
- package/dist/ui/breadcrumb.js.map +1 -1
- package/dist/ui/button.d.ts +2 -2
- package/dist/ui/button.js +14 -14
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/card.js +5 -5
- package/dist/ui/card.js.map +1 -1
- package/dist/ui/charts/index.js +5 -5
- package/dist/ui/charts/index.js.map +1 -1
- package/dist/ui/checkbox.js +1 -1
- package/dist/ui/checkbox.js.map +1 -1
- package/dist/ui/code.js +2 -2
- package/dist/ui/code.js.map +1 -1
- package/dist/ui/color-input.js +10 -10
- package/dist/ui/color-input.js.map +1 -1
- package/dist/ui/color-swatch.js +3 -3
- package/dist/ui/color-swatch.js.map +1 -1
- package/dist/ui/combobox.js +5 -5
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/context-menu.js +6 -6
- package/dist/ui/context-menu.js.map +1 -1
- package/dist/ui/data-table-body.js +1 -1
- package/dist/ui/data-table-body.js.map +1 -1
- package/dist/ui/data-table-bulk-actions.js +2 -2
- package/dist/ui/data-table-bulk-actions.js.map +1 -1
- package/dist/ui/data-table-card.js +2 -2
- package/dist/ui/data-table-card.js.map +1 -1
- package/dist/ui/data-table-header.js +2 -2
- package/dist/ui/data-table-header.js.map +1 -1
- package/dist/ui/data-table-pagination.js +3 -3
- package/dist/ui/data-table-pagination.js.map +1 -1
- package/dist/ui/data-table-toolbar.js +1 -1
- package/dist/ui/data-table-toolbar.js.map +1 -1
- package/dist/ui/data-table.js +1 -1
- package/dist/ui/data-table.js.map +1 -1
- package/dist/ui/devalok-grain.d.ts +1 -1
- package/dist/ui/devalok-grain.js.map +1 -1
- package/dist/ui/dialog.js +2 -2
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/dropdown-menu.js +6 -6
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/dist/ui/file-upload.js +4 -4
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/hover-card.js +1 -1
- package/dist/ui/hover-card.js.map +1 -1
- package/dist/ui/icon-button.js +1 -1
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +2 -2
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/input-otp.js +1 -1
- package/dist/ui/input-otp.js.map +1 -1
- package/dist/ui/input.d.ts +1 -9
- package/dist/ui/input.d.ts.map +1 -1
- package/dist/ui/input.js +28 -29
- package/dist/ui/input.js.map +1 -1
- package/dist/ui/link.js +1 -1
- package/dist/ui/link.js.map +1 -1
- package/dist/ui/menubar.js +8 -8
- package/dist/ui/menubar.js.map +1 -1
- package/dist/ui/navigation-menu.js +3 -3
- package/dist/ui/navigation-menu.js.map +1 -1
- package/dist/ui/number-input.js +3 -3
- package/dist/ui/number-input.js.map +1 -1
- package/dist/ui/pagination.js +1 -1
- package/dist/ui/pagination.js.map +1 -1
- package/dist/ui/progress.js +1 -1
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/radio.js +1 -1
- package/dist/ui/radio.js.map +1 -1
- package/dist/ui/segmented-control.d.ts +1 -1
- package/dist/ui/segmented-control.d.ts.map +1 -1
- package/dist/ui/segmented-control.js +5 -7
- package/dist/ui/segmented-control.js.map +1 -1
- package/dist/ui/select.js +3 -3
- package/dist/ui/select.js.map +1 -1
- package/dist/ui/sheet.js +2 -2
- package/dist/ui/sheet.js.map +1 -1
- package/dist/ui/sidebar.js +11 -11
- package/dist/ui/sidebar.js.map +1 -1
- package/dist/ui/skeleton.js +9 -9
- package/dist/ui/skeleton.js.map +1 -1
- package/dist/ui/slider.js +2 -2
- package/dist/ui/slider.js.map +1 -1
- package/dist/ui/split-button.js +7 -7
- package/dist/ui/split-button.js.map +1 -1
- package/dist/ui/stat-card.js +7 -7
- package/dist/ui/stat-card.js.map +1 -1
- package/dist/ui/status-dot.js +2 -2
- package/dist/ui/status-dot.js.map +1 -1
- package/dist/ui/stepper.js +2 -2
- package/dist/ui/stepper.js.map +1 -1
- package/dist/ui/switch.js +2 -2
- package/dist/ui/switch.js.map +1 -1
- package/dist/ui/tabs.js +3 -3
- package/dist/ui/tabs.js.map +1 -1
- package/dist/ui/textarea.js +1 -1
- package/dist/ui/textarea.js.map +1 -1
- package/dist/ui/toast.js +8 -8
- package/dist/ui/toast.js.map +1 -1
- package/dist/ui/toggle.js +1 -1
- package/dist/ui/toggle.js.map +1 -1
- package/dist/ui/tooltip.js +1 -1
- package/dist/ui/tooltip.js.map +1 -1
- package/docs/components/_header.md +91 -2
- package/docs/components/ui/alert.md +4 -1
- package/docs/components/ui/banner.md +3 -1
- package/docs/components/ui/input.md +4 -2
- package/docs/components/ui/segmented-control.md +13 -6
- package/docs/recipes/customize-brand.md +297 -0
- package/docs/recipes/index.md +51 -0
- package/docs/recipes/install-astro.md +178 -0
- package/docs/recipes/install-next-app-router.md +230 -0
- package/docs/recipes/install-next-pages.md +123 -0
- package/docs/recipes/install-remix.md +171 -0
- package/docs/recipes/install-tanstack-start.md +143 -0
- package/docs/recipes/install-vite.md +170 -0
- package/docs/recipes/server-components.md +209 -0
- package/docs/recipes/troubleshoot.md +217 -0
- package/llms-full.txt +116 -54
- package/llms.txt +42 -17
- package/package.json +46 -35
- package/skill/README.md +99 -0
- package/skill/SKILL.md +144 -0
- package/skill/install.sh +59 -0
- package/skill/references/components-full.md +6997 -0
- package/skill/references/components.md +673 -0
- package/skill/references/customize-brand.md +299 -0
- package/skill/references/server-components.md +211 -0
- package/skill/references/setup-astro.md +180 -0
- package/skill/references/setup-next-app-router.md +232 -0
- package/skill/references/setup-next-pages.md +125 -0
- package/skill/references/setup-remix.md +173 -0
- package/skill/references/setup-tanstack-start.md +145 -0
- package/skill/references/setup-vite.md +172 -0
- package/skill/references/troubleshoot.md +219 -0
- package/dist/composed/responsive-overlay.d.ts +0 -23
- package/dist/composed/responsive-overlay.d.ts.map +0 -1
- package/dist/composed/responsive-overlay.js +0 -40
- package/dist/composed/responsive-overlay.js.map +0 -1
- package/dist/hooks/use-toast.d.ts +0 -17
- package/dist/hooks/use-toast.d.ts.map +0 -1
- package/dist/hooks/use-toast.js +0 -3
- package/dist/tailwind/index.cjs +0 -41
- package/dist/tailwind/index.d.ts +0 -2
- package/dist/tailwind/index.d.ts.map +0 -1
- package/dist/tailwind/index.js +0 -2
- package/dist/tailwind/preset.d.ts +0 -25
- package/dist/tailwind/preset.d.ts.map +0 -1
- package/dist/tailwind/preset.js +0 -17
- package/dist/tailwind/preset.js.map +0 -1
- package/docs/components/composed/responsive-overlay.md +0 -41
- /package/{LICENSE → skill/LICENSE} +0 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# Install: Next.js (App Router)
|
|
2
|
+
|
|
3
|
+
> Setup recipe for adding `@devalok/shilp-sutra` to a Next.js 13+ App Router project.
|
|
4
|
+
|
|
5
|
+
## 1. Detect the framework
|
|
6
|
+
|
|
7
|
+
You are in this recipe if **all** of these are true:
|
|
8
|
+
|
|
9
|
+
- `package.json` lists `"next"` at version `^13.0.0` or higher
|
|
10
|
+
- An `app/` directory exists at the project root or under `src/`
|
|
11
|
+
- An `app/layout.tsx` (or `.jsx`) file exists
|
|
12
|
+
- No `pages/` directory at the project root, OR `pages/` exists but only contains `_app.{js,tsx}` and `_document.{js,tsx}` (legacy artifacts)
|
|
13
|
+
|
|
14
|
+
If `pages/` is the primary router, use [install-next-pages.md](./install-next-pages.md).
|
|
15
|
+
|
|
16
|
+
## 2. Install dependencies
|
|
17
|
+
|
|
18
|
+
Pick the package manager that matches the project's lockfile.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# pnpm (lockfile: pnpm-lock.yaml)
|
|
22
|
+
pnpm add @devalok/shilp-sutra framer-motion next-themes
|
|
23
|
+
pnpm add -D tailwindcss@^4 @tailwindcss/postcss
|
|
24
|
+
|
|
25
|
+
# npm (lockfile: package-lock.json)
|
|
26
|
+
npm install @devalok/shilp-sutra framer-motion next-themes
|
|
27
|
+
npm install -D tailwindcss@^4 @tailwindcss/postcss
|
|
28
|
+
|
|
29
|
+
# yarn (lockfile: yarn.lock)
|
|
30
|
+
yarn add @devalok/shilp-sutra framer-motion next-themes
|
|
31
|
+
yarn add -D tailwindcss@^4 @tailwindcss/postcss
|
|
32
|
+
|
|
33
|
+
# bun (lockfile: bun.lockb)
|
|
34
|
+
bun add @devalok/shilp-sutra framer-motion next-themes
|
|
35
|
+
bun add -d tailwindcss@^4 @tailwindcss/postcss
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Add only if you will render `<Toaster />`:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pnpm add sonner
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Add brand assets package if you need Devalok or Karm logos:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pnpm add @devalok/shilp-sutra-brand
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 3. Configure PostCSS
|
|
51
|
+
|
|
52
|
+
Create or update `postcss.config.mjs` at the project root:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
export default {
|
|
56
|
+
plugins: {
|
|
57
|
+
"@tailwindcss/postcss": {},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
If a `postcss.config.{js,cjs,json}` already exists, merge the plugin in. Do not delete the existing file.
|
|
63
|
+
|
|
64
|
+
## 4. Wire Tailwind 4 + design tokens
|
|
65
|
+
|
|
66
|
+
Locate the global CSS file. Common paths in priority order:
|
|
67
|
+
|
|
68
|
+
- `app/globals.css`
|
|
69
|
+
- `src/app/globals.css`
|
|
70
|
+
- `app/global.css`
|
|
71
|
+
|
|
72
|
+
If none exists, create `app/globals.css`. Set the file contents to (or merge into):
|
|
73
|
+
|
|
74
|
+
```css
|
|
75
|
+
@import "tailwindcss";
|
|
76
|
+
@import "@devalok/shilp-sutra/css";
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Order matters.** `tailwindcss` MUST come first. The shilp-sutra `/css` entry registers `@theme` blocks that the Tailwind import must process.
|
|
80
|
+
|
|
81
|
+
If the project has its own theme overrides, place them AFTER both imports:
|
|
82
|
+
|
|
83
|
+
```css
|
|
84
|
+
@import "tailwindcss";
|
|
85
|
+
@import "@devalok/shilp-sutra/css";
|
|
86
|
+
|
|
87
|
+
@theme {
|
|
88
|
+
--color-brand: oklch(0.65 0.2 280);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Import the CSS file once from `app/layout.tsx` (it should already be imported in a fresh `create-next-app` project):
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
import "./globals.css";
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 5. Configure `transpilePackages`
|
|
99
|
+
|
|
100
|
+
Edit `next.config.{ts,js,mjs}`. Add the `transpilePackages` field:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import type { NextConfig } from "next";
|
|
104
|
+
|
|
105
|
+
const nextConfig: NextConfig = {
|
|
106
|
+
transpilePackages: ["@devalok/shilp-sutra", "@devalok/shilp-sutra-brand"],
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export default nextConfig;
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
If a `transpilePackages` array already exists, append to it. Do not replace.
|
|
113
|
+
|
|
114
|
+
Without `transpilePackages`, Next will refuse to load our pre-built `dist/*.js` because it ships native ESM that does not match Next's CJS-leaning loader for `node_modules`.
|
|
115
|
+
|
|
116
|
+
## 6. Scaffold the Providers wrapper
|
|
117
|
+
|
|
118
|
+
Create `app/providers.tsx`:
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
"use client";
|
|
122
|
+
|
|
123
|
+
import type { ReactNode } from "react";
|
|
124
|
+
import { ThemeProvider } from "next-themes";
|
|
125
|
+
import { Toaster } from "@devalok/shilp-sutra/ui/toaster";
|
|
126
|
+
|
|
127
|
+
export function Providers({ children }: { children: ReactNode }) {
|
|
128
|
+
return (
|
|
129
|
+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
|
130
|
+
{children}
|
|
131
|
+
<Toaster />
|
|
132
|
+
</ThemeProvider>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`next-themes` is already in the install list from § 2 — no extra install step needed here. If `<Toaster />` is not used:
|
|
138
|
+
|
|
139
|
+
- Drop the `Toaster` import and its JSX usage
|
|
140
|
+
- Skip installing `sonner`
|
|
141
|
+
|
|
142
|
+
Mount `<Providers>` from `app/layout.tsx`:
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
import "./globals.css";
|
|
146
|
+
import { Providers } from "./providers";
|
|
147
|
+
|
|
148
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
149
|
+
return (
|
|
150
|
+
<html lang="en" suppressHydrationWarning>
|
|
151
|
+
<body>
|
|
152
|
+
<Providers>{children}</Providers>
|
|
153
|
+
</body>
|
|
154
|
+
</html>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`suppressHydrationWarning` on `<html>` is required because `next-themes` writes the `class` attribute before React hydrates. Without it, every page logs a hydration warning.
|
|
160
|
+
|
|
161
|
+
## 7. Verify the install
|
|
162
|
+
|
|
163
|
+
Replace the contents of `app/page.tsx`:
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
import { Button } from "@devalok/shilp-sutra/ui/button";
|
|
167
|
+
import { Stack } from "@devalok/shilp-sutra/ui/stack";
|
|
168
|
+
import { Text } from "@devalok/shilp-sutra/ui/text";
|
|
169
|
+
|
|
170
|
+
export default function Home() {
|
|
171
|
+
return (
|
|
172
|
+
<Stack className="p-ds-08" gap="ds-04">
|
|
173
|
+
<Text variant="heading-2xl">Hello, Shilp Sutra</Text>
|
|
174
|
+
<Stack direction="row" gap="ds-03">
|
|
175
|
+
<Button>Primary</Button>
|
|
176
|
+
<Button variant="soft">Soft</Button>
|
|
177
|
+
<Button variant="outline">Outline</Button>
|
|
178
|
+
</Stack>
|
|
179
|
+
</Stack>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Run the dev server:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
pnpm dev
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Open `http://localhost:3000`. You should see:
|
|
191
|
+
|
|
192
|
+
- The heading rendered in **Ranade** (display font), the buttons in **Inter** (body font)
|
|
193
|
+
- The primary button on a saturated accent background, the soft button with a tinted background and no border, the outline button with a border and transparent background
|
|
194
|
+
- No hydration warning in the browser console
|
|
195
|
+
- No 404 for fonts (fonts are bundled inside the package; `next/font` is not required)
|
|
196
|
+
|
|
197
|
+
If anything is off, see [troubleshoot.md](./troubleshoot.md).
|
|
198
|
+
|
|
199
|
+
## 8. Common gotchas
|
|
200
|
+
|
|
201
|
+
- **CSS import order.** `tailwindcss` BEFORE `@devalok/shilp-sutra/css`. Reversing the order silently produces a build with no design-system utilities.
|
|
202
|
+
- **Multiple `framer-motion` copies.** Run `pnpm why framer-motion`. If it shows more than one resolved version, contexts (`MotionConfig`, `LayoutGroup`, `AnimatePresence`) silently break. Fix:
|
|
203
|
+
```jsonc
|
|
204
|
+
// package.json
|
|
205
|
+
{
|
|
206
|
+
"pnpm": {
|
|
207
|
+
"overrides": {
|
|
208
|
+
"framer-motion": "^12"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
For npm/yarn/bun equivalents, see [troubleshoot.md](./troubleshoot.md).
|
|
214
|
+
- **Server Component imports.** Use per-component imports (`@devalok/shilp-sutra/ui/text`) inside Server Components. The barrel import `@devalok/shilp-sutra/ui` pulls client-only code and breaks RSC. See [server-components.md](./server-components.md).
|
|
215
|
+
- **`p-3` vs `p-ds-03`.** Our spacing namespace is `--spacing-ds-*` to avoid collision with consumer numeric spacing. Use `p-ds-04`, not `p-4`.
|
|
216
|
+
- **Bare `shadow` is dead.** Tailwind 4 has no `--shadow-DEFAULT`. Use `shadow-raised`, `shadow-overlay`, or `shadow-floating`.
|
|
217
|
+
|
|
218
|
+
## 9. What you should NOT do
|
|
219
|
+
|
|
220
|
+
- ❌ Create `tailwind.config.ts` with `presets: [shilpSutra]` — the JS preset was removed in 0.38.
|
|
221
|
+
- ❌ Add `@plugin "@devalok/shilp-sutra/tailwind"` — also removed.
|
|
222
|
+
- ❌ Wrap the whole app in `<MotionConfig reducedMotion="...">` unless the user explicitly asks for a global motion override; Shilp Sutra components already respect `prefers-reduced-motion`.
|
|
223
|
+
- ❌ Import from `@devalok/shilp-sutra/tailwind` — the export was removed in 0.38.
|
|
224
|
+
- ❌ Run `pnpm add @radix-ui/react-*` — Radix is vendored; no @radix-ui runtime deps are required.
|
|
225
|
+
|
|
226
|
+
## 10. Optional next steps
|
|
227
|
+
|
|
228
|
+
- **Brand customization** — swap accent color, radius scale, or fonts: see [customize-brand.md](./customize-brand.md).
|
|
229
|
+
- **App shell** — add a sidebar + topbar layout: read `llms-full.txt` sections for `AppSidebar` and `TopBar`.
|
|
230
|
+
- **Server-safe components** — push as much rendering as possible into Server Components: see [server-components.md](./server-components.md).
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Install: Next.js (Pages Router)
|
|
2
|
+
|
|
3
|
+
> Setup recipe for adding `@devalok/shilp-sutra` to a Next.js project that uses the Pages Router (`pages/_app.tsx` as the entry).
|
|
4
|
+
|
|
5
|
+
## 1. Detect
|
|
6
|
+
|
|
7
|
+
You are in this recipe if:
|
|
8
|
+
|
|
9
|
+
- `package.json` lists `"next"` (any version `>= 12`)
|
|
10
|
+
- A `pages/` directory exists at the project root or under `src/` and contains `_app.{js,tsx}` (and optionally `_document.{js,tsx}`)
|
|
11
|
+
- `app/` directory does NOT exist, OR exists but is unused
|
|
12
|
+
|
|
13
|
+
If both `app/` and `pages/` exist, prefer [install-next-app-router.md](./install-next-app-router.md) and treat the Pages Router as legacy.
|
|
14
|
+
|
|
15
|
+
## 2. Install
|
|
16
|
+
|
|
17
|
+
Same dependencies as the App Router recipe — see [install-next-app-router.md § 2](./install-next-app-router.md#2-install-dependencies). Replace `next-themes`'s `attribute="class"` setup with the same on Pages Router (it works identically).
|
|
18
|
+
|
|
19
|
+
## 3. PostCSS
|
|
20
|
+
|
|
21
|
+
Same as App Router — see [§ 3](./install-next-app-router.md#3-configure-postcss).
|
|
22
|
+
|
|
23
|
+
## 4. Wire Tailwind 4 + tokens
|
|
24
|
+
|
|
25
|
+
Common CSS entry paths in priority order:
|
|
26
|
+
|
|
27
|
+
- `styles/globals.css`
|
|
28
|
+
- `src/styles/globals.css`
|
|
29
|
+
- `pages/_app.css` (rare)
|
|
30
|
+
|
|
31
|
+
If none exists, create `styles/globals.css` with:
|
|
32
|
+
|
|
33
|
+
```css
|
|
34
|
+
@import "tailwindcss";
|
|
35
|
+
@import "@devalok/shilp-sutra/css";
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Import it from `pages/_app.tsx`:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import "../styles/globals.css";
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 5. `transpilePackages`
|
|
45
|
+
|
|
46
|
+
Identical to App Router — see [§ 5](./install-next-app-router.md#5-configure-transpilepackages).
|
|
47
|
+
|
|
48
|
+
## 6. Providers in `_app.tsx`
|
|
49
|
+
|
|
50
|
+
Replace or merge into `pages/_app.tsx`:
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import "../styles/globals.css";
|
|
54
|
+
import type { AppProps } from "next/app";
|
|
55
|
+
import { ThemeProvider } from "next-themes";
|
|
56
|
+
import { Toaster } from "@devalok/shilp-sutra/ui/toaster";
|
|
57
|
+
|
|
58
|
+
export default function App({ Component, pageProps }: AppProps) {
|
|
59
|
+
return (
|
|
60
|
+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
|
61
|
+
<Component {...pageProps} />
|
|
62
|
+
<Toaster />
|
|
63
|
+
</ThemeProvider>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
For `next-themes` to avoid hydration warnings, add a `_document.tsx` with `suppressHydrationWarning` on the `<html>`:
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
// pages/_document.tsx
|
|
72
|
+
import { Html, Head, Main, NextScript } from "next/document";
|
|
73
|
+
|
|
74
|
+
export default function Document() {
|
|
75
|
+
return (
|
|
76
|
+
<Html lang="en" suppressHydrationWarning>
|
|
77
|
+
<Head />
|
|
78
|
+
<body>
|
|
79
|
+
<Main />
|
|
80
|
+
<NextScript />
|
|
81
|
+
</body>
|
|
82
|
+
</Html>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 7. Verify
|
|
88
|
+
|
|
89
|
+
Replace `pages/index.tsx`:
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { Button } from "@devalok/shilp-sutra/ui/button";
|
|
93
|
+
import { Stack } from "@devalok/shilp-sutra/ui/stack";
|
|
94
|
+
import { Text } from "@devalok/shilp-sutra/ui/text";
|
|
95
|
+
|
|
96
|
+
export default function Home() {
|
|
97
|
+
return (
|
|
98
|
+
<Stack className="p-ds-08" gap="ds-04">
|
|
99
|
+
<Text variant="heading-2xl">Hello, Shilp Sutra</Text>
|
|
100
|
+
<Stack direction="row" gap="ds-03">
|
|
101
|
+
<Button>Primary</Button>
|
|
102
|
+
<Button variant="soft">Soft</Button>
|
|
103
|
+
</Stack>
|
|
104
|
+
</Stack>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Run `pnpm dev` and open `http://localhost:3000`. Expected output is the same as the App Router recipe — see [§ 7](./install-next-app-router.md#7-verify-the-install).
|
|
110
|
+
|
|
111
|
+
## 8. Pages Router specifics
|
|
112
|
+
|
|
113
|
+
- **No React Server Components.** Every component runs on the client. Per-component imports still help tree-shaking but are not required for RSC safety.
|
|
114
|
+
- **`getServerSideProps` / `getStaticProps`** — do not import shilp-sutra components inside these (they run server-side and won't render JSX). Components are imported and used in the page module's default export, as usual.
|
|
115
|
+
- **`pages/_document.tsx` runs server-only.** Do not import shilp-sutra components there.
|
|
116
|
+
|
|
117
|
+
## 9. Gotchas
|
|
118
|
+
|
|
119
|
+
Same as App Router — see [§ 8](./install-next-app-router.md#8-common-gotchas).
|
|
120
|
+
|
|
121
|
+
## 10. What NOT to do
|
|
122
|
+
|
|
123
|
+
Same as App Router — see [§ 9](./install-next-app-router.md#9-what-you-should-not-do).
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Install: Remix
|
|
2
|
+
|
|
3
|
+
> Setup recipe for adding `@devalok/shilp-sutra` to a Remix project (v2 with Vite).
|
|
4
|
+
|
|
5
|
+
## 1. Detect
|
|
6
|
+
|
|
7
|
+
You are in this recipe if:
|
|
8
|
+
|
|
9
|
+
- `package.json` lists `"@remix-run/node"` and `"@remix-run/react"`
|
|
10
|
+
- `vite.config.{ts,js}` exists with the `vitePlugin` from `@remix-run/dev`
|
|
11
|
+
- `app/root.tsx` exists with `<Outlet />` inside `<Document>` shell
|
|
12
|
+
|
|
13
|
+
For React Router v7 (the spiritual successor to Remix), use the [install-vite.md](./install-vite.md) recipe — it works the same way.
|
|
14
|
+
|
|
15
|
+
## 2. Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add @devalok/shilp-sutra framer-motion
|
|
19
|
+
pnpm add -D tailwindcss@^4 @tailwindcss/vite
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Optional:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add sonner # only if rendering <Toaster />
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 3. Wire Tailwind 4 in `vite.config.ts`
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { vitePlugin as remix } from "@remix-run/dev";
|
|
32
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
33
|
+
import { defineConfig } from "vite";
|
|
34
|
+
|
|
35
|
+
export default defineConfig({
|
|
36
|
+
plugins: [
|
|
37
|
+
tailwindcss(),
|
|
38
|
+
remix(),
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`tailwindcss()` should come before `remix()` so the design tokens are processed first.
|
|
44
|
+
|
|
45
|
+
## 4. Wire tokens
|
|
46
|
+
|
|
47
|
+
Create `app/styles/globals.css`:
|
|
48
|
+
|
|
49
|
+
```css
|
|
50
|
+
@import "tailwindcss";
|
|
51
|
+
@import "@devalok/shilp-sutra/css";
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Wire it as a Remix link export from `app/root.tsx`:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import type { LinksFunction } from "@remix-run/node";
|
|
58
|
+
import globalsCss from "./styles/globals.css?url";
|
|
59
|
+
|
|
60
|
+
export const links: LinksFunction = () => [
|
|
61
|
+
{ rel: "stylesheet", href: globalsCss },
|
|
62
|
+
];
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The `?url` suffix is critical — it tells Vite to emit the file as an asset URL instead of inlining the CSS contents.
|
|
66
|
+
|
|
67
|
+
## 5. Theme toggle
|
|
68
|
+
|
|
69
|
+
Create `public/theme-bootstrap.js` (a static asset served verbatim):
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
(function () {
|
|
73
|
+
try {
|
|
74
|
+
var stored = localStorage.getItem("theme");
|
|
75
|
+
var prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
76
|
+
if (stored === "dark" || (!stored && prefersDark)) {
|
|
77
|
+
document.documentElement.classList.add("dark");
|
|
78
|
+
}
|
|
79
|
+
} catch (e) {}
|
|
80
|
+
})();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Reference it from `app/root.tsx` so it loads before any React hydration:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { Outlet, Meta, Links, Scripts, ScrollRestoration } from "@remix-run/react";
|
|
87
|
+
|
|
88
|
+
export default function App() {
|
|
89
|
+
return (
|
|
90
|
+
<html lang="en" suppressHydrationWarning>
|
|
91
|
+
<head>
|
|
92
|
+
<Meta />
|
|
93
|
+
<Links />
|
|
94
|
+
<script src="/theme-bootstrap.js" />
|
|
95
|
+
</head>
|
|
96
|
+
<body>
|
|
97
|
+
<Outlet />
|
|
98
|
+
<ScrollRestoration />
|
|
99
|
+
<Scripts />
|
|
100
|
+
</body>
|
|
101
|
+
</html>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
For runtime toggling inside React components, use `useColorMode`:
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
import { useColorMode } from "@devalok/shilp-sutra/hooks/use-color-mode";
|
|
110
|
+
|
|
111
|
+
export function ThemeToggle() {
|
|
112
|
+
const { mode, toggle } = useColorMode();
|
|
113
|
+
return (
|
|
114
|
+
<button onClick={toggle} aria-label="Toggle theme">
|
|
115
|
+
{mode === "dark" ? "☀" : "☾"}
|
|
116
|
+
</button>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## 6. Toaster (optional)
|
|
122
|
+
|
|
123
|
+
Mount once in `app/root.tsx` next to `<Outlet />`:
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
import { Toaster } from "@devalok/shilp-sutra/ui/toaster";
|
|
127
|
+
|
|
128
|
+
// inside <body>
|
|
129
|
+
<>
|
|
130
|
+
<Outlet />
|
|
131
|
+
<Toaster />
|
|
132
|
+
</>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 7. Verify
|
|
136
|
+
|
|
137
|
+
Create `app/routes/_index.tsx`:
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import { Button } from "@devalok/shilp-sutra/ui/button";
|
|
141
|
+
import { Stack } from "@devalok/shilp-sutra/ui/stack";
|
|
142
|
+
import { Text } from "@devalok/shilp-sutra/ui/text";
|
|
143
|
+
|
|
144
|
+
export default function Index() {
|
|
145
|
+
return (
|
|
146
|
+
<Stack className="p-ds-08" gap="ds-04">
|
|
147
|
+
<Text variant="heading-2xl">Hello, Shilp Sutra</Text>
|
|
148
|
+
<Stack direction="row" gap="ds-03">
|
|
149
|
+
<Button>Primary</Button>
|
|
150
|
+
<Button variant="soft">Soft</Button>
|
|
151
|
+
</Stack>
|
|
152
|
+
</Stack>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Run `pnpm dev` and open the URL.
|
|
158
|
+
|
|
159
|
+
## 8. Remix-specific gotchas
|
|
160
|
+
|
|
161
|
+
- **`?url` suffix on CSS imports.** Without it, Vite tries to inline the CSS, which breaks Tailwind processing.
|
|
162
|
+
- **Loaders are server-only.** Do not import shilp-sutra components inside a `loader` function — they will not render.
|
|
163
|
+
- **Server-rendered output.** Remix SSRs every route. The CSS-in-JS-free approach of shilp-sutra works perfectly here; no extra config needed.
|
|
164
|
+
- **`framer-motion` and SSR.** All shilp-sutra animations gracefully degrade for the initial server render. No special handling required.
|
|
165
|
+
- **CSP.** If your CSP blocks inline scripts, the `theme-bootstrap.js` static asset above already complies (no `unsafe-inline` needed).
|
|
166
|
+
|
|
167
|
+
## 9. What NOT to do
|
|
168
|
+
|
|
169
|
+
- ❌ Add `tailwind.config.{ts,js}` — Tailwind 4 is CSS-first.
|
|
170
|
+
- ❌ Skip the `?url` suffix on CSS imports.
|
|
171
|
+
- ❌ Mount `<Toaster />` inside route components — it should live once at the root.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Install: TanStack Start
|
|
2
|
+
|
|
3
|
+
> Setup recipe for adding `@devalok/shilp-sutra` to a TanStack Start project (the React full-stack framework built on Vinxi/Vite).
|
|
4
|
+
|
|
5
|
+
## 1. Detect
|
|
6
|
+
|
|
7
|
+
You are in this recipe if:
|
|
8
|
+
|
|
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
|
|
12
|
+
|
|
13
|
+
## 2. Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add @devalok/shilp-sutra framer-motion
|
|
17
|
+
pnpm add -D tailwindcss@^4 @tailwindcss/vite
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Optional:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm add sonner # only if rendering <Toaster />
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 3. Wire Tailwind 4 in `app.config.ts`
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { defineConfig } from "@tanstack/start/config";
|
|
30
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
31
|
+
|
|
32
|
+
export default defineConfig({
|
|
33
|
+
vite: {
|
|
34
|
+
plugins: [tailwindcss()],
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 4. Wire tokens
|
|
40
|
+
|
|
41
|
+
Create `app/styles/globals.css`:
|
|
42
|
+
|
|
43
|
+
```css
|
|
44
|
+
@import "tailwindcss";
|
|
45
|
+
@import "@devalok/shilp-sutra/css";
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Import it from `app/routes/__root.tsx`:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import "../styles/globals.css";
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
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`.
|
|
55
|
+
|
|
56
|
+
## 5. Theme toggle
|
|
57
|
+
|
|
58
|
+
Create `public/theme-bootstrap.js` (a static asset served verbatim):
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
(function () {
|
|
62
|
+
try {
|
|
63
|
+
var stored = localStorage.getItem("theme");
|
|
64
|
+
var prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
65
|
+
if (stored === "dark" || (!stored && prefersDark)) {
|
|
66
|
+
document.documentElement.classList.add("dark");
|
|
67
|
+
}
|
|
68
|
+
} catch (e) {}
|
|
69
|
+
})();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Reference it from `app/routes/__root.tsx`:
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import { createRootRoute, Outlet } from "@tanstack/react-router";
|
|
76
|
+
|
|
77
|
+
export const Route = createRootRoute({
|
|
78
|
+
component: () => (
|
|
79
|
+
<html lang="en" suppressHydrationWarning>
|
|
80
|
+
<head>
|
|
81
|
+
<script src="/theme-bootstrap.js" />
|
|
82
|
+
</head>
|
|
83
|
+
<body>
|
|
84
|
+
<Outlet />
|
|
85
|
+
</body>
|
|
86
|
+
</html>
|
|
87
|
+
),
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
For runtime toggling, use the `useColorMode` hook — see [install-vite.md § 5](./install-vite.md#5-theme-toggle-no-next-themes-here).
|
|
92
|
+
|
|
93
|
+
## 6. Toaster (optional)
|
|
94
|
+
|
|
95
|
+
Mount in `__root.tsx` next to `<Outlet />`:
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
import { Toaster } from "@devalok/shilp-sutra/ui/toaster";
|
|
99
|
+
|
|
100
|
+
// inside <body>
|
|
101
|
+
<>
|
|
102
|
+
<Outlet />
|
|
103
|
+
<Toaster />
|
|
104
|
+
</>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 7. Verify
|
|
108
|
+
|
|
109
|
+
Create or replace `app/routes/index.tsx`:
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
113
|
+
import { Button } from "@devalok/shilp-sutra/ui/button";
|
|
114
|
+
import { Stack } from "@devalok/shilp-sutra/ui/stack";
|
|
115
|
+
import { Text } from "@devalok/shilp-sutra/ui/text";
|
|
116
|
+
|
|
117
|
+
export const Route = createFileRoute("/")({
|
|
118
|
+
component: () => (
|
|
119
|
+
<Stack className="p-ds-08" gap="ds-04">
|
|
120
|
+
<Text variant="heading-2xl">Hello, Shilp Sutra</Text>
|
|
121
|
+
<Stack direction="row" gap="ds-03">
|
|
122
|
+
<Button>Primary</Button>
|
|
123
|
+
<Button variant="soft">Soft</Button>
|
|
124
|
+
</Stack>
|
|
125
|
+
</Stack>
|
|
126
|
+
),
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Run `pnpm dev` and open the URL.
|
|
131
|
+
|
|
132
|
+
## 8. TanStack Start specifics
|
|
133
|
+
|
|
134
|
+
- **Server functions** (`createServerFn`) — do not import shilp-sutra components inside server functions; they run server-only.
|
|
135
|
+
- **Streaming SSR** is the default. All shilp-sutra components SSR cleanly because they have no client-only side effects at module top-level.
|
|
136
|
+
- **`framer-motion` SSR** — animations gracefully degrade on the initial render.
|
|
137
|
+
- **CSP.** The static `theme-bootstrap.js` asset complies with strict CSP (no inline scripts required).
|
|
138
|
+
|
|
139
|
+
## 9. What NOT to do
|
|
140
|
+
|
|
141
|
+
- ❌ Add `tailwind.config.{ts,js}` — Tailwind 4 is CSS-first.
|
|
142
|
+
- ❌ Mount `<Toaster />` inside route components — it should live once at the `__root`.
|
|
143
|
+
- ❌ Mix `@tailwindcss/postcss` and `@tailwindcss/vite` — pick one (Vite plugin recommended for TanStack Start).
|