@devalok/shilp-sutra 0.39.0 → 0.40.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 +151 -0
- package/MIGRATION.md +137 -0
- package/README.md +3 -0
- package/dist/_chunks/badge-group.js +75 -74
- package/dist/_chunks/badge-group.js.map +1 -1
- package/dist/_chunks/chart-container.js +50 -0
- package/dist/_chunks/chart-container.js.map +1 -0
- package/dist/_chunks/chat.js +231 -223
- package/dist/_chunks/chat.js.map +1 -1
- package/dist/_chunks/colors.js +30 -0
- package/dist/_chunks/colors.js.map +1 -0
- package/dist/_chunks/emoji-data.js +45 -0
- package/dist/_chunks/emoji-data.js.map +1 -0
- package/dist/_chunks/grid-lines.js +72 -0
- package/dist/_chunks/grid-lines.js.map +1 -0
- package/dist/_chunks/mention-suggestion.js +31 -259
- package/dist/_chunks/mention-suggestion.js.map +1 -1
- package/dist/_chunks/normalize-icon.js +18 -0
- package/dist/_chunks/normalize-icon.js.map +1 -0
- package/dist/_chunks/oauth-button.js +227 -0
- package/dist/_chunks/oauth-button.js.map +1 -0
- package/dist/_chunks/primitives.js +107 -107
- package/dist/_chunks/primitives.js.map +1 -1
- package/dist/_chunks/{text.js → success.js} +24 -61
- package/dist/_chunks/success.js.map +1 -0
- package/dist/_chunks/tiptap.js +1952 -1949
- package/dist/_chunks/tiptap.js.map +1 -1
- package/dist/_chunks/tooltip.js +58 -0
- package/dist/_chunks/tooltip.js.map +1 -0
- package/dist/_chunks/tree-view.js +101 -96
- package/dist/_chunks/tree-view.js.map +1 -1
- package/dist/ai/ai-command-provider.d.ts +3 -2
- package/dist/ai/ai-command-provider.d.ts.map +1 -1
- package/dist/ai/ai-command-provider.js.map +1 -1
- package/dist/ai/block-renderer.js +11 -9
- package/dist/ai/block-renderer.js.map +1 -1
- package/dist/ai/blocks/error.js +31 -0
- package/dist/ai/blocks/error.js.map +1 -0
- package/dist/ai/blocks/index.d.ts +0 -2
- package/dist/ai/blocks/index.d.ts.map +1 -1
- package/dist/ai/blocks/index.js +2 -2
- package/dist/ai/blocks/text.js +19 -0
- package/dist/ai/blocks/text.js.map +1 -0
- package/dist/ai/command-bar.d.ts.map +1 -1
- package/dist/ai/command-bar.js +192 -187
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.d.ts +2 -1
- package/dist/ai/conversation.d.ts.map +1 -1
- package/dist/ai/conversation.js +88 -83
- package/dist/ai/conversation.js.map +1 -1
- package/dist/ai/index.d.ts +0 -4
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +45 -46
- package/dist/ai/index.js.map +1 -1
- package/dist/composed/activity-feed.d.ts +2 -1
- package/dist/composed/activity-feed.d.ts.map +1 -1
- package/dist/composed/activity-feed.js.map +1 -1
- package/dist/composed/bulk-action-bar.d.ts +2 -2
- package/dist/composed/bulk-action-bar.d.ts.map +1 -1
- package/dist/composed/bulk-action-bar.js +11 -11
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/command-palette.d.ts +2 -1
- package/dist/composed/command-palette.d.ts.map +1 -1
- package/dist/composed/command-palette.js +103 -98
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/date-picker/index.js +747 -3
- package/dist/composed/date-picker/index.js.map +1 -0
- package/dist/composed/empty-state.d.ts +3 -3
- package/dist/composed/empty-state.d.ts.map +1 -1
- package/dist/composed/empty-state.js +40 -31
- package/dist/composed/empty-state.js.map +1 -1
- package/dist/composed/extensions/emoji-node.js +81 -0
- package/dist/composed/extensions/emoji-node.js.map +1 -0
- package/dist/composed/extensions/emoji-suggestion.js +117 -0
- package/dist/composed/extensions/emoji-suggestion.js.map +1 -0
- package/dist/composed/file-preview.js +498 -2
- package/dist/{_chunks → composed}/file-preview.js.map +1 -1
- package/dist/composed/index.d.ts +0 -15
- package/dist/composed/index.d.ts.map +1 -1
- package/dist/composed/index.js +16 -24
- package/dist/composed/rich-chat-input.js +2073 -2
- package/dist/{_chunks → composed}/rich-chat-input.js.map +1 -1
- package/dist/composed/rich-text-editor.js +64 -61
- package/dist/composed/rich-text-editor.js.map +1 -1
- package/dist/composed/status-badge.d.ts +3 -2
- package/dist/composed/status-badge.d.ts.map +1 -1
- package/dist/composed/status-badge.js +58 -53
- package/dist/composed/status-badge.js.map +1 -1
- package/dist/shell/app-command-palette.d.ts +2 -1
- package/dist/shell/app-command-palette.d.ts.map +1 -1
- package/dist/shell/app-command-palette.js.map +1 -1
- package/dist/shell/bottom-navbar.d.ts +3 -1
- package/dist/shell/bottom-navbar.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.js +90 -82
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/shell/command-registry.d.ts +2 -1
- package/dist/shell/command-registry.d.ts.map +1 -1
- package/dist/shell/command-registry.js.map +1 -1
- package/dist/shell/sidebar.d.ts +7 -4
- package/dist/shell/sidebar.d.ts.map +1 -1
- package/dist/shell/sidebar.js +143 -129
- package/dist/shell/sidebar.js.map +1 -1
- package/dist/shell/top-bar.d.ts +4 -3
- package/dist/shell/top-bar.d.ts.map +1 -1
- package/dist/shell/top-bar.js +114 -106
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/ui/badge.d.ts +3 -2
- package/dist/ui/badge.d.ts.map +1 -1
- package/dist/ui/button.d.ts +3 -2
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +54 -53
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/charts/area-chart.js +177 -0
- package/dist/ui/charts/area-chart.js.map +1 -0
- package/dist/ui/charts/bar-chart.js +127 -0
- package/dist/ui/charts/bar-chart.js.map +1 -0
- package/dist/ui/charts/chart-container.js +3 -0
- package/dist/ui/charts/gauge-chart.js +72 -0
- package/dist/ui/charts/gauge-chart.js.map +1 -0
- package/dist/ui/charts/index.js +10 -1035
- package/dist/ui/charts/line-chart.js +135 -0
- package/dist/ui/charts/line-chart.js.map +1 -0
- package/dist/ui/charts/pie-chart.js +111 -0
- package/dist/ui/charts/pie-chart.js.map +1 -0
- package/dist/ui/charts/radar-chart.js +170 -0
- package/dist/ui/charts/radar-chart.js.map +1 -0
- package/dist/ui/charts/sparkline.js +119 -0
- package/dist/ui/charts/sparkline.js.map +1 -0
- package/dist/ui/chat/message.d.ts +3 -3
- package/dist/ui/chat/message.d.ts.map +1 -1
- package/dist/ui/chat/system-message.d.ts +2 -1
- package/dist/ui/chat/system-message.d.ts.map +1 -1
- package/dist/ui/combobox.d.ts +2 -1
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +97 -92
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/container.d.ts +6 -1
- package/dist/ui/container.d.ts.map +1 -1
- package/dist/ui/container.js +2 -1
- package/dist/ui/container.js.map +1 -1
- package/dist/ui/icon-button.d.ts +9 -2
- package/dist/ui/icon-button.d.ts.map +1 -1
- package/dist/ui/icon-button.js +14 -13
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/index.d.ts +1 -3
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +31 -33
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/lib/icon-input.d.ts +42 -0
- package/dist/ui/lib/icon-input.d.ts.map +1 -0
- package/dist/ui/lib/normalize-icon.d.ts +39 -0
- package/dist/ui/lib/normalize-icon.d.ts.map +1 -0
- package/dist/ui/oauth-button/index.d.ts +3 -0
- package/dist/ui/oauth-button/index.d.ts.map +1 -0
- package/dist/ui/oauth-button/index.js +3 -0
- package/dist/ui/oauth-button/oauth-button.d.ts +208 -0
- package/dist/ui/oauth-button/oauth-button.d.ts.map +1 -0
- package/dist/ui/progress.js +1 -1
- package/dist/ui/segmented-control.d.ts +3 -4
- package/dist/ui/segmented-control.d.ts.map +1 -1
- package/dist/ui/segmented-control.js +53 -45
- package/dist/ui/segmented-control.js.map +1 -1
- package/dist/ui/stack.d.ts +6 -1
- package/dist/ui/stack.d.ts.map +1 -1
- package/dist/ui/stack.js +2 -1
- package/dist/ui/stack.js.map +1 -1
- package/dist/ui/stat-card.d.ts +2 -3
- package/dist/ui/stat-card.d.ts.map +1 -1
- package/dist/ui/stat-card.js +117 -115
- package/dist/ui/stat-card.js.map +1 -1
- package/dist/ui/stepper.d.ts +2 -1
- package/dist/ui/stepper.d.ts.map +1 -1
- package/dist/ui/stepper.js +74 -69
- package/dist/ui/stepper.js.map +1 -1
- package/dist/ui/text.d.ts +7 -2
- package/dist/ui/text.d.ts.map +1 -1
- package/dist/ui/text.js +2 -1
- package/dist/ui/text.js.map +1 -1
- package/dist/ui/toaster.d.ts +11 -2
- package/dist/ui/toaster.d.ts.map +1 -1
- package/dist/ui/toaster.js.map +1 -1
- package/dist/ui/tooltip.js +12 -12
- package/dist/ui/tree-view/tree-item.d.ts +3 -2
- package/dist/ui/tree-view/tree-item.d.ts.map +1 -1
- package/dist/ui/tree-view/use-tree.d.ts +2 -1
- package/dist/ui/tree-view/use-tree.d.ts.map +1 -1
- package/docs/components/ui/oauth-button.md +86 -0
- package/docs/recipes/customize-brand.md +15 -0
- package/docs/recipes/index.md +5 -1
- package/docs/recipes/install-astro.md +15 -0
- package/docs/recipes/install-next-app-router.md +21 -5
- package/docs/recipes/install-next-pages.md +2 -0
- package/docs/recipes/install-remix.md +15 -0
- package/docs/recipes/install-tanstack-start.md +15 -0
- package/docs/recipes/install-vite.md +15 -0
- package/docs/recipes/troubleshoot.md +22 -0
- package/llms-full.txt +87 -1
- package/llms-quick.txt +247 -0
- package/llms.txt +107 -2
- package/package.json +79 -2
- package/scripts/welcome.mjs +219 -0
- package/skill/SKILL.md +22 -3
- package/skill/references/components-full.md +87 -1
- package/skill/references/components.md +107 -2
- package/skill/references/customize-brand.md +15 -0
- package/skill/references/setup-astro.md +15 -0
- package/skill/references/setup-next-app-router.md +21 -5
- package/skill/references/setup-next-pages.md +2 -0
- package/skill/references/setup-remix.md +15 -0
- package/skill/references/setup-tanstack-start.md +15 -0
- package/skill/references/setup-vite.md +15 -0
- package/skill/references/troubleshoot.md +22 -0
- package/dist/_chunks/date-picker.js +0 -748
- package/dist/_chunks/date-picker.js.map +0 -1
- package/dist/_chunks/file-preview.js +0 -499
- package/dist/_chunks/rich-chat-input.js +0 -2071
- package/dist/_chunks/text.js.map +0 -1
- package/dist/ui/charts/index.js.map +0 -1
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
> All variant values and props verified from source CVA definitions.
|
|
8
8
|
>
|
|
9
9
|
> Package: @devalok/shilp-sutra
|
|
10
|
-
> Version: 0.
|
|
10
|
+
> Version: 0.40.0
|
|
11
11
|
>
|
|
12
12
|
> **If you are an AI agent reading this file top-to-bottom:** the Setup
|
|
13
13
|
> section below is authoritative. If any later per-component doc or a
|
|
@@ -3034,6 +3034,92 @@ const { size, stroke } = useIconContext()
|
|
|
3034
3034
|
|
|
3035
3035
|
### v0.1.0
|
|
3036
3036
|
- **Added** Initial release
|
|
3037
|
+
# OAuthButton
|
|
3038
|
+
|
|
3039
|
+
- Import: @devalok/shilp-sutra/ui/oauth-button
|
|
3040
|
+
- Server-safe: No
|
|
3041
|
+
- Category: ui
|
|
3042
|
+
|
|
3043
|
+
## Exports
|
|
3044
|
+
- `OAuthButton` — primary brand-aware sign-in button
|
|
3045
|
+
- `OAuthGroup` — stacked layout wrapper with consistent spacing
|
|
3046
|
+
- `OAuthDivider` — `or`-style horizontal rule between OAuth row and email form
|
|
3047
|
+
- `OAuthConnectionRow` — settings-page row for a linked provider (Disconnect / Connect action)
|
|
3048
|
+
|
|
3049
|
+
## OAuthButton props
|
|
3050
|
+
provider: "google" | "apple" | "github" | "microsoft" | "x" | "linkedin" | "facebook" | "discord" | "slack" | "gitlab" | "sso" | "email" | "passkey" (required)
|
|
3051
|
+
intent: "continue" | "signin" | "signup" (default "continue") — drives the verb in the label
|
|
3052
|
+
appearance: "brand" | "outline" | "dark" (default "brand") — visual treatment
|
|
3053
|
+
icon: ReactNode — override the default Tabler glyph with a brand-multicolour SVG
|
|
3054
|
+
iconOnly: boolean — compact icon-only button; provider name preserved in aria-label
|
|
3055
|
+
compact: boolean — short label ("Google" not "Continue with Google"); aria-label keeps long form
|
|
3056
|
+
lastUsed: boolean — inline right-edge pill inside the button (a stronger pattern is reorder, below)
|
|
3057
|
+
helperText: ReactNode — reassurance copy rendered below the button
|
|
3058
|
+
children: ReactNode — override the default label entirely (i18n / custom copy)
|
|
3059
|
+
size: inherited from Button ("xs" | "sm" | "md" | "lg" | compact + icon variants)
|
|
3060
|
+
fullWidth, loading, onClick, onClickAsync, asyncFeedbackDuration, disabled — inherited from Button
|
|
3061
|
+
|
|
3062
|
+
## Data attributes
|
|
3063
|
+
- `data-provider="<provider>"` — useful for analytics filtering
|
|
3064
|
+
- `data-oauth-appearance="<appearance>"`
|
|
3065
|
+
|
|
3066
|
+
## OAuthGroup props
|
|
3067
|
+
orientation: "vertical" | "horizontal" (default "vertical")
|
|
3068
|
+
gap: "ds-02" | "ds-03" | "ds-04" (default "ds-03")
|
|
3069
|
+
fullWidth: boolean (default true) — stretches children to fill width when vertical
|
|
3070
|
+
reorderLastUsedFirst: boolean (default false) — pull the child with lastUsed to position 0
|
|
3071
|
+
(Stripe-style — a stronger conversion lever than a visual badge alone)
|
|
3072
|
+
|
|
3073
|
+
## OAuthDivider props
|
|
3074
|
+
label: ReactNode (default "or")
|
|
3075
|
+
|
|
3076
|
+
## OAuthConnectionRow props
|
|
3077
|
+
provider: OAuthProvider (required)
|
|
3078
|
+
connected: boolean (required)
|
|
3079
|
+
accountLabel: ReactNode — account identifier shown next to the provider name (e.g. email)
|
|
3080
|
+
onAction: (e) => void — synchronous click handler
|
|
3081
|
+
onActionAsync: (e) => Promise<void> — uses Button's async state machine
|
|
3082
|
+
actionLabel: ReactNode — override the "Disconnect" / "Connect <name>" copy
|
|
3083
|
+
icon: ReactNode — override the default glyph
|
|
3084
|
+
disabled: boolean
|
|
3085
|
+
|
|
3086
|
+
## Defaults
|
|
3087
|
+
intent="continue", appearance="brand", iconOnly=false, lastUsed=false
|
|
3088
|
+
|
|
3089
|
+
## Example
|
|
3090
|
+
```jsx
|
|
3091
|
+
// Typical signup flow
|
|
3092
|
+
<OAuthGroup>
|
|
3093
|
+
<OAuthButton provider="google" lastUsed />
|
|
3094
|
+
<OAuthButton provider="apple" />
|
|
3095
|
+
<OAuthButton provider="github" />
|
|
3096
|
+
</OAuthGroup>
|
|
3097
|
+
<OAuthDivider />
|
|
3098
|
+
<OAuthGroup>
|
|
3099
|
+
<OAuthButton provider="passkey" appearance="outline" />
|
|
3100
|
+
<OAuthButton provider="email" appearance="outline" />
|
|
3101
|
+
</OAuthGroup>
|
|
3102
|
+
|
|
3103
|
+
// Async loading + success/error feedback
|
|
3104
|
+
<OAuthButton provider="google" fullWidth onClickAsync={signInWithGoogle} />
|
|
3105
|
+
|
|
3106
|
+
// True brand-multicolour glyph from the provider's brand page
|
|
3107
|
+
<OAuthButton provider="google" icon={<GoogleGSvg />} />
|
|
3108
|
+
|
|
3109
|
+
// Settings page — linked state
|
|
3110
|
+
<OAuthConnectionRow
|
|
3111
|
+
provider="google"
|
|
3112
|
+
connected
|
|
3113
|
+
accountLabel="namaskar@devalok.in"
|
|
3114
|
+
onAction={disconnectGoogle}
|
|
3115
|
+
/>
|
|
3116
|
+
```
|
|
3117
|
+
|
|
3118
|
+
## Composability
|
|
3119
|
+
- **Built on Button.** Async state machine, loading/processing, sizes, and `fullWidth` are inherited. `variant` and `color` are managed internally — pass `appearance` instead.
|
|
3120
|
+
- **Tabler peer dep.** Default glyphs come from `@tabler/icons-react`. To match a provider's official multicolour mark, pass `icon={<YourSvg />}`.
|
|
3121
|
+
- **Brand-colour backgrounds.** `appearance="brand"` uses each provider's published button colour. `appearance="outline"` falls back to DS-neutral. `appearance="dark"` unifies every provider into an Apple-style black-on-white (light) / white-on-black (dark) treatment — useful when you want a row to feel visually consistent across providers.
|
|
3122
|
+
- **Last-used hint.** Storage is the consumer's responsibility — pass `lastUsed={user.lastProvider === 'google'}`.
|
|
3037
3123
|
# Pagination
|
|
3038
3124
|
|
|
3039
3125
|
- Import: @devalok/shilp-sutra/ui/pagination
|
|
@@ -28,8 +28,34 @@ Other recipes:
|
|
|
28
28
|
- `server-components.md` — RSC-safety matrix and import patterns
|
|
29
29
|
- `troubleshoot.md` — decision tree for the 8 most common breakages
|
|
30
30
|
|
|
31
|
+
## The Themer (fast path for branding)
|
|
32
|
+
|
|
33
|
+
Before hand-writing CSS variables, point the user at **https://shilp-sutra.devalok.in/themer** — one funnel, four doors. Each door drops the user at a result page with install commands + a copy-pasteable CSS block (role tokens + 12-step OKLCH accent ramp) + a shareable URL.
|
|
34
|
+
|
|
35
|
+
| User context | URL |
|
|
36
|
+
|---|---|
|
|
37
|
+
| "Make it look like Linear / Stripe / Apple / Material / Notion / Vercel / Devalok" | `/themer/archetypes` |
|
|
38
|
+
| "Here's our brand color: `#…`" | `/themer/brand` |
|
|
39
|
+
| "Not sure" | `/themer/wizard` |
|
|
40
|
+
| "Show me a sample result" | `/themer/result?archetype=devalok` |
|
|
41
|
+
|
|
42
|
+
Paste the snippet *after* `@import "@devalok/shilp-sutra/css";` in the global stylesheet. No `tailwind.config.ts`, no theme provider, no JS bundle. Fall through to `customize-brand.md` only for tokens the Themer doesn't expose yet (font stack, spacing scale, focus ring).
|
|
43
|
+
|
|
31
44
|
The repo URL for these files is `https://github.com/devalok-design/shilp-sutra/tree/main/packages/core/docs/recipes`. Consumer projects should also have an `AGENTS.md` at their root with the rules above pre-loaded — read that first if it exists.
|
|
32
45
|
|
|
46
|
+
## NEW (v0.40.0)
|
|
47
|
+
|
|
48
|
+
- **OAuthButton.** Brand-aware social/login buttons. Subpath: `@devalok/shilp-sutra/ui/oauth-button`. 13 providers (`google` `apple` `github` `microsoft` `x` `linkedin` `facebook` `discord` `slack` `gitlab` `sso` `email` `passkey`). Props: `provider`, `intent` (`continue|signin|signup`), `appearance` (`brand|outline|dark`), `icon` (override default glyph), `iconOnly`, `compact` (renders just "Google" instead of "Continue with Google"; aria-label keeps long form), `lastUsed` (inline right-edge pill inside button), `helperText`. Inherits Button async/loading/sizes. Siblings: `OAuthGroup` (with `reorderLastUsedFirst` for Stripe-style ordering), `OAuthDivider`, `OAuthConnectionRow` (settings-page linked state). Default glyphs from Tabler peer dep; pass `icon` to drop in a brand's official multicolour SVG. In dark mode every brand appearance lands on the same DS surface — brand identity comes from the glyph, not the bg, so rows stay visually coherent.
|
|
49
|
+
- **Icon API unification.** Every icon-accepting prop (`startIcon`, `endIcon`, `icon`, `leftIcon`, `rightIcon`) across 22 components now takes one type: **`IconInput`**. Pass a rendered element (`<Icon icon={IconPlus} />` or `<IconPlus />`), a component ref (`IconPlus`), or any custom node — all four shapes work interchangeably. Type widening only; every call that compiled before still compiles. Helpers exported for your own wrappers: `import type { IconInput } from '@devalok/shilp-sutra/ui/lib/icon-input'` + `import { normalizeIcon } from '@devalok/shilp-sutra/ui/lib/normalize-icon'`. `IconProvider` now sizes icons via context — delete `className="h-4 w-4"` overrides.
|
|
50
|
+
- **Polymorphic `Text` / `Stack` / `Container`.** The `as` prop now widens accepted attributes to the rendered element: `<Text as="label" htmlFor="email">`, `<Text as="a" href="/x">`, `<Stack as="ul" role="list">`, `<Container as="main" aria-label>` all typecheck. Default element behavior unchanged.
|
|
51
|
+
- **Agent-friendly install experience.** `AGENTS.md` now ships in the tarball (`node_modules/@devalok/shilp-sutra/AGENTS.md`), discoverable by 25+ agent tools. `package.json` declares an `agents` field (npm-agentskills convention) so `pnpm dlx @codemcp/agentskills export` auto-installs the bundled skill. New postinstall welcome banner (silent in CI / non-TTY / `SHILP_SUTRA_NO_WELCOME=1`). `troubleshoot.md` gained peer-cliff symptom entries.
|
|
52
|
+
- **`llms-quick.txt`.** New ≤15K-token fast-path summary in the tarball — fits in one Read on any agent. Read order is now `llms-quick.txt` → `llms.txt` → `llms-full.txt`.
|
|
53
|
+
- **Companion package `@devalok/eslint-plugin-shilp-sutra`** (first release). 12 rules — deprecated-API catches, peer-cliff barrel-import detection, TW3→TW4 classname autofixes. `pnpm add -D @devalok/eslint-plugin-shilp-sutra`, then `shilpSutra.configs['flat/recommended']`. Three presets: `recommended`, `strict`, `migration` (one-shot codemod).
|
|
54
|
+
|
|
55
|
+
## BREAKING CHANGES (v0.40.0)
|
|
56
|
+
|
|
57
|
+
- **Barrel peer-cliff cleanup.** 12 symbols that statically import optional peers were removed from their parent barrels (`/ui`, `/composed`, `/ai`, `/ai/blocks`) — they now import ONLY via per-component subpath. Affected: `Toaster`/`toast` (→ `/ui/toaster`, `/ui/toast`), `InputOTP*` (→ `/ui/input-otp`), `DatePicker*` (→ `/composed/date-picker`), `EmojiPicker*` (→ `/composed/emoji-picker`), `FilePreview` (→ `/composed/file-preview`), `MarkdownViewer` (→ `/composed/markdown-viewer`), `RichTextEditor*`/`RichChatInput*` (→ their subpaths), `BlockRenderer`/`ErrorBlock`/`TextBlock` (→ `/ai/*`). Fixes `Module not found: Can't resolve 'sonner'`/etc. at consumer build time. Full before/after table in `MIGRATION.md → v0.40.0`. Per-chart subpaths (`/ui/charts/bar-chart`, etc.) added non-breaking alongside.
|
|
58
|
+
|
|
33
59
|
## NEW (v0.39.0)
|
|
34
60
|
|
|
35
61
|
- **Shape presets (`[data-shape]`).** Set on `<html>` (or any subtree) to re-skin roundness across the whole UI. Three ship by default: `sharp` (technical, 2/4/6 px), `slightly-rounded` (default, 6/10/16 px), `rounded` (consumer, 10/16/24 px). Pill shapes (Badge, Switch, Radio, Avatar circle) stay pill regardless.
|
|
@@ -443,6 +469,85 @@ import { useColorMode } from '@devalok/shilp-sutra/hooks/use-color-mode'
|
|
|
443
469
|
// CSS tokens (import once at app root — already included in /css):
|
|
444
470
|
import '@devalok/shilp-sutra/css'
|
|
445
471
|
|
|
472
|
+
## IMPORT PATH CHEATSHEET (don't guess — these subpaths are NOT always the kebab-case of the component name)
|
|
473
|
+
|
|
474
|
+
> **0.40.0 — barrel peer-cliff cleanup.** Components below marked `MANDATORY per-component` were removed from their parent barrel (`/ui`, `/composed`, `/ai`, `/ai/blocks`) because they statically import optional peers (`input-otp`, `sonner`, `date-fns`, `@emoji-mart/*`, `react-pdf`, `react-zoom-pan-pinch`, `react-markdown`, `remark-gfm`, `react-syntax-highlighter`, `@tiptap/*`). Fresh consumers using the barrel were getting `Module not found` at build time. The per-component subpath is now the ONLY way to import them. See MIGRATION.md → "v0.40.0 — barrel peer-cliff cleanup" for the full before/after.
|
|
475
|
+
|
|
476
|
+
Common confusions to memorize:
|
|
477
|
+
|
|
478
|
+
| Component / API | Exact import path |
|
|
479
|
+
|------------------------------------------------|----------------------------------------------------------------|
|
|
480
|
+
| `FormField`, `FormHelperText`, `useFormField` | `@devalok/shilp-sutra/ui/form` (NOT `ui/form-field`)|
|
|
481
|
+
| `Label` | `@devalok/shilp-sutra/ui/label` |
|
|
482
|
+
| `AppSidebar` | `@devalok/shilp-sutra/shell/sidebar` (NOT `shell/app-sidebar`)|
|
|
483
|
+
| `TopBar`, `TopBar.*` | `@devalok/shilp-sutra/shell/top-bar` |
|
|
484
|
+
| `BottomNavbar` | `@devalok/shilp-sutra/shell/bottom-navbar` |
|
|
485
|
+
| `AppCommandPalette` | `@devalok/shilp-sutra/shell/app-command-palette` |
|
|
486
|
+
| `CommandRegistryProvider`, `useCommandRegistry`| `@devalok/shilp-sutra/shell/command-registry` |
|
|
487
|
+
| `NotificationCenter` | `@devalok/shilp-sutra/shell/notification-center` |
|
|
488
|
+
| `NotificationPreferences` | `@devalok/shilp-sutra/shell/notification-preferences` |
|
|
489
|
+
| `LinkProvider`, `useLink` | `@devalok/shilp-sutra/shell/link-context` |
|
|
490
|
+
| `CommandPalette` (lower-level palette) | `@devalok/shilp-sutra/composed/command-palette` |
|
|
491
|
+
| `BarChart`, `LineChart`, `AreaChart`, `PieChart`, `RadarChart`, `GaugeChart`, `Sparkline`, `ChartContainer`, `Legend` | `@devalok/shilp-sutra/ui/charts` (full barrel, pulls all 9 d3-\* peers) — **prefer per-chart subpath when possible: `/ui/charts/bar-chart`, `/ui/charts/line-chart`, `/ui/charts/area-chart`, `/ui/charts/pie-chart`, `/ui/charts/radar-chart`, `/ui/charts/gauge-chart`, `/ui/charts/sparkline`, `/ui/charts/chart-container`** (each pulls only the d3-\* peers it needs — BarChart needs `d3-scale` + `d3-axis` + `d3-selection`; PieChart/RadarChart need only `d3-shape`) |
|
|
492
|
+
| `DataTable` | `@devalok/shilp-sutra/ui/data-table` |
|
|
493
|
+
| `DataTableToolbar` | `@devalok/shilp-sutra/ui/data-table-toolbar` |
|
|
494
|
+
| `DatePicker`, `DateRangePicker`, `DateTimePicker`, `TimePicker`, `CalendarGrid`, `YearPicker`, `MonthPicker`, `Presets`, `useCalendar` | `@devalok/shilp-sutra/composed/date-picker` **MANDATORY per-component (0.40.0+)** — pulls `date-fns` |
|
|
495
|
+
| `Toaster` | `@devalok/shilp-sutra/ui/toaster` **MANDATORY per-component (0.40.0+)** — pulls `sonner` |
|
|
496
|
+
| `toast` | `@devalok/shilp-sutra/ui/toast` **MANDATORY per-component (0.40.0+)** — pulls `sonner` |
|
|
497
|
+
| `InputOTP`, `InputOTPGroup`, `InputOTPSeparator`, `InputOTPSlot` | `@devalok/shilp-sutra/ui/input-otp` **MANDATORY per-component (0.40.0+)** — pulls `input-otp` |
|
|
498
|
+
| `EmojiPicker`, `EmojiPickerPopover`, `EmojiData`, `EmojiSet` | `@devalok/shilp-sutra/composed/emoji-picker` **MANDATORY per-component (0.40.0+)** — pulls `@emoji-mart/data` + `@emoji-mart/react` |
|
|
499
|
+
| `EmojiNode`, `EmojiNodeAttrs` | `@devalok/shilp-sutra/composed/extensions/emoji-node` **MANDATORY per-component (0.40.0+)** — pulls `@tiptap/*` |
|
|
500
|
+
| `createEmojiSuggestion` | `@devalok/shilp-sutra/composed/extensions/emoji-suggestion` **MANDATORY per-component (0.40.0+)** — pulls `@tiptap/*` |
|
|
501
|
+
| `FilePreview`, `FilePreviewProps` | `@devalok/shilp-sutra/composed/file-preview` **MANDATORY per-component (0.40.0+)** — pulls `react-pdf` + `react-zoom-pan-pinch` |
|
|
502
|
+
| `MarkdownViewer` | `@devalok/shilp-sutra/composed/markdown-viewer` **MANDATORY per-component (0.40.0+)** — pulls `react-markdown` + `react-syntax-highlighter` + `remark-gfm` |
|
|
503
|
+
| `RichChatInput`, `AudioPlayer`, `AudioWaveform`, `useVoiceRecorder` | `@devalok/shilp-sutra/composed/rich-chat-input` **MANDATORY per-component (0.40.0+)** — pulls `@tiptap/*` |
|
|
504
|
+
| `RichTextEditor`, `RichTextViewer`, `MentionItem`, `ToolbarItem` | `@devalok/shilp-sutra/composed/rich-text-editor` **MANDATORY per-component (0.40.0+)** — pulls `@tiptap/*` |
|
|
505
|
+
| `MessageList`, `Message`, `SystemMessage`, `MessageInput`, `DateSeparator`, `UnreadSeparator`, `TypingIndicator` | `@devalok/shilp-sutra/ui/chat` |
|
|
506
|
+
| `CommandBar` | `@devalok/shilp-sutra/ai/command-bar` (also re-exported from `/ai`) |
|
|
507
|
+
| `AIConversation` | `@devalok/shilp-sutra/ai/conversation` |
|
|
508
|
+
| `BlockRenderer` | `@devalok/shilp-sutra/ai/block-renderer` **MANDATORY per-component (0.40.0+)** — transitively pulls `react-markdown` + `remark-gfm` via ErrorBlock/TextBlock |
|
|
509
|
+
| `AICommandProvider` | `@devalok/shilp-sutra/ai/ai-command-provider` |
|
|
510
|
+
| `DevadootIcon` | `@devalok/shilp-sutra/ai` |
|
|
511
|
+
| `ErrorBlock` | `@devalok/shilp-sutra/ai/blocks/error` **MANDATORY per-component (0.40.0+)** — pulls `react-markdown` + `remark-gfm` |
|
|
512
|
+
| `TextBlock` | `@devalok/shilp-sutra/ai/blocks/text` **MANDATORY per-component (0.40.0+)** — pulls `react-markdown` + `remark-gfm` |
|
|
513
|
+
| `BlockTable`, `ConfirmBlock`, `DividerBlock`, `InfoBlock`, `LoadingBlock`, `StatRowBlock`, `SuccessBlock` | `@devalok/shilp-sutra/ai/blocks` (barrel — these 7 are peer-cliff-free) |
|
|
514
|
+
| `useColorMode` | `@devalok/shilp-sutra/hooks/use-color-mode` |
|
|
515
|
+
| `useMobile` | `@devalok/shilp-sutra/hooks/use-mobile` |
|
|
516
|
+
| `MotionProvider`, `springs`, `tweens`, `stagger`, `useMotion` | `@devalok/shilp-sutra/motion` |
|
|
517
|
+
| `MotionFade`, `MotionScale`, `MotionPop`, `MotionSlide`, `MotionCollapse`, `MotionStagger`, `MotionStaggerItem` | `@devalok/shilp-sutra/motion/primitives` |
|
|
518
|
+
|
|
519
|
+
Components named directly after their file (`Button` → `ui/button`, `Card` → `ui/card`, `Avatar` → `ui/avatar`, `Stack` → `ui/stack`, `Text` → `ui/text`, etc.) follow the kebab-case-of-name rule. The table above is for the ones that DON'T.
|
|
520
|
+
|
|
521
|
+
**When in doubt:** `cat node_modules/@devalok/shilp-sutra/package.json | jq '.exports | keys'` lists every available subpath in the installed version.
|
|
522
|
+
|
|
523
|
+
## ICON API — one shape across every component (v0.40.0+)
|
|
524
|
+
|
|
525
|
+
Every icon-accepting prop in the design system (`startIcon`, `endIcon`, `icon`, etc. — see list below) takes the **`IconInput`** type. Pass any of these four shapes interchangeably:
|
|
526
|
+
|
|
527
|
+
```tsx
|
|
528
|
+
import { IconPlus } from '@tabler/icons-react'
|
|
529
|
+
import { Icon } from '@devalok/shilp-sutra/ui/icon'
|
|
530
|
+
|
|
531
|
+
<Button startIcon={<Icon icon={IconPlus} />}>Add</Button> // canonical
|
|
532
|
+
<Button startIcon={<IconPlus />}>Add</Button> // raw Tabler element
|
|
533
|
+
<Button startIcon={IconPlus}>Add</Button> // component ref
|
|
534
|
+
<Button startIcon={<span>+</span>}>Add</Button> // custom node
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
All four work identically at the call site. The component wraps its icon slot in `<IconProvider size={...}>` so size + stroke flow via React context — no `className="h-4 w-4"` overrides needed.
|
|
538
|
+
|
|
539
|
+
**Components on the unified API:** Button, IconButton, Badge, Combobox, SegmentedControl, Stepper, StatCard, TreeItem (TreeNode.icon), OAuthButton (icon + linkedIcon), Chat.Message.Avatar, Chat.Message.Action, Chat.SystemMessage, AIConversation (agent.icon), AICommandProvider (agent.icon), CommandBar (item.icon), EmptyState (kills the dual ReactNode|ComponentType signature), BulkActionBar (action.icon), ActivityFeed (item.icon), CommandPalette (item.icon), TopBar (UserMenuItem.icon, TopBar.IconButton.icon), Sidebar (NavItem.icon, NavSubItem.icon, footer.promo.icon), BottomNavbar (item.icon), AppCommandPalette (SearchResult.icon), CommandRegistry (CommandPageItem.icon).
|
|
540
|
+
|
|
541
|
+
**Internals** (`<Toaster>`, `<Toast>`'s success/error icons) use Sonner's own type contract and don't accept consumer-passed icons — that's by design.
|
|
542
|
+
|
|
543
|
+
**When to use which shape:**
|
|
544
|
+
- `<Icon icon={IconX} />` when you want explicit size/stroke control (size flows from context if not set)
|
|
545
|
+
- `<IconX />` when you trust the surrounding `IconProvider` and don't need stroke control
|
|
546
|
+
- `IconX` (raw ref) when you want the helper to do the wrapping for you (auto-wraps to `<Icon icon={IconX} />`)
|
|
547
|
+
- Custom node when the "icon" is actually `<span>$</span>` or an emoji
|
|
548
|
+
|
|
549
|
+
**Migration:** zero consumer changes needed if you were already passing valid React content. Components that previously took strict `IconProps['icon']` (BulkActionBar, Message.Action) or `ComponentType<{className}>` (SegmentedControl) now also accept the other three shapes. Strict-to-loose type widening — no breaking calls.
|
|
550
|
+
|
|
446
551
|
## CRITICAL: Differences from shadcn/ui
|
|
447
552
|
|
|
448
553
|
If you have shadcn/ui knowledge, these are the differences that WILL trip you up:
|
|
@@ -480,7 +585,7 @@ Components with two-axis system: Button, Badge, Alert, Banner, Progress, StatusB
|
|
|
480
585
|
|
|
481
586
|
### Inputs & Controls
|
|
482
587
|
- Button: variant(solid|soft|outline|ghost|link) color(accent|error|success|warning|neutral) size(xs|sm|md|lg|compact-xs|compact-sm|compact-md|icon-xs|icon-sm|icon-md|icon-lg) shape(default|pill) weight(semibold|normal) + loading, startIcon, endIcon, asChild, processing?('ambient'|'working'|'urgent'|boolean — marching ants SVG border, forces soft variant), processingColor?('accent'|'error'|'success'|'warning'|'neutral'), processingDisabled?(boolean, default true — set false for cancel-by-click). onClickAsync auto-activates processing='working' during loading phase. Layout animation always on. Deprecated aliases still work: variant="default"→solid, variant="destructive"→solid+error, color="default"→accent
|
|
483
|
-
- IconButton: icon(ReactNode, required) shape(square|circle) size(sm|md|lg) + aria-label required
|
|
588
|
+
- IconButton: icon(ReactNode, required as PROP — NOT children) shape(square|circle) size(sm|md|lg) + aria-label required. **Children rejected by type** (`Omit<ButtonProps, 'children'>`); pass the icon via `icon=` prop. Correct: `<IconButton icon={<Icon icon={IconArrowRight} />} aria-label="Submit" />`. Wrong: `<IconButton><Icon icon={IconArrowRight} /></IconButton>` (TS error). Wrap with `<Icon icon={…} />` (not raw Tabler `<IconX />`) so the size context cascades.
|
|
484
589
|
- SplitButton: [Action | ▼] button with dropdown. Props: variant(solid|soft|outline), color, size(xs|sm|md|icon-xs|icon-sm|icon-md), triggerSide(left|right, default right), triggerWidth?(number|string), placement?(Floating UI Placement, default top-end), dropdownContent(ReactNode), open?, onOpenChange?, dropdownLabel?, dropdownIcon?. ARIA: role="group", aria-haspopup="menu", aria-expanded.
|
|
485
590
|
- ButtonGroup: Visually merges adjacent Buttons. Props: variant, color, size, disabled (propagates), orientation(horizontal|vertical), attached(true|false, default true), fullWidth. Compound pattern: Button reads position from context, applies radius + border-removal inline. Tonal dividers for solid/soft/ghost. Focus z-index isolation.
|
|
486
591
|
- Icon: `<Icon icon={IconPlus} />` — context-aware wrapper for Tabler icons. Size tiers: xs(14px) sm(16px) md(18px) lg(20px) xl(24px) 2xl(32px). Default: md. Stroke: light(1.5) regular(2) bold(2.5). Default: regular. Scales per size tier. Reads size from parent Button/IconGroup via IconContext. Explicit props override. Accessibility: aria-hidden by default. Pass label="Add item" for accessible icons. Animation: animate="spin|pulse|bounce|draw". `draw` renders SVG path-draw animation (check/X icons draw progressively via pathLength; other icons fall back to static). State machine: state="idle|loading|success|error". Button integration: startIcon={<Icon icon={IconPlus} />} (NOT raw <IconPlus />). IconGroup: <IconGroup size="sm" gap="tight"> for toolbar patterns.
|
|
@@ -638,7 +743,7 @@ Import: `@devalok/shilp-sutra/ui/chat`
|
|
|
638
743
|
- Old Fade/Collapse/Grow/Slide from @devalok/shilp-sutra/ui/transitions are REMOVED — use Motion* equivalents
|
|
639
744
|
|
|
640
745
|
### Hooks
|
|
641
|
-
- toast: imperative API — import { toast } from '@devalok/shilp-sutra/ui/toast'. Methods: toast.success/error/warning/info/loading/message/undo/promise/upload/custom/dismiss. useToast() is deprecated.
|
|
746
|
+
- toast: imperative API — import { toast } from '@devalok/shilp-sutra/ui/toast'. **Signature is `(message: string, options?: { description?, duration?, action?, … })`** (sonner-style positional, NOT object-first). Examples: `toast.success('Saved')`, `toast.error('Failed to fetch', { description: 'Check your network', duration: 7000 })`, `toast.promise(fn, { loading: '…', success: '…', error: '…' })`, `toast.upload(file, { onProgress, onComplete })`. Methods: toast.success/error/warning/info/loading/message/undo/promise/upload/custom/dismiss. useToast() is deprecated. Mount `<Toaster />` at layout root or `toast()` calls are no-ops + log a dev warning.
|
|
642
747
|
- useColorMode(): returns { colorMode, setColorMode, toggleColorMode }
|
|
643
748
|
- useMobile(): returns boolean (true if viewport < 768px)
|
|
644
749
|
- useLink(): returns router-agnostic Link component from LinkProvider context (shell/link-context)
|
|
@@ -4,6 +4,21 @@
|
|
|
4
4
|
|
|
5
5
|
Override colors, radius, fonts, and spacing without forking the package. All customization happens through CSS custom properties — no JS configuration.
|
|
6
6
|
|
|
7
|
+
## The fast path: use the Themer
|
|
8
|
+
|
|
9
|
+
Before hand-writing variables, try **[shilp-sutra.devalok.in/themer](https://shilp-sutra.devalok.in/themer)**. It is one funnel with four entry doors:
|
|
10
|
+
|
|
11
|
+
- **Pick an archetype** — Linear, Stripe, Apple, Material, Notion, Vercel, or Devalok. Click → result page.
|
|
12
|
+
- **Use my brand color** — paste a hex or dial OKLCH. Auto-generates the 12-step ramp and suggests an archetype.
|
|
13
|
+
- **Walk me through it** — five-question wizard composes the answers into a theme.
|
|
14
|
+
- **Just exploring** — land on a sample result page to see what you ship away with.
|
|
15
|
+
|
|
16
|
+
Every door drops you at the same result screen: a copy-pasteable CSS block (role tokens + 12-step OKLCH accent ramp), install commands for your package manager, and a share URL that encodes the theme.
|
|
17
|
+
|
|
18
|
+
Paste the snippet into your global stylesheet *after* the `@import "@devalok/shilp-sutra/css";` line. That's the whole flow — no `tailwind.config.ts`, no theme provider, no JS bundle.
|
|
19
|
+
|
|
20
|
+
The rest of this doc covers what to do if the Themer doesn't expose a token you need to override (font stack, spacing scale, focus ring) — fall through to the hand-written cases below.
|
|
21
|
+
|
|
7
22
|
## How tokens layer
|
|
8
23
|
|
|
9
24
|
Shilp Sutra's tokens are organized in three tiers:
|
|
@@ -31,6 +31,21 @@ Add only if rendering `<Toaster />`:
|
|
|
31
31
|
pnpm add sonner
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
### 2a. Optional peer dependencies (install ONLY when importing the matching subpath)
|
|
35
|
+
|
|
36
|
+
Some components ship hard peers as optional. **Install BEFORE first import** or Astro's Vite build will fail with `Failed to resolve import`. Skip if you only use core components.
|
|
37
|
+
|
|
38
|
+
| When you import… | Install |
|
|
39
|
+
|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
|
|
40
|
+
| `@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` |
|
|
41
|
+
| `@devalok/shilp-sutra/ui/data-table` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
|
|
42
|
+
| `@devalok/shilp-sutra/composed/date-picker` (+ DateRange, DateTime, Calendar) | `pnpm add date-fns` |
|
|
43
|
+
| `@devalok/shilp-sutra/composed/rich-text-editor` (+ RichChatInput, RichTextViewer) | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
44
|
+
| `@devalok/shilp-sutra/ui/input-otp` | `pnpm add input-otp` |
|
|
45
|
+
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
46
|
+
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter` |
|
|
47
|
+
| Any `Icon` / `IconButton` with Tabler icons | `pnpm add @tabler/icons-react` |
|
|
48
|
+
|
|
34
49
|
## 3. Wire Tailwind 4 in `astro.config`
|
|
35
50
|
|
|
36
51
|
Astro has its own `@astrojs/tailwind` integration, but for Tailwind 4 use the Vite plugin directly (Astro 4.5+ supports this):
|
|
@@ -10,10 +10,9 @@ You are in this recipe if **all** of these are true:
|
|
|
10
10
|
|
|
11
11
|
- `package.json` lists `"next"` at version `^13.0.0` or higher
|
|
12
12
|
- An `app/` directory exists at the project root or under `src/`
|
|
13
|
-
- An `app/layout.tsx
|
|
14
|
-
- No `pages/` directory at the project root, OR `pages/` exists but only contains `_app.{js,tsx}` and `_document.{js,tsx}` (legacy artifacts)
|
|
13
|
+
- An `app/layout.{tsx,jsx}` file exists
|
|
15
14
|
|
|
16
|
-
If `pages/`
|
|
15
|
+
If a `pages/` directory exists at the project root AND contains route files (not just `_app`/`_document` legacy artifacts from older `create-next-app` versions), use [install-next-pages.md](./install-next-pages.md). `create-next-app@16+` no longer scaffolds `pages/` for App Router projects.
|
|
17
16
|
|
|
18
17
|
## 2. Install dependencies
|
|
19
18
|
|
|
@@ -49,6 +48,23 @@ Add brand assets package if you need Devalok or Karm logos:
|
|
|
49
48
|
pnpm add @devalok/shilp-sutra-brand
|
|
50
49
|
```
|
|
51
50
|
|
|
51
|
+
### 2a. Optional peer dependencies (install ONLY when importing the matching subpath)
|
|
52
|
+
|
|
53
|
+
Some components depend on third-party libraries that ship as optional peers. **Install BEFORE first import** of the matching component, or `next build` will exit with `Module not found`. Skip entirely if you only use core components (`Button`, `Text`, `Stack`, `Dialog`, `Toast`, `Form*`, `Input`, `Card`, etc.).
|
|
54
|
+
|
|
55
|
+
| When you import… | Install |
|
|
56
|
+
|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
|
|
57
|
+
| `@devalok/shilp-sutra/ui/charts/*` (BarChart, LineChart, …)| `pnpm add d3-array d3-axis d3-format d3-interpolate d3-scale d3-selection d3-shape d3-time-format d3-transition` |
|
|
58
|
+
| `@devalok/shilp-sutra/ui/data-table` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
|
|
59
|
+
| `@devalok/shilp-sutra/composed/date-picker` (+ DateRange, DateTime, Calendar) | `pnpm add date-fns` |
|
|
60
|
+
| `@devalok/shilp-sutra/composed/rich-text-editor` (+ RichChatInput, RichTextViewer) | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
61
|
+
| `@devalok/shilp-sutra/ui/input-otp` | `pnpm add input-otp` |
|
|
62
|
+
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
63
|
+
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter` |
|
|
64
|
+
| Any `Icon` / `IconButton` use with Tabler icons | `pnpm add @tabler/icons-react` |
|
|
65
|
+
|
|
66
|
+
> These aren't in core deps so consumers who never render a chart, OTP input, or rich-text editor don't pay the install / bundle cost. One-time decision at install.
|
|
67
|
+
|
|
52
68
|
## 3. Configure PostCSS
|
|
53
69
|
|
|
54
70
|
Create or update `postcss.config.mjs` at the project root:
|
|
@@ -213,8 +229,8 @@ If anything is off, see [troubleshoot.md](./troubleshoot.md).
|
|
|
213
229
|
}
|
|
214
230
|
```
|
|
215
231
|
For npm/yarn/bun equivalents, see [troubleshoot.md](./troubleshoot.md).
|
|
216
|
-
- **
|
|
217
|
-
- **`p-3` vs `p-ds-03
|
|
232
|
+
- **Per-component imports keep RSC fast AND avoid peer-dep cliffs.** Inside Server Components, prefer `@devalok/shilp-sutra/ui/text`, `…/composed/page-header`, etc. The barrel `@devalok/shilp-sutra/ui` re-exports many client components — including some with hard peer-dep imports (e.g. `input-otp`) — so it both inflates the client bundle and forces those peers to be installed even when you never render those components. See [server-components.md](./server-components.md) for the full RSC-safety matrix.
|
|
233
|
+
- **`p-3` vs `p-ds-03` — both are valid.** DS spacing uses the `--spacing-ds-*` namespace (`p-ds-04`, `gap-ds-03`); Tailwind 4's default numeric scale (`p-4`, `gap-2`) coexists by design. Pick `p-ds-*` for values that should track DS theme changes (card padding, form gaps); pick `p-N` for one-off layout values (section breathing room). Do NOT mass-codemod `p-4` → `p-ds-04` — that is not what the package intends.
|
|
218
234
|
- **Bare `shadow` is dead.** Tailwind 4 has no `--shadow-DEFAULT`. Use `shadow-raised`, `shadow-overlay`, or `shadow-floating`.
|
|
219
235
|
|
|
220
236
|
## 9. What you should NOT do
|
|
@@ -18,6 +18,8 @@ If both `app/` and `pages/` exist, prefer [install-next-app-router.md](./install
|
|
|
18
18
|
|
|
19
19
|
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).
|
|
20
20
|
|
|
21
|
+
**Optional peer dependencies** — if you'll render `<DataTable>`, any chart, `<DatePicker>`, `<RichTextEditor>`, `<InputOTP>`, `<FilePreview>`, `<MarkdownViewer>`, or use Tabler icons, install the matching peers BEFORE first import. Full table at [install-next-app-router.md § 2a](./install-next-app-router.md#2a-optional-peer-dependencies-install-only-when-importing-the-matching-subpath) — identical for Pages Router.
|
|
22
|
+
|
|
21
23
|
## 3. PostCSS
|
|
22
24
|
|
|
23
25
|
Same as App Router — see [§ 3](./install-next-app-router.md#3-configure-postcss).
|
|
@@ -27,6 +27,21 @@ Optional:
|
|
|
27
27
|
pnpm add sonner # only if rendering <Toaster />
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
### 2a. Optional peer dependencies (install ONLY when importing the matching subpath)
|
|
31
|
+
|
|
32
|
+
Some components ship hard peers as optional. **Install BEFORE first import** or Remix's Vite build will fail with `Failed to resolve import`. Skip if you only use core components.
|
|
33
|
+
|
|
34
|
+
| When you import… | Install |
|
|
35
|
+
|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
|
|
36
|
+
| `@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` |
|
|
37
|
+
| `@devalok/shilp-sutra/ui/data-table` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
|
|
38
|
+
| `@devalok/shilp-sutra/composed/date-picker` (+ DateRange, DateTime, Calendar) | `pnpm add date-fns` |
|
|
39
|
+
| `@devalok/shilp-sutra/composed/rich-text-editor` (+ RichChatInput, RichTextViewer) | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
40
|
+
| `@devalok/shilp-sutra/ui/input-otp` | `pnpm add input-otp` |
|
|
41
|
+
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
42
|
+
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter` |
|
|
43
|
+
| Any `Icon` / `IconButton` with Tabler icons | `pnpm add @tabler/icons-react` |
|
|
44
|
+
|
|
30
45
|
## 3. Wire Tailwind 4 in `vite.config.ts`
|
|
31
46
|
|
|
32
47
|
```ts
|
|
@@ -25,6 +25,21 @@ Optional:
|
|
|
25
25
|
pnpm add sonner # only if rendering <Toaster />
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
### 2a. Optional peer dependencies (install ONLY when importing the matching subpath)
|
|
29
|
+
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
| When you import… | Install |
|
|
33
|
+
|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
|
|
34
|
+
| `@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` |
|
|
35
|
+
| `@devalok/shilp-sutra/ui/data-table` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
|
|
36
|
+
| `@devalok/shilp-sutra/composed/date-picker` (+ DateRange, DateTime, Calendar) | `pnpm add date-fns` |
|
|
37
|
+
| `@devalok/shilp-sutra/composed/rich-text-editor` (+ RichChatInput, RichTextViewer) | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
38
|
+
| `@devalok/shilp-sutra/ui/input-otp` | `pnpm add input-otp` |
|
|
39
|
+
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
40
|
+
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter` |
|
|
41
|
+
| Any `Icon` / `IconButton` with Tabler icons | `pnpm add @tabler/icons-react` |
|
|
42
|
+
|
|
28
43
|
## 3. Wire Tailwind 4 in `app.config.ts`
|
|
29
44
|
|
|
30
45
|
```ts
|
|
@@ -42,6 +42,21 @@ Add only if rendering `<Toaster />`:
|
|
|
42
42
|
pnpm add sonner
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
### 2a. Optional peer dependencies (install ONLY when importing the matching subpath)
|
|
46
|
+
|
|
47
|
+
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.
|
|
48
|
+
|
|
49
|
+
| When you import… | Install |
|
|
50
|
+
|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
|
|
51
|
+
| `@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` |
|
|
52
|
+
| `@devalok/shilp-sutra/ui/data-table` | `pnpm add @tanstack/react-table @tanstack/react-virtual` |
|
|
53
|
+
| `@devalok/shilp-sutra/composed/date-picker` (+ DateRange, DateTime, Calendar) | `pnpm add date-fns` |
|
|
54
|
+
| `@devalok/shilp-sutra/composed/rich-text-editor` (+ RichChatInput, RichTextViewer) | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
55
|
+
| `@devalok/shilp-sutra/ui/input-otp` | `pnpm add input-otp` |
|
|
56
|
+
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
57
|
+
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter` |
|
|
58
|
+
| Any `Icon` / `IconButton` with Tabler icons | `pnpm add @tabler/icons-react` |
|
|
59
|
+
|
|
45
60
|
## 3. Wire Tailwind 4 in `vite.config.ts`
|
|
46
61
|
|
|
47
62
|
Use the official Tailwind 4 Vite plugin (faster than PostCSS for Vite):
|
|
@@ -99,6 +99,28 @@ transpilePackages: ["@devalok/shilp-sutra", "@devalok/shilp-sutra-brand"],
|
|
|
99
99
|
|
|
100
100
|
If `@devalok/shilp-sutra-brand` is not installed, list only `@devalok/shilp-sutra`.
|
|
101
101
|
|
|
102
|
+
## Symptom: Build error `Cannot find module 'sonner' / 'input-otp' / 'date-fns' / '@tiptap/react' / 'react-pdf' / 'react-markdown' / '@emoji-mart/react'`
|
|
103
|
+
|
|
104
|
+
**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):
|
|
105
|
+
|
|
106
|
+
| You imported (per-component subpath) | Install |
|
|
107
|
+
|--------------------------------------|-----------------------------------------------------------------------------------------------|
|
|
108
|
+
| `…/ui/toaster` or `…/ui/toast` | `pnpm add sonner` |
|
|
109
|
+
| `…/ui/input-otp` | `pnpm add input-otp` |
|
|
110
|
+
| `…/composed/date-picker` | `pnpm add date-fns` |
|
|
111
|
+
| `…/composed/emoji-picker` | `pnpm add @emoji-mart/data @emoji-mart/react` |
|
|
112
|
+
| `…/composed/extensions/emoji-node` or `…/extensions/emoji-suggestion` | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
113
|
+
| `…/composed/rich-text-editor` | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
114
|
+
| `…/composed/rich-chat-input` | `pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder` |
|
|
115
|
+
| `…/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
116
|
+
| `…/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter remark-gfm` |
|
|
117
|
+
| `…/ai/block-renderer`, `…/ai/blocks/text`, `…/ai/blocks/error` | `pnpm add react-markdown remark-gfm` |
|
|
118
|
+
| Any `…/ui/charts/*` | `pnpm add d3-array d3-axis d3-format d3-interpolate d3-scale d3-selection d3-shape d3-time-format d3-transition` |
|
|
119
|
+
|
|
120
|
+
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.
|
|
121
|
+
|
|
122
|
+
For the full table in your framework's install recipe, see `install-<framework>.md → §2a. Optional peer dependencies`.
|
|
123
|
+
|
|
102
124
|
## Symptom: Hydration warning on every page load (Next.js)
|
|
103
125
|
|
|
104
126
|
**Diagnosis:** `next-themes` writes the `class` attribute on `<html>` before React hydrates, causing a server/client class mismatch.
|