canvas-ui-sdk 0.3.23 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -5
- package/dist/charts.js +11 -6
- package/dist/charts.js.map +1 -1
- package/dist/index.d.ts +1233 -153
- package/dist/index.js +3562 -447
- package/dist/index.js.map +1 -1
- package/mcp/dist/index.js +1195 -149
- package/package.json +1 -1
- package/prompts/.cursorrules +96 -0
- package/prompts/.windsurfrules +96 -0
- package/prompts/CLAUDE.md +22 -0
- package/prompts/copilot-instructions.md +96 -0
- package/registry/blocks/activity-feed.json +12 -1
- package/registry/blocks/blog-cards.json +10 -2
- package/registry/blocks/bottom-action-bar.json +27 -0
- package/registry/blocks/bottom-input-chat-widget.json +9 -1
- package/registry/blocks/category-grid.json +10 -2
- package/registry/blocks/centered-hero.json +9 -1
- package/registry/blocks/chat-message.json +8 -1
- package/registry/blocks/circular-progress-bar-list.json +11 -1
- package/registry/blocks/confirmation-popup.json +10 -1
- package/registry/blocks/contact-form-popup.json +10 -1
- package/registry/blocks/content-dropzone.json +8 -0
- package/registry/blocks/content-with-image.json +9 -1
- package/registry/blocks/core-values-grid.json +10 -2
- package/registry/blocks/credit-card-display.json +9 -1
- package/registry/blocks/cta-banner.json +10 -2
- package/registry/blocks/destination-cards.json +10 -1
- package/registry/blocks/detail-drawer.json +10 -1
- package/registry/blocks/details-popup.json +10 -1
- package/registry/blocks/editable-list.json +29 -0
- package/registry/blocks/empty-state.json +10 -2
- package/registry/blocks/faq-accordion.json +9 -1
- package/registry/blocks/faqs-table.json +10 -1
- package/registry/blocks/feature-with-image.json +9 -1
- package/registry/blocks/featured-news-cards.json +10 -2
- package/registry/blocks/featured-places.json +10 -2
- package/registry/blocks/features-comparison.json +9 -1
- package/registry/blocks/feedback-popup.json +9 -1
- package/registry/blocks/filter-popover.json +8 -1
- package/registry/blocks/fixed-column-data-table.json +11 -1
- package/registry/blocks/flair-banner.json +9 -1
- package/registry/blocks/footer-navbar.json +9 -1
- package/registry/blocks/form-group.json +14 -3
- package/registry/blocks/form-popup.json +31 -0
- package/registry/blocks/gallery-section.json +10 -2
- package/registry/blocks/gradient-banner.json +10 -2
- package/registry/blocks/graph-metric-tiles.json +1 -1
- package/registry/blocks/grid-tiles-list.json +10 -1
- package/registry/blocks/hero-dark-centered.json +9 -1
- package/registry/blocks/hero-dark-with-image.json +9 -1
- package/registry/blocks/hero-fullwidth-image.json +9 -1
- package/registry/blocks/hero-section.json +9 -1
- package/registry/blocks/how-it-works.json +9 -1
- package/registry/blocks/image-feed-with-nested-comments.json +10 -1
- package/registry/blocks/image-popup.json +10 -1
- package/registry/blocks/invoice-popup.json +10 -1
- package/registry/blocks/large-image-labels-list.json +10 -1
- package/registry/blocks/list-popup.json +28 -0
- package/registry/blocks/loader.json +9 -1
- package/registry/blocks/login-branding-panel.json +10 -2
- package/registry/blocks/menu-section.json +9 -1
- package/registry/blocks/menufocus-template.json +9 -1
- package/registry/blocks/messenger-sidebar.json +11 -2
- package/registry/blocks/metrics-section.json +10 -2
- package/registry/blocks/mobile-bottom-nav.json +10 -2
- package/registry/blocks/monthly-calendar-widget.json +9 -1
- package/registry/blocks/multistep-form-popup.json +34 -0
- package/registry/blocks/nested-comments-table.json +9 -1
- package/registry/blocks/nested-data-table.json +10 -1
- package/registry/blocks/nps-survey-popup.json +27 -0
- package/registry/blocks/office-locations.json +10 -2
- package/registry/blocks/order-summary-sidebar.json +27 -0
- package/registry/blocks/page-header-section.json +9 -1
- package/registry/blocks/pagination.json +8 -1
- package/registry/blocks/participant-list.json +9 -1
- package/registry/blocks/persona-card.json +10 -1
- package/registry/blocks/personalize-feed-popup.json +27 -0
- package/registry/blocks/pill-tabs.json +9 -1
- package/registry/blocks/place-detail-panel.json +11 -1
- package/registry/blocks/pricing-cards.json +10 -2
- package/registry/blocks/pricing-cta.json +9 -1
- package/registry/blocks/pricing-plans-popup.json +10 -1
- package/registry/blocks/profile-card.json +12 -2
- package/registry/blocks/profile-grid-tiles-list.json +10 -1
- package/registry/blocks/profile-image-uploader.json +9 -1
- package/registry/blocks/profile-info-cards.json +10 -1
- package/registry/blocks/progress-bar.json +8 -1
- package/registry/blocks/prompt-template.json +1 -1
- package/registry/blocks/purchase-confirmation-popup.json +10 -1
- package/registry/blocks/reservation-card.json +26 -0
- package/registry/blocks/reviews-grid.json +10 -2
- package/registry/blocks/reviews-table.json +10 -1
- package/registry/blocks/screen-prompt-template.json +1 -1
- package/registry/blocks/search-bar.json +9 -2
- package/registry/blocks/search-sidebar.json +9 -2
- package/registry/blocks/settings-list-row.json +9 -1
- package/registry/blocks/share-project-popup.json +36 -0
- package/registry/blocks/sidebar-cards.json +10 -2
- package/registry/blocks/sidebar-profile-card.json +10 -2
- package/registry/blocks/slideshow-grid-tiles.json +10 -2
- package/registry/blocks/slideshow-popup.json +10 -1
- package/registry/blocks/small-edit-popup.json +29 -0
- package/registry/blocks/social-feed.json +10 -1
- package/registry/blocks/social-proof.json +9 -1
- package/registry/blocks/standard-data-table.json +13 -1
- package/registry/blocks/standard-list-with-image.json +10 -1
- package/registry/blocks/step-tracker.json +9 -1
- package/registry/blocks/store-location-map.json +9 -1
- package/registry/blocks/team-cards-grid.json +9 -1
- package/registry/blocks/team-circular-grid.json +9 -1
- package/registry/blocks/terms-of-service-popup.json +10 -1
- package/registry/blocks/testimonial-carousel.json +10 -2
- package/registry/blocks/tile-image-gallery.json +26 -0
- package/registry/blocks/title-group.json +10 -1
- package/registry/blocks/upvoting-posts-table.json +10 -1
- package/registry/blocks/vertical-how-it-works.json +9 -1
- package/registry/blocks/vertical-step-tracker.json +9 -1
- package/registry/blocks/video-chat-controls.json +9 -1
- package/registry/blocks/video-content-section.json +9 -1
- package/registry/blocks/video-playlist.json +9 -1
- package/registry/blocks/video-popup.json +9 -1
- package/registry/blocks/view-profile-popup.json +10 -1
- package/registry/blocks/webcam-preview.json +9 -1
- package/registry/hooks/use-css-variable-sync.json +10 -1
- package/registry/hooks/use-mobile.json +9 -1
- package/registry/index.json +1526 -147
- package/registry/layout/account-settings-shell.json +10 -1
- package/registry/layout/dashboard-shell.json +12 -1
- package/registry/layout/double-sidebar-shell.json +11 -2
- package/registry/layout/double-sidebar.json +9 -1
- package/registry/layout/header.json +10 -1
- package/registry/layout/icon-sidebar-shell.json +9 -1
- package/registry/layout/icon-sidebar.json +9 -1
- package/registry/layout/mobile-menu-shell.json +10 -1
- package/registry/layout/multistep-progressbar-shell.json +9 -1
- package/registry/layout/multistep-shell.json +11 -1
- package/registry/layout/multistep-sidebar-shell.json +10 -2
- package/registry/layout/project-context-shell.json +1 -1
- package/registry/layout/search-bar-shell.json +8 -1
- package/registry/layout/sidebar-nav.json +7 -1
- package/registry/layout/sidebar.json +9 -2
- package/registry/layout/standard-page-shell.json +10 -1
- package/registry/layout/vertical-multistep-shell.json +10 -1
- package/registry/ui/avatar.json +9 -1
- package/registry/ui/button.json +9 -1
- package/registry/ui/calendar.json +9 -1
- package/registry/ui/checkbox.json +8 -1
- package/registry/ui/date-input.json +9 -1
- package/registry/ui/dialog.json +8 -1
- package/registry/ui/dropdown-menu.json +8 -1
- package/registry/ui/file-uploader.json +9 -1
- package/registry/ui/image-uploader.json +9 -1
- package/registry/ui/input.json +8 -1
- package/registry/ui/label.json +8 -1
- package/registry/ui/line-tabs.json +9 -1
- package/registry/ui/multiselect-checkbox-field.json +9 -1
- package/registry/ui/multiselect-tags.json +9 -1
- package/registry/ui/popover.json +8 -1
- package/registry/ui/radio-group.json +9 -1
- package/registry/ui/range-input.json +8 -1
- package/registry/ui/scroll-area.json +8 -1
- package/registry/ui/searchbox.json +9 -1
- package/registry/ui/select.json +9 -1
- package/registry/ui/selectable-pills.json +11 -1
- package/registry/ui/separator.json +8 -1
- package/registry/ui/sheet.json +9 -1
- package/registry/ui/sidebar.json +8 -1
- package/registry/ui/skeleton.json +8 -1
- package/registry/ui/slider.json +10 -2
- package/registry/ui/switch.json +9 -1
- package/registry/ui/tabs.json +8 -1
- package/registry/ui/text-input.json +8 -1
- package/registry/ui/textarea.json +9 -1
- package/registry/ui/tooltip.json +8 -1
- package/registry/ui/typography.json +9 -1
- package/styles/tokens.reference.css +21 -0
package/package.json
CHANGED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Canvas Consumer App
|
|
2
|
+
|
|
3
|
+
This is a Next.js app that uses the Canvas UI SDK component library.
|
|
4
|
+
|
|
5
|
+
## Adding Components
|
|
6
|
+
|
|
7
|
+
This project uses a **shadcn-style CLI** to copy component source files from `canvas-ui-sdk` into the project for full customization.
|
|
8
|
+
|
|
9
|
+
### Available commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# See all available components (145 total: layouts, blocks, UI primitives, hooks)
|
|
13
|
+
npx canvas-ui list
|
|
14
|
+
|
|
15
|
+
# Copy components into the project (auto-resolves dependencies)
|
|
16
|
+
npx canvas-ui add <component-name> [component-name...]
|
|
17
|
+
|
|
18
|
+
# Examples:
|
|
19
|
+
npx canvas-ui add button # Copies button + utils
|
|
20
|
+
npx canvas-ui add dashboard-shell # Copies shell + sidebar + header + 15 deps
|
|
21
|
+
npx canvas-ui add standard-data-table # Copies table + pagination + deps
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### How it works
|
|
25
|
+
|
|
26
|
+
- Components are copied as **editable source files** into `src/components/`
|
|
27
|
+
- UI primitives go to `src/components/ui/`
|
|
28
|
+
- Layout shells go to `src/components/layout/`
|
|
29
|
+
- Block components go to `src/components/blocks/<category>/`
|
|
30
|
+
- Hooks go to `src/hooks/`
|
|
31
|
+
- Utilities go to `src/lib/`
|
|
32
|
+
- Import paths use `@/` aliases (e.g. `@/components/ui/button`, `@/lib/utils`)
|
|
33
|
+
- npm dependencies (like `@radix-ui/*`, `class-variance-authority`) are auto-installed
|
|
34
|
+
|
|
35
|
+
### When building a page
|
|
36
|
+
|
|
37
|
+
1. Decide which layout shell fits (run `npx canvas-ui list` to see options)
|
|
38
|
+
2. Add the layout: `npx canvas-ui add <shell-name>`
|
|
39
|
+
3. Add any blocks needed: `npx canvas-ui add <block-name> [block-name...]`
|
|
40
|
+
4. Import components from their local paths (e.g. `import { Button } from "@/components/ui/button"`)
|
|
41
|
+
5. Customize the copied source files as needed
|
|
42
|
+
|
|
43
|
+
### What stays in the npm package (do NOT copy these)
|
|
44
|
+
|
|
45
|
+
- Design tokens / CSS variables (`canvas-ui-sdk/styles`)
|
|
46
|
+
- Tailwind theme mappings (`canvas-ui-sdk/tailwind`)
|
|
47
|
+
- Theme context and providers (`canvas-ui-sdk`)
|
|
48
|
+
|
|
49
|
+
These are imported directly from the npm package, not copied.
|
|
50
|
+
|
|
51
|
+
## Design Tokens
|
|
52
|
+
|
|
53
|
+
When creating or modifying components, always use the canvas design token CSS variables. Never use raw Tailwind color classes (`bg-white`, `text-gray-500`, `border-gray-200`) or hardcoded pixel values for font sizes. Use the token system instead:
|
|
54
|
+
|
|
55
|
+
- **Colors**: `var(--canvas-background)`, `var(--canvas-text)`, `var(--canvas-primary)`, `var(--canvas-border)`, etc.
|
|
56
|
+
- **Typography**: `var(--typo-body-s-size)`, `var(--typo-body-m-size)`, `var(--typo-h4-size)`, `var(--typo-global-font)`, etc.
|
|
57
|
+
- **Spacing**: `var(--spacing-sm)`, `var(--spacing-md)`, `var(--spacing-lg)`, etc.
|
|
58
|
+
- **Radii**: `var(--radius-xs)`, `var(--radius-sm)`, `var(--radius-md)`, etc.
|
|
59
|
+
- **Inputs**: `var(--canvas-border-input)`, `var(--input-standard-height)`, `var(--input-standard-radius)`, etc.
|
|
60
|
+
- **Buttons**: `var(--btn-primary-bg)`, `var(--btn-standard-height)`, etc.
|
|
61
|
+
|
|
62
|
+
Reference the SDK's `styles/tokens.reference.css` for the full list of available tokens.
|
|
63
|
+
|
|
64
|
+
## Design Best Practices
|
|
65
|
+
|
|
66
|
+
- **Prefer SDK components over hand-rolled layouts** for common UI patterns (stats, metrics, reviews, profile cards, data tables). Always check `npx canvas-ui list` or the MCP `list_components` tool before writing custom markup — the SDK likely has a component that handles it with proper spacing, alignment, and responsive behavior built in.
|
|
67
|
+
- **Numeric displays need visual structure** — never render large numbers in a bare flex row without containment. Use `StatsCard` for profile/sidebar stats, `MetricCardsRow` for dashboard KPIs with change indicators, or `MetricsSection` for marketing hero stats. If none fits exactly, at minimum wrap numbers in a card container with dividers or border separators.
|
|
68
|
+
- **Use Typography for text** — use the `Typography` component with heading variants (`h4`–`h6`) for stat values and `body-s` muted for labels. Avoid raw `fontSize`/`fontWeight` inline styles when Typography already handles token-correct sizing, font family, and line height.
|
|
69
|
+
- **Customize components, don't rebuild them** — when a component is close but not perfect for a use case, import it and make small modifications (remove the card wrapper via className, adjust padding, hide a section) rather than rebuilding from scratch. Components encode spacing, alignment, typography scale, and responsive breakpoints that are easy to get wrong when hand-rolling.
|
|
70
|
+
- **Use the MCP `review_design` tool** before finalizing layouts — it checks for common anti-patterns like uncontained numbers, missing visual hierarchy, or hand-rolled patterns that have SDK component equivalents.
|
|
71
|
+
- **Block-first for content sections** — before writing custom JSX for any content section, check if the SDK has a block for it. Common mappings: Reviews → `ReviewsTable`, Image galleries → `TileImageGallery`, Activity feeds → `ActivityFeed`, Chat → `BottomInputChatWidget`, Data listings → `StandardDataTable` / `GridTilesList`, FAQ → `FaqsTable`, Social feeds → `SocialFeed`, Calendar → `MonthlyCalendarWidget`, Comments → `NestedCommentsTable`. The SDK has 119 blocks — hand-rolling what already exists wastes time and produces worse results.
|
|
72
|
+
- **Always provide images** — components that accept image props (`TileImageGallery`, `LoginBrandingPanel`, `HeroSection`, `ProfileCard`, `DestinationCards`, etc.) should always receive relevant images. First check if the user has saved brand assets in the ThemeDrawer's Images panel — if available, use those. Otherwise, use high-quality Unsplash images that match the content context. Never leave image props empty when the component has a visual placeholder or broken default.
|
|
73
|
+
- **Choose the right data format** — use `GridTilesList` (tile cards with images) when each item has a prominent visual (property photos, product images, portfolio pieces). Use `StandardDataTable` (tabular rows) for text-heavy data like user lists, transactions, or logs. When items have large images, the tile format is always more appropriate than squeezing them into small row avatars.
|
|
74
|
+
|
|
75
|
+
## CSS Setup
|
|
76
|
+
|
|
77
|
+
The app's `src/app/globals.css` imports:
|
|
78
|
+
```css
|
|
79
|
+
@import "tailwindcss";
|
|
80
|
+
@import "canvas-ui-sdk/tailwind";
|
|
81
|
+
@import "canvas-ui-sdk/styles";
|
|
82
|
+
@source "../../node_modules/canvas-ui-sdk/dist";
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Project Structure
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
src/
|
|
89
|
+
app/ # Next.js app router pages
|
|
90
|
+
components/ # Copied Canvas UI components (editable)
|
|
91
|
+
ui/ # Primitives (button, input, dialog, etc.)
|
|
92
|
+
layout/ # Layout shells (dashboard-shell, sidebar, etc.)
|
|
93
|
+
blocks/ # Feature blocks (data-tables, forms, cards, etc.)
|
|
94
|
+
hooks/ # Copied hooks
|
|
95
|
+
lib/ # Utilities (utils.ts with cn() helper)
|
|
96
|
+
```
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Canvas Consumer App
|
|
2
|
+
|
|
3
|
+
This is a Next.js app that uses the Canvas UI SDK component library.
|
|
4
|
+
|
|
5
|
+
## Adding Components
|
|
6
|
+
|
|
7
|
+
This project uses a **shadcn-style CLI** to copy component source files from `canvas-ui-sdk` into the project for full customization.
|
|
8
|
+
|
|
9
|
+
### Available commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# See all available components (145 total: layouts, blocks, UI primitives, hooks)
|
|
13
|
+
npx canvas-ui list
|
|
14
|
+
|
|
15
|
+
# Copy components into the project (auto-resolves dependencies)
|
|
16
|
+
npx canvas-ui add <component-name> [component-name...]
|
|
17
|
+
|
|
18
|
+
# Examples:
|
|
19
|
+
npx canvas-ui add button # Copies button + utils
|
|
20
|
+
npx canvas-ui add dashboard-shell # Copies shell + sidebar + header + 15 deps
|
|
21
|
+
npx canvas-ui add standard-data-table # Copies table + pagination + deps
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### How it works
|
|
25
|
+
|
|
26
|
+
- Components are copied as **editable source files** into `src/components/`
|
|
27
|
+
- UI primitives go to `src/components/ui/`
|
|
28
|
+
- Layout shells go to `src/components/layout/`
|
|
29
|
+
- Block components go to `src/components/blocks/<category>/`
|
|
30
|
+
- Hooks go to `src/hooks/`
|
|
31
|
+
- Utilities go to `src/lib/`
|
|
32
|
+
- Import paths use `@/` aliases (e.g. `@/components/ui/button`, `@/lib/utils`)
|
|
33
|
+
- npm dependencies (like `@radix-ui/*`, `class-variance-authority`) are auto-installed
|
|
34
|
+
|
|
35
|
+
### When building a page
|
|
36
|
+
|
|
37
|
+
1. Decide which layout shell fits (run `npx canvas-ui list` to see options)
|
|
38
|
+
2. Add the layout: `npx canvas-ui add <shell-name>`
|
|
39
|
+
3. Add any blocks needed: `npx canvas-ui add <block-name> [block-name...]`
|
|
40
|
+
4. Import components from their local paths (e.g. `import { Button } from "@/components/ui/button"`)
|
|
41
|
+
5. Customize the copied source files as needed
|
|
42
|
+
|
|
43
|
+
### What stays in the npm package (do NOT copy these)
|
|
44
|
+
|
|
45
|
+
- Design tokens / CSS variables (`canvas-ui-sdk/styles`)
|
|
46
|
+
- Tailwind theme mappings (`canvas-ui-sdk/tailwind`)
|
|
47
|
+
- Theme context and providers (`canvas-ui-sdk`)
|
|
48
|
+
|
|
49
|
+
These are imported directly from the npm package, not copied.
|
|
50
|
+
|
|
51
|
+
## Design Tokens
|
|
52
|
+
|
|
53
|
+
When creating or modifying components, always use the canvas design token CSS variables. Never use raw Tailwind color classes (`bg-white`, `text-gray-500`, `border-gray-200`) or hardcoded pixel values for font sizes. Use the token system instead:
|
|
54
|
+
|
|
55
|
+
- **Colors**: `var(--canvas-background)`, `var(--canvas-text)`, `var(--canvas-primary)`, `var(--canvas-border)`, etc.
|
|
56
|
+
- **Typography**: `var(--typo-body-s-size)`, `var(--typo-body-m-size)`, `var(--typo-h4-size)`, `var(--typo-global-font)`, etc.
|
|
57
|
+
- **Spacing**: `var(--spacing-sm)`, `var(--spacing-md)`, `var(--spacing-lg)`, etc.
|
|
58
|
+
- **Radii**: `var(--radius-xs)`, `var(--radius-sm)`, `var(--radius-md)`, etc.
|
|
59
|
+
- **Inputs**: `var(--canvas-border-input)`, `var(--input-standard-height)`, `var(--input-standard-radius)`, etc.
|
|
60
|
+
- **Buttons**: `var(--btn-primary-bg)`, `var(--btn-standard-height)`, etc.
|
|
61
|
+
|
|
62
|
+
Reference the SDK's `styles/tokens.reference.css` for the full list of available tokens.
|
|
63
|
+
|
|
64
|
+
## Design Best Practices
|
|
65
|
+
|
|
66
|
+
- **Prefer SDK components over hand-rolled layouts** for common UI patterns (stats, metrics, reviews, profile cards, data tables). Always check `npx canvas-ui list` or the MCP `list_components` tool before writing custom markup — the SDK likely has a component that handles it with proper spacing, alignment, and responsive behavior built in.
|
|
67
|
+
- **Numeric displays need visual structure** — never render large numbers in a bare flex row without containment. Use `StatsCard` for profile/sidebar stats, `MetricCardsRow` for dashboard KPIs with change indicators, or `MetricsSection` for marketing hero stats. If none fits exactly, at minimum wrap numbers in a card container with dividers or border separators.
|
|
68
|
+
- **Use Typography for text** — use the `Typography` component with heading variants (`h4`–`h6`) for stat values and `body-s` muted for labels. Avoid raw `fontSize`/`fontWeight` inline styles when Typography already handles token-correct sizing, font family, and line height.
|
|
69
|
+
- **Customize components, don't rebuild them** — when a component is close but not perfect for a use case, import it and make small modifications (remove the card wrapper via className, adjust padding, hide a section) rather than rebuilding from scratch. Components encode spacing, alignment, typography scale, and responsive breakpoints that are easy to get wrong when hand-rolling.
|
|
70
|
+
- **Use the MCP `review_design` tool** before finalizing layouts — it checks for common anti-patterns like uncontained numbers, missing visual hierarchy, or hand-rolled patterns that have SDK component equivalents.
|
|
71
|
+
- **Block-first for content sections** — before writing custom JSX for any content section, check if the SDK has a block for it. Common mappings: Reviews → `ReviewsTable`, Image galleries → `TileImageGallery`, Activity feeds → `ActivityFeed`, Chat → `BottomInputChatWidget`, Data listings → `StandardDataTable` / `GridTilesList`, FAQ → `FaqsTable`, Social feeds → `SocialFeed`, Calendar → `MonthlyCalendarWidget`, Comments → `NestedCommentsTable`. The SDK has 119 blocks — hand-rolling what already exists wastes time and produces worse results.
|
|
72
|
+
- **Always provide images** — components that accept image props (`TileImageGallery`, `LoginBrandingPanel`, `HeroSection`, `ProfileCard`, `DestinationCards`, etc.) should always receive relevant images. First check if the user has saved brand assets in the ThemeDrawer's Images panel — if available, use those. Otherwise, use high-quality Unsplash images that match the content context. Never leave image props empty when the component has a visual placeholder or broken default.
|
|
73
|
+
- **Choose the right data format** — use `GridTilesList` (tile cards with images) when each item has a prominent visual (property photos, product images, portfolio pieces). Use `StandardDataTable` (tabular rows) for text-heavy data like user lists, transactions, or logs. When items have large images, the tile format is always more appropriate than squeezing them into small row avatars.
|
|
74
|
+
|
|
75
|
+
## CSS Setup
|
|
76
|
+
|
|
77
|
+
The app's `src/app/globals.css` imports:
|
|
78
|
+
```css
|
|
79
|
+
@import "tailwindcss";
|
|
80
|
+
@import "canvas-ui-sdk/tailwind";
|
|
81
|
+
@import "canvas-ui-sdk/styles";
|
|
82
|
+
@source "../../node_modules/canvas-ui-sdk/dist";
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Project Structure
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
src/
|
|
89
|
+
app/ # Next.js app router pages
|
|
90
|
+
components/ # Copied Canvas UI components (editable)
|
|
91
|
+
ui/ # Primitives (button, input, dialog, etc.)
|
|
92
|
+
layout/ # Layout shells (dashboard-shell, sidebar, etc.)
|
|
93
|
+
blocks/ # Feature blocks (data-tables, forms, cards, etc.)
|
|
94
|
+
hooks/ # Copied hooks
|
|
95
|
+
lib/ # Utilities (utils.ts with cn() helper)
|
|
96
|
+
```
|
package/prompts/CLAUDE.md
CHANGED
|
@@ -32,6 +32,17 @@ npx canvas-ui add standard-data-table # Copies table + pagination + deps
|
|
|
32
32
|
- Import paths use `@/` aliases (e.g. `@/components/ui/button`, `@/lib/utils`)
|
|
33
33
|
- npm dependencies (like `@radix-ui/*`, `class-variance-authority`) are auto-installed
|
|
34
34
|
|
|
35
|
+
### Default Page Templates
|
|
36
|
+
|
|
37
|
+
When building common app pages, use these Canvas base templates by default:
|
|
38
|
+
- **Account settings / user preferences** → `page-account` (AccountSettingsShell)
|
|
39
|
+
- **Admin portal / admin dashboard** → `page-admin-portal` (DashboardShell)
|
|
40
|
+
- **Login** → `page-login` (split layout with LoginBrandingPanel)
|
|
41
|
+
- **Signup** → `page-login` (same template, adjust form fields)
|
|
42
|
+
- **Password reset** → `page-reset-password` (split layout)
|
|
43
|
+
|
|
44
|
+
Only deviate from these defaults when the user explicitly specifies a different template, provides a reference design that significantly differs, or describes requirements incompatible with the base templates.
|
|
45
|
+
|
|
35
46
|
### When building a page
|
|
36
47
|
|
|
37
48
|
1. Decide which layout shell fits (run `npx canvas-ui list` to see options)
|
|
@@ -61,6 +72,17 @@ When creating or modifying components, always use the canvas design token CSS va
|
|
|
61
72
|
|
|
62
73
|
Reference the SDK's `styles/tokens.reference.css` for the full list of available tokens.
|
|
63
74
|
|
|
75
|
+
## Design Best Practices
|
|
76
|
+
|
|
77
|
+
- **Prefer SDK components over hand-rolled layouts** for common UI patterns (stats, metrics, reviews, profile cards, data tables). Always check `npx canvas-ui list` or the MCP `list_components` tool before writing custom markup — the SDK likely has a component that handles it with proper spacing, alignment, and responsive behavior built in.
|
|
78
|
+
- **Numeric displays need visual structure** — never render large numbers in a bare flex row without containment. Use `StatsCard` for profile/sidebar stats, `MetricCardsRow` for dashboard KPIs with change indicators, or `MetricsSection` for marketing hero stats. If none fits exactly, at minimum wrap numbers in a card container with dividers or border separators.
|
|
79
|
+
- **Use Typography for text** — use the `Typography` component with heading variants (`h4`–`h6`) for stat values and `body-s` muted for labels. Avoid raw `fontSize`/`fontWeight` inline styles when Typography already handles token-correct sizing, font family, and line height.
|
|
80
|
+
- **Customize components, don't rebuild them** — when a component is close but not perfect for a use case, import it and make small modifications (remove the card wrapper via className, adjust padding, hide a section) rather than rebuilding from scratch. Components encode spacing, alignment, typography scale, and responsive breakpoints that are easy to get wrong when hand-rolling.
|
|
81
|
+
- **Use the MCP `review_design` tool** before finalizing layouts — it checks for common anti-patterns like uncontained numbers, missing visual hierarchy, or hand-rolled patterns that have SDK component equivalents.
|
|
82
|
+
- **Block-first for content sections** — before writing custom JSX for any content section, check if the SDK has a block for it. Common mappings: Reviews → `ReviewsTable`, Image galleries → `TileImageGallery`, Activity feeds → `ActivityFeed`, Chat → `BottomInputChatWidget`, Data listings → `StandardDataTable` / `GridTilesList`, FAQ → `FaqsTable`, Social feeds → `SocialFeed`, Calendar → `MonthlyCalendarWidget`, Comments → `NestedCommentsTable`. The SDK has 119 blocks — hand-rolling what already exists wastes time and produces worse results.
|
|
83
|
+
- **Always provide images** — components that accept image props (`TileImageGallery`, `LoginBrandingPanel`, `HeroSection`, `ProfileCard`, `DestinationCards`, etc.) should always receive relevant images. First check if the user has saved brand assets in the ThemeDrawer's Images panel — if available, use those. Otherwise, use high-quality Unsplash images that match the content context. Never leave image props empty when the component has a visual placeholder or broken default.
|
|
84
|
+
- **Choose the right data format** — use `GridTilesList` (tile cards with images) when each item has a prominent visual (property photos, product images, portfolio pieces). Use `StandardDataTable` (tabular rows) for text-heavy data like user lists, transactions, or logs. When items have large images, the tile format is always more appropriate than squeezing them into small row avatars.
|
|
85
|
+
|
|
64
86
|
## CSS Setup
|
|
65
87
|
|
|
66
88
|
The app's `src/app/globals.css` imports:
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Canvas Consumer App
|
|
2
|
+
|
|
3
|
+
This is a Next.js app that uses the Canvas UI SDK component library.
|
|
4
|
+
|
|
5
|
+
## Adding Components
|
|
6
|
+
|
|
7
|
+
This project uses a **shadcn-style CLI** to copy component source files from `canvas-ui-sdk` into the project for full customization.
|
|
8
|
+
|
|
9
|
+
### Available commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# See all available components (145 total: layouts, blocks, UI primitives, hooks)
|
|
13
|
+
npx canvas-ui list
|
|
14
|
+
|
|
15
|
+
# Copy components into the project (auto-resolves dependencies)
|
|
16
|
+
npx canvas-ui add <component-name> [component-name...]
|
|
17
|
+
|
|
18
|
+
# Examples:
|
|
19
|
+
npx canvas-ui add button # Copies button + utils
|
|
20
|
+
npx canvas-ui add dashboard-shell # Copies shell + sidebar + header + 15 deps
|
|
21
|
+
npx canvas-ui add standard-data-table # Copies table + pagination + deps
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### How it works
|
|
25
|
+
|
|
26
|
+
- Components are copied as **editable source files** into `src/components/`
|
|
27
|
+
- UI primitives go to `src/components/ui/`
|
|
28
|
+
- Layout shells go to `src/components/layout/`
|
|
29
|
+
- Block components go to `src/components/blocks/<category>/`
|
|
30
|
+
- Hooks go to `src/hooks/`
|
|
31
|
+
- Utilities go to `src/lib/`
|
|
32
|
+
- Import paths use `@/` aliases (e.g. `@/components/ui/button`, `@/lib/utils`)
|
|
33
|
+
- npm dependencies (like `@radix-ui/*`, `class-variance-authority`) are auto-installed
|
|
34
|
+
|
|
35
|
+
### When building a page
|
|
36
|
+
|
|
37
|
+
1. Decide which layout shell fits (run `npx canvas-ui list` to see options)
|
|
38
|
+
2. Add the layout: `npx canvas-ui add <shell-name>`
|
|
39
|
+
3. Add any blocks needed: `npx canvas-ui add <block-name> [block-name...]`
|
|
40
|
+
4. Import components from their local paths (e.g. `import { Button } from "@/components/ui/button"`)
|
|
41
|
+
5. Customize the copied source files as needed
|
|
42
|
+
|
|
43
|
+
### What stays in the npm package (do NOT copy these)
|
|
44
|
+
|
|
45
|
+
- Design tokens / CSS variables (`canvas-ui-sdk/styles`)
|
|
46
|
+
- Tailwind theme mappings (`canvas-ui-sdk/tailwind`)
|
|
47
|
+
- Theme context and providers (`canvas-ui-sdk`)
|
|
48
|
+
|
|
49
|
+
These are imported directly from the npm package, not copied.
|
|
50
|
+
|
|
51
|
+
## Design Tokens
|
|
52
|
+
|
|
53
|
+
When creating or modifying components, always use the canvas design token CSS variables. Never use raw Tailwind color classes (`bg-white`, `text-gray-500`, `border-gray-200`) or hardcoded pixel values for font sizes. Use the token system instead:
|
|
54
|
+
|
|
55
|
+
- **Colors**: `var(--canvas-background)`, `var(--canvas-text)`, `var(--canvas-primary)`, `var(--canvas-border)`, etc.
|
|
56
|
+
- **Typography**: `var(--typo-body-s-size)`, `var(--typo-body-m-size)`, `var(--typo-h4-size)`, `var(--typo-global-font)`, etc.
|
|
57
|
+
- **Spacing**: `var(--spacing-sm)`, `var(--spacing-md)`, `var(--spacing-lg)`, etc.
|
|
58
|
+
- **Radii**: `var(--radius-xs)`, `var(--radius-sm)`, `var(--radius-md)`, etc.
|
|
59
|
+
- **Inputs**: `var(--canvas-border-input)`, `var(--input-standard-height)`, `var(--input-standard-radius)`, etc.
|
|
60
|
+
- **Buttons**: `var(--btn-primary-bg)`, `var(--btn-standard-height)`, etc.
|
|
61
|
+
|
|
62
|
+
Reference the SDK's `styles/tokens.reference.css` for the full list of available tokens.
|
|
63
|
+
|
|
64
|
+
## Design Best Practices
|
|
65
|
+
|
|
66
|
+
- **Prefer SDK components over hand-rolled layouts** for common UI patterns (stats, metrics, reviews, profile cards, data tables). Always check `npx canvas-ui list` or the MCP `list_components` tool before writing custom markup — the SDK likely has a component that handles it with proper spacing, alignment, and responsive behavior built in.
|
|
67
|
+
- **Numeric displays need visual structure** — never render large numbers in a bare flex row without containment. Use `StatsCard` for profile/sidebar stats, `MetricCardsRow` for dashboard KPIs with change indicators, or `MetricsSection` for marketing hero stats. If none fits exactly, at minimum wrap numbers in a card container with dividers or border separators.
|
|
68
|
+
- **Use Typography for text** — use the `Typography` component with heading variants (`h4`–`h6`) for stat values and `body-s` muted for labels. Avoid raw `fontSize`/`fontWeight` inline styles when Typography already handles token-correct sizing, font family, and line height.
|
|
69
|
+
- **Customize components, don't rebuild them** — when a component is close but not perfect for a use case, import it and make small modifications (remove the card wrapper via className, adjust padding, hide a section) rather than rebuilding from scratch. Components encode spacing, alignment, typography scale, and responsive breakpoints that are easy to get wrong when hand-rolling.
|
|
70
|
+
- **Use the MCP `review_design` tool** before finalizing layouts — it checks for common anti-patterns like uncontained numbers, missing visual hierarchy, or hand-rolled patterns that have SDK component equivalents.
|
|
71
|
+
- **Block-first for content sections** — before writing custom JSX for any content section, check if the SDK has a block for it. Common mappings: Reviews → `ReviewsTable`, Image galleries → `TileImageGallery`, Activity feeds → `ActivityFeed`, Chat → `BottomInputChatWidget`, Data listings → `StandardDataTable` / `GridTilesList`, FAQ → `FaqsTable`, Social feeds → `SocialFeed`, Calendar → `MonthlyCalendarWidget`, Comments → `NestedCommentsTable`. The SDK has 119 blocks — hand-rolling what already exists wastes time and produces worse results.
|
|
72
|
+
- **Always provide images** — components that accept image props (`TileImageGallery`, `LoginBrandingPanel`, `HeroSection`, `ProfileCard`, `DestinationCards`, etc.) should always receive relevant images. First check if the user has saved brand assets in the ThemeDrawer's Images panel — if available, use those. Otherwise, use high-quality Unsplash images that match the content context. Never leave image props empty when the component has a visual placeholder or broken default.
|
|
73
|
+
- **Choose the right data format** — use `GridTilesList` (tile cards with images) when each item has a prominent visual (property photos, product images, portfolio pieces). Use `StandardDataTable` (tabular rows) for text-heavy data like user lists, transactions, or logs. When items have large images, the tile format is always more appropriate than squeezing them into small row avatars.
|
|
74
|
+
|
|
75
|
+
## CSS Setup
|
|
76
|
+
|
|
77
|
+
The app's `src/app/globals.css` imports:
|
|
78
|
+
```css
|
|
79
|
+
@import "tailwindcss";
|
|
80
|
+
@import "canvas-ui-sdk/tailwind";
|
|
81
|
+
@import "canvas-ui-sdk/styles";
|
|
82
|
+
@source "../../node_modules/canvas-ui-sdk/dist";
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Project Structure
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
src/
|
|
89
|
+
app/ # Next.js app router pages
|
|
90
|
+
components/ # Copied Canvas UI components (editable)
|
|
91
|
+
ui/ # Primitives (button, input, dialog, etc.)
|
|
92
|
+
layout/ # Layout shells (dashboard-shell, sidebar, etc.)
|
|
93
|
+
blocks/ # Feature blocks (data-tables, forms, cards, etc.)
|
|
94
|
+
hooks/ # Copied hooks
|
|
95
|
+
lib/ # Utilities (utils.ts with cn() helper)
|
|
96
|
+
```
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "activity-feed",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "Timeline-style activity feed
|
|
4
|
+
"description": "Timeline-style activity feed with vertical connecting lines between entries. Each entry shows user avatar, action description, timestamp, and optional attachments or reactions. Full-width block (~400-800px depending on items). Use for audit logs, project activity, notification history, or any chronological event stream.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"timeline",
|
|
7
|
+
"audit",
|
|
8
|
+
"log",
|
|
9
|
+
"history",
|
|
10
|
+
"events",
|
|
11
|
+
"chronological",
|
|
12
|
+
"feed",
|
|
13
|
+
"activity"
|
|
14
|
+
],
|
|
15
|
+
"visualWeight": "heavy",
|
|
5
16
|
"files": [
|
|
6
17
|
{
|
|
7
18
|
"path": "components/blocks/activity-feed.tsx",
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blog-cards",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "3-column grid of blog/article cards with large images, title, description, and 'Read more' link with arrow icon. Header with subtitle and title. Use for blog sections, news feeds, content highlights, or any editorial content grid.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"blog",
|
|
7
|
+
"articles",
|
|
8
|
+
"news",
|
|
9
|
+
"content",
|
|
10
|
+
"cards"
|
|
11
|
+
],
|
|
12
|
+
"visualWeight": "medium",
|
|
5
13
|
"files": [
|
|
6
14
|
{
|
|
7
15
|
"path": "components/blocks/marketing/blog-cards.tsx",
|
|
8
16
|
"type": "registry:block",
|
|
9
|
-
"content": "\"use client\";\n\nimport { ArrowRight } from \"@phosphor-icons/react\";\nimport { Typography } from \"../../ui/typography\";\n\ninterface BlogPost {\n id: string;\n title: string;\n description: string;\n image: string;\n}\n\nconst defaultPosts: BlogPost[] = [\n {\n id: \"1\",\n title: \"Top destinations to visit\",\n description: \"Discover the most exciting and must-visit travel spots around the world, from iconic cities to hidden gems.\",\n image: \"https://images.unsplash.com/photo-1502602898657-3e91760cbb34?w=400&h=340&fit=crop\",\n },\n {\n id: \"2\",\n title: \"Breathtaking natural wonders\",\n description: \"Explore the world's most awe-inspiring landscapes, from towering mountains to stunning waterfalls and surreal deserts.\",\n image: \"https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=340&fit=crop\",\n },\n {\n id: \"3\",\n title: \"Must-try dishes in Italy\",\n description: \"Indulge in Italy's most delicious and authentic dishes, from creamy pasta to crispy pizzas and decadent desserts.\",\n image: \"https://images.unsplash.com/photo-1498579150354-977475b7ea0b?w=400&h=340&fit=crop\",\n },\n];\n\ninterface BlogCardsProps {\n subtitle?: string;\n title?: string;\n posts?: BlogPost[];\n}\n\nexport function BlogCards({ \n subtitle = \"OUR BLOG\",\n title = \"Get inspired\",\n posts = defaultPosts,\n}: BlogCardsProps) {\n return (\n <section \n className=\"w-full px-4 md:px-8 lg:px-20 py-16 md:py-24\"\n style={{\n backgroundColor: \"var(--canvas-background)\",\n }}\n >\n <div className=\"w-full max-w-[1240px] mx-auto flex flex-col gap-16\">\n {/* Header */}\n <div className=\"flex flex-col gap-3 max-w-[768px]\">\n <Typography variant=\"body-s\" as=\"p\" color=\"muted\">\n {subtitle}\n </Typography>\n <Typography variant=\"h3\" as=\"h2\">\n {title}\n </Typography>\n </div>\n\n {/* Cards Grid */}\n <div className=\"grid grid-cols-1
|
|
17
|
+
"content": "\"use client\";\n\nimport { ArrowRight } from \"@phosphor-icons/react\";\nimport { Typography } from \"../../ui/typography\";\n\ninterface BlogPost {\n id: string;\n title: string;\n description: string;\n image: string;\n}\n\nconst defaultPosts: BlogPost[] = [\n {\n id: \"1\",\n title: \"Top destinations to visit\",\n description: \"Discover the most exciting and must-visit travel spots around the world, from iconic cities to hidden gems.\",\n image: \"https://images.unsplash.com/photo-1502602898657-3e91760cbb34?w=400&h=340&fit=crop\",\n },\n {\n id: \"2\",\n title: \"Breathtaking natural wonders\",\n description: \"Explore the world's most awe-inspiring landscapes, from towering mountains to stunning waterfalls and surreal deserts.\",\n image: \"https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=340&fit=crop\",\n },\n {\n id: \"3\",\n title: \"Must-try dishes in Italy\",\n description: \"Indulge in Italy's most delicious and authentic dishes, from creamy pasta to crispy pizzas and decadent desserts.\",\n image: \"https://images.unsplash.com/photo-1498579150354-977475b7ea0b?w=400&h=340&fit=crop\",\n },\n];\n\ninterface BlogCardsProps {\n subtitle?: string;\n title?: string;\n posts?: BlogPost[];\n}\n\nexport function BlogCards({ \n subtitle = \"OUR BLOG\",\n title = \"Get inspired\",\n posts = defaultPosts,\n}: BlogCardsProps) {\n return (\n <section \n className=\"w-full px-4 md:px-8 lg:px-20 py-16 md:py-24\"\n style={{\n backgroundColor: \"var(--canvas-background)\",\n }}\n >\n <div className=\"w-full max-w-[1240px] mx-auto flex flex-col gap-16\">\n {/* Header */}\n <div className=\"flex flex-col gap-3 max-w-[768px]\">\n <Typography variant=\"body-s\" as=\"p\" color=\"muted\">\n {subtitle}\n </Typography>\n <Typography variant=\"h3\" as=\"h2\">\n {title}\n </Typography>\n </div>\n\n {/* Cards Grid */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-10\">\n {posts.map((post) => (\n <div \n key={post.id}\n className=\"flex flex-col overflow-hidden cursor-pointer group\"\n style={{\n border: \"1px solid var(--canvas-border)\",\n borderRadius: \"var(--radius-xl)\",\n }}\n >\n {/* Image */}\n <div \n className=\"w-full h-[220px] sm:h-[340px] overflow-hidden\"\n style={{\n borderBottom: \"1px solid var(--canvas-border)\",\n }}\n >\n <img \n src={post.image} \n alt={post.title}\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\"\n />\n </div>\n \n {/* Content */}\n <div \n className=\"flex flex-col gap-1 p-6\"\n >\n <Typography variant=\"body-xl\" as=\"h3\" style={{ fontWeight: 600 }}>\n {post.title}\n </Typography>\n <Typography variant=\"body-m\" color=\"muted\">\n {post.description}\n </Typography>\n \n {/* Read more */}\n <div className=\"flex items-center gap-2 pt-5\">\n <Typography variant=\"body-m\" as=\"span\" style={{ fontWeight: 500 }}>\n Read more\n </Typography>\n <div \n className=\"flex items-center justify-center\"\n style={{\n width: \"24px\",\n height: \"24px\",\n backgroundColor: \"var(--canvas-text)\",\n borderRadius: \"var(--radius-4xl)\",\n }}\n >\n <ArrowRight size={16} color=\"white\" weight=\"bold\" />\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n}\n"
|
|
10
18
|
}
|
|
11
19
|
],
|
|
12
20
|
"dependencies": [
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bottom-action-bar",
|
|
3
|
+
"type": "registry:block",
|
|
4
|
+
"description": "Sticky bottom bar displaying price with unit and primary CTA button. Fixed to bottom of viewport (~64px tall). Use on mobile-friendly detail pages for persistent booking/purchase actions.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"bottom",
|
|
7
|
+
"action",
|
|
8
|
+
"bar",
|
|
9
|
+
"sticky",
|
|
10
|
+
"cta",
|
|
11
|
+
"mobile",
|
|
12
|
+
"price"
|
|
13
|
+
],
|
|
14
|
+
"visualWeight": "light",
|
|
15
|
+
"files": [
|
|
16
|
+
{
|
|
17
|
+
"path": "components/blocks/bottom-action-bar.tsx",
|
|
18
|
+
"type": "registry:block",
|
|
19
|
+
"content": "\"use client\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BottomActionBarProps {\n /** Price display (e.g. \"$100\") */\n price?: string;\n /** Price unit label (e.g. \"per person\") */\n priceUnit?: string;\n /** CTA button label */\n ctaLabel?: string;\n /** CTA button click handler */\n onCtaClick?: () => void;\n /** Additional class names */\n className?: string;\n}\n\n// ============================================================================\n// BottomActionBar\n// ============================================================================\n\n/**\n * Canvas Design System - Bottom Action Bar\n *\n * A sticky bottom bar displaying a price with unit and a primary CTA button.\n * Typically used on product/listing detail pages for mobile-friendly booking.\n */\nexport function BottomActionBar({\n price = \"$100\",\n priceUnit = \"per person\",\n ctaLabel = \"Reserve now\",\n onCtaClick,\n className,\n}: BottomActionBarProps) {\n return (\n <div\n className={cn(\"w-full\", className)}\n style={{\n backgroundColor: \"var(--canvas-background)\",\n borderTop: \"1px solid var(--canvas-border)\",\n boxShadow: \"0px 4px 16px 0px rgba(0,0,0,0.04)\",\n }}\n >\n <div\n className=\"flex items-center overflow-hidden\"\n style={{\n paddingLeft: \"var(--spacing-5xl)\",\n paddingRight: \"var(--spacing-5xl)\",\n paddingTop: \"var(--spacing-xl)\",\n paddingBottom: \"var(--spacing-xl)\",\n gap: \"var(--spacing-3xl)\",\n }}\n >\n {/* Price */}\n <div\n className=\"flex flex-1 items-center min-w-0\"\n style={{ gap: \"var(--spacing-xs)\" }}\n >\n <span\n style={{\n fontFamily: \"var(--typo-body-xl-font, var(--typo-global-font))\",\n fontSize: \"var(--typo-body-xl-size)\",\n fontWeight: 700,\n lineHeight: \"30px\",\n color: \"var(--canvas-text)\",\n }}\n >\n {price}\n </span>\n <span\n style={{\n fontFamily: \"var(--typo-body-s-font, var(--typo-global-font))\",\n fontSize: \"var(--typo-body-s-size)\",\n lineHeight: \"20px\",\n color: \"var(--canvas-text-placeholder)\",\n }}\n >\n {priceUnit}\n </span>\n </div>\n\n {/* CTA */}\n <Button variant=\"primary\" size=\"default\" onClick={onCtaClick}>\n {ctaLabel}\n </Button>\n </div>\n </div>\n );\n}\n"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"dependencies": [],
|
|
23
|
+
"registryDependencies": [
|
|
24
|
+
"lib/utils",
|
|
25
|
+
"ui/button"
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bottom-input-chat-widget",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "Chat widget with two views: threads list (showing conversation previews) and conversation view (showing message bubbles). Bottom input bar with attachment support. Use for in-app messaging, support chat, or team communication.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"chat",
|
|
7
|
+
"widget",
|
|
8
|
+
"messaging",
|
|
9
|
+
"threads",
|
|
10
|
+
"support"
|
|
11
|
+
],
|
|
12
|
+
"visualWeight": "heavy",
|
|
5
13
|
"files": [
|
|
6
14
|
{
|
|
7
15
|
"path": "components/blocks/bottom-input-chat-widget.tsx",
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "category-grid",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "5-column grid of category cards, each with a large icon, category title, and item count on a bordered card. Use for browse-by-category sections, service categories, or topic navigation grids.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"categories",
|
|
7
|
+
"grid",
|
|
8
|
+
"icons",
|
|
9
|
+
"browse",
|
|
10
|
+
"navigation"
|
|
11
|
+
],
|
|
12
|
+
"visualWeight": "medium",
|
|
5
13
|
"files": [
|
|
6
14
|
{
|
|
7
15
|
"path": "components/blocks/marketing/category-grid.tsx",
|
|
8
16
|
"type": "registry:block",
|
|
9
|
-
"content": "\"use client\";\n\nimport { \n Heart, Star, Sun, CurrencyDollar, Smiley, \n Image, Coffee, Moon, Clock, MapPin \n} from \"@phosphor-icons/react\";\nimport { Typography } from \"../../ui/typography\";\n\ninterface CategoryItem {\n id: string;\n title: string;\n count: string;\n icon: React.ReactNode;\n}\n\nconst defaultCategories: CategoryItem[] = [\n { id: \"1\", title: \"Most popular\", count: \"5,000 homes\", icon: <Heart size={48} /> },\n { id: \"2\", title: \"Top rated\", count: \"5,000 homes\", icon: <Star size={48} /> },\n { id: \"3\", title: \"Unique stays\", count: \"5,000 homes\", icon: <Sun size={48} /> },\n { id: \"4\", title: \"Affordable\", count: \"5,000 homes\", icon: <CurrencyDollar size={48} /> },\n { id: \"5\", title: \"Friendly staff\", count: \"5,000 homes\", icon: <Smiley size={48} /> },\n { id: \"6\", title: \"Best views\", count: \"5,000 homes\", icon: <Image size={48} /> },\n { id: \"7\", title: \"Cafes\", count: \"5,000 homes\", icon: <Coffee size={48} /> },\n { id: \"8\", title: \"Night life\", count: \"5,000 homes\", icon: <Moon size={48} /> },\n { id: \"9\", title: \"Open 24 hours\", count: \"5,000 homes\", icon: <Clock size={48} /> },\n { id: \"10\", title: \"Best locations\", count: \"5,000 homes\", icon: <MapPin size={48} /> },\n];\n\ninterface CategoryGridProps {\n title?: string;\n categories?: CategoryItem[];\n}\n\nexport function CategoryGrid({ \n title = \"Browse by category\", \n categories = defaultCategories \n}: CategoryGridProps) {\n return (\n <section \n className=\"w-full px-4 md:px-8 lg:px-10 py-10 md:py-16\"\n style={{\n backgroundColor: \"var(--canvas-background)\",\n }}\n >\n <div className=\"w-full max-w-[1240px] mx-auto\">\n {/* Header */}\n <Typography variant=\"h3\" as=\"h2\" style={{ marginBottom: \"var(--spacing-6xl)\" }}>\n {title}\n </Typography>\n\n {/* Categories Grid */}\n <div className=\"grid grid-cols-2 sm:grid-cols-3
|
|
17
|
+
"content": "\"use client\";\n\nimport { \n Heart, Star, Sun, CurrencyDollar, Smiley, \n Image, Coffee, Moon, Clock, MapPin \n} from \"@phosphor-icons/react\";\nimport { Typography } from \"../../ui/typography\";\n\ninterface CategoryItem {\n id: string;\n title: string;\n count: string;\n icon: React.ReactNode;\n}\n\nconst defaultCategories: CategoryItem[] = [\n { id: \"1\", title: \"Most popular\", count: \"5,000 homes\", icon: <Heart size={48} /> },\n { id: \"2\", title: \"Top rated\", count: \"5,000 homes\", icon: <Star size={48} /> },\n { id: \"3\", title: \"Unique stays\", count: \"5,000 homes\", icon: <Sun size={48} /> },\n { id: \"4\", title: \"Affordable\", count: \"5,000 homes\", icon: <CurrencyDollar size={48} /> },\n { id: \"5\", title: \"Friendly staff\", count: \"5,000 homes\", icon: <Smiley size={48} /> },\n { id: \"6\", title: \"Best views\", count: \"5,000 homes\", icon: <Image size={48} /> },\n { id: \"7\", title: \"Cafes\", count: \"5,000 homes\", icon: <Coffee size={48} /> },\n { id: \"8\", title: \"Night life\", count: \"5,000 homes\", icon: <Moon size={48} /> },\n { id: \"9\", title: \"Open 24 hours\", count: \"5,000 homes\", icon: <Clock size={48} /> },\n { id: \"10\", title: \"Best locations\", count: \"5,000 homes\", icon: <MapPin size={48} /> },\n];\n\ninterface CategoryGridProps {\n title?: string;\n categories?: CategoryItem[];\n}\n\nexport function CategoryGrid({ \n title = \"Browse by category\", \n categories = defaultCategories \n}: CategoryGridProps) {\n return (\n <section \n className=\"w-full px-4 md:px-8 lg:px-10 py-10 md:py-16\"\n style={{\n backgroundColor: \"var(--canvas-background)\",\n }}\n >\n <div className=\"w-full max-w-[1240px] mx-auto\">\n {/* Header */}\n <Typography variant=\"h3\" as=\"h2\" style={{ marginBottom: \"var(--spacing-6xl)\" }}>\n {title}\n </Typography>\n\n {/* Categories Grid */}\n <div className=\"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-8\">\n {categories.map((category) => (\n <div \n key={category.id}\n className=\"flex flex-col items-center justify-center text-center cursor-pointer hover:shadow-md transition-shadow\"\n style={{\n height: \"158px\",\n padding: \"var(--spacing-3xl)\",\n border: \"1px solid var(--canvas-border)\",\n borderRadius: \"var(--spacing-md)\",\n gap: \"var(--spacing-md)\",\n boxShadow: \"0px 1px 8px 0px rgba(0, 0, 0, 0.03)\",\n }}\n >\n <div style={{ color: \"var(--canvas-text)\" }}>\n {category.icon}\n </div>\n <div className=\"flex flex-col\" style={{ gap: \"var(--spacing-xxs)\" }}>\n <Typography variant=\"body-xl\" className=\"font-semibold\">\n {category.title}\n </Typography>\n <Typography variant=\"body-m\" color=\"muted\">\n {category.count}\n </Typography>\n </div>\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n}\n\n"
|
|
10
18
|
}
|
|
11
19
|
],
|
|
12
20
|
"dependencies": [
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "centered-hero",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "Clean centered hero with large heading and subtitle text on a plain background. No image or search bar. Use for about pages, company pages, or minimal landing sections.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"hero",
|
|
7
|
+
"centered",
|
|
8
|
+
"minimal",
|
|
9
|
+
"about",
|
|
10
|
+
"clean"
|
|
11
|
+
],
|
|
12
|
+
"visualWeight": "spacer",
|
|
5
13
|
"files": [
|
|
6
14
|
{
|
|
7
15
|
"path": "components/blocks/marketing/centered-hero.tsx",
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chat-message",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "",
|
|
4
|
+
"description": "Individual chat message component with avatar, sender name, timestamp, and message content. Supports sent/received alignment. Use inside chat interfaces for individual message rendering.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"chat",
|
|
7
|
+
"message",
|
|
8
|
+
"conversation",
|
|
9
|
+
"bubble"
|
|
10
|
+
],
|
|
11
|
+
"visualWeight": "light",
|
|
5
12
|
"files": [
|
|
6
13
|
{
|
|
7
14
|
"path": "components/blocks/chat-message.tsx",
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circular-progress-bar-list",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "Vertical list of items, each with a circular progress indicator (percentage ring), title, description, and action menu. Header with sort/filter controls. Full-width block (~400-600px). Use for skill assessments, goal tracking, course completion, or any list where items have progress.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"progress",
|
|
7
|
+
"skills",
|
|
8
|
+
"goals",
|
|
9
|
+
"tracking",
|
|
10
|
+
"completion",
|
|
11
|
+
"circular",
|
|
12
|
+
"ring"
|
|
13
|
+
],
|
|
14
|
+
"visualWeight": "heavy",
|
|
5
15
|
"files": [
|
|
6
16
|
{
|
|
7
17
|
"path": "components/blocks/circular-progress-bar-list.tsx",
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "confirmation-popup",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "",
|
|
4
|
+
"description": "Modal overlay with title, description text, and confirm/cancel action buttons. Confirm button supports destructive (red) and default (primary) variants. Compact centered dialog (~200px tall). Use for delete confirmations, discard warnings, or any yes/no decision.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"confirm",
|
|
7
|
+
"dialog",
|
|
8
|
+
"modal",
|
|
9
|
+
"delete",
|
|
10
|
+
"warning",
|
|
11
|
+
"destructive"
|
|
12
|
+
],
|
|
13
|
+
"visualWeight": "light",
|
|
5
14
|
"files": [
|
|
6
15
|
{
|
|
7
16
|
"path": "components/blocks/confirmation-popup.tsx",
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "contact-form-popup",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "",
|
|
4
|
+
"description": "Contact form modal with gradient banner, large overlapping avatar, and configurable form fields supporting text, email, tel, and textarea inputs. Centered dialog (~450px tall). Use for contact forms, inquiry submissions, or any user-to-user messaging form.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"contact",
|
|
7
|
+
"form",
|
|
8
|
+
"modal",
|
|
9
|
+
"message",
|
|
10
|
+
"email",
|
|
11
|
+
"inquiry"
|
|
12
|
+
],
|
|
13
|
+
"visualWeight": "medium",
|
|
5
14
|
"files": [
|
|
6
15
|
{
|
|
7
16
|
"path": "components/blocks/contact-form-popup.tsx",
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
"name": "content-dropzone",
|
|
3
3
|
"type": "registry:block",
|
|
4
4
|
"description": "Placeholder dropzone for content areas. Shows dashed placeholder when empty; arranges children in a flex column with 32px (--spacing-4xl) gap between blocks. Within a block, use 12px (--spacing-lg) gap between title groups and their content.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"content",
|
|
7
|
+
"dropzone",
|
|
8
|
+
"container",
|
|
9
|
+
"layout",
|
|
10
|
+
"spacing"
|
|
11
|
+
],
|
|
12
|
+
"visualWeight": "light",
|
|
5
13
|
"files": [
|
|
6
14
|
{
|
|
7
15
|
"path": "components/blocks/content-dropzone.tsx",
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "content-with-image",
|
|
3
3
|
"type": "registry:block",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "Two-column content section with image and text content side by side. Image position toggleable. Similar to FeatureWithImage but more generic. Use for any content + image layout.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"content",
|
|
7
|
+
"image",
|
|
8
|
+
"two-column",
|
|
9
|
+
"text",
|
|
10
|
+
"layout"
|
|
11
|
+
],
|
|
12
|
+
"visualWeight": "medium",
|
|
5
13
|
"files": [
|
|
6
14
|
{
|
|
7
15
|
"path": "components/blocks/marketing/content-with-image.tsx",
|