├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── .nvmrc
├── .prettierignore
├── .prettierrc.json
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app
├── (home)
│ ├── blog
│ │ ├── [slug]
│ │ │ ├── page.client.tsx
│ │ │ └── page.tsx
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── api
│ └── search
│ │ └── route.ts
├── blog-og
│ └── [...slug]
│ │ └── route.tsx
├── docs-banners.tsx
├── docs-og
│ └── [...slug]
│ │ └── route.tsx
├── docs
│ ├── [[...slug]]
│ │ └── page.tsx
│ └── layout.tsx
├── favicon.ico
├── fonts
│ ├── GeistMonoVF.woff
│ └── GeistVF.woff
├── global.css
├── layout.config.tsx
├── layout.tsx
├── opengraph-image.jpg
├── opengraph-image.txt
├── preview
│ └── [[...slug]]
│ │ └── page.tsx
├── sitemap.ts
├── twitter-image-alt.txt
└── twitter-image.jpg
├── cli.json
├── components.json
├── components
├── commerce-ui
│ ├── blocks
│ │ ├── banners
│ │ │ ├── banner-01.tsx
│ │ │ ├── banner-02.tsx
│ │ │ ├── banner-03.tsx
│ │ │ ├── banner-04.tsx
│ │ │ ├── banner-05.tsx
│ │ │ ├── banner-06.tsx
│ │ │ ├── banner-07.tsx
│ │ │ ├── banner-08.tsx
│ │ │ ├── banner-09.tsx
│ │ │ ├── banner-10.tsx
│ │ │ ├── banner-11.tsx
│ │ │ └── banner-12.tsx
│ │ ├── carts
│ │ │ ├── cart-01-ex.tsx
│ │ │ └── cart-01.tsx
│ │ ├── product-card
│ │ │ ├── product-card-01.tsx
│ │ │ ├── product-card-02.tsx
│ │ │ ├── product-card-03.tsx
│ │ │ ├── product-card-04.tsx
│ │ │ ├── product-card-05.tsx
│ │ │ ├── product-card-06.tsx
│ │ │ ├── product-card-07.tsx
│ │ │ ├── product-card-08.tsx
│ │ │ ├── product-card-09.tsx
│ │ │ ├── product-card-10.tsx
│ │ │ ├── product-card-11.tsx
│ │ │ ├── product-card-12.tsx
│ │ │ └── product-card-13.tsx
│ │ ├── product-cards
│ │ │ ├── product-cards-01.tsx
│ │ │ ├── product-cards-03.tsx
│ │ │ ├── product-cards-04.tsx
│ │ │ ├── product-cards-10.tsx
│ │ │ ├── product-cards-11.tsx
│ │ │ └── product-cards-12.tsx
│ │ ├── product-variants
│ │ │ ├── product-variants-01-ex.tsx
│ │ │ ├── product-variants-01.tsx
│ │ │ ├── product-variants-02-ex.tsx
│ │ │ ├── product-variants-02.tsx
│ │ │ ├── product-variants-03-ex.tsx
│ │ │ ├── product-variants-03.tsx
│ │ │ ├── product-variants-04-ex.tsx
│ │ │ ├── product-variants-04.tsx
│ │ │ ├── product-variants-05-ex.tsx
│ │ │ └── product-variants-05.tsx
│ │ └── reviews
│ │ │ ├── review-01.tsx
│ │ │ ├── review-02.tsx
│ │ │ ├── review-03.tsx
│ │ │ ├── review-04.tsx
│ │ │ ├── review-05.tsx
│ │ │ ├── review-06.tsx
│ │ │ ├── review-07.tsx
│ │ │ ├── review-08.tsx
│ │ │ ├── review-09.tsx
│ │ │ └── review-10.tsx
│ ├── components
│ │ ├── face-rating
│ │ │ ├── basic
│ │ │ │ ├── face-rating-basic-ex-01.tsx
│ │ │ │ ├── face-rating-basic-ex-02.tsx
│ │ │ │ ├── face-rating-basic-ex-03.tsx
│ │ │ │ └── face-rating-basic.tsx
│ │ │ └── gradient
│ │ │ │ ├── face-rating-gradient-ex-01.tsx
│ │ │ │ └── face-rating-gradient.tsx
│ │ ├── image-carousel
│ │ │ └── basic
│ │ │ │ ├── image-carousel-basic-ex-01.tsx
│ │ │ │ ├── image-carousel-basic-ex-02.tsx
│ │ │ │ ├── image-carousel-basic-ex-03.tsx
│ │ │ │ ├── image-carousel-basic-ex-04.tsx
│ │ │ │ └── image-carousel-basic.tsx
│ │ ├── image-viewer
│ │ │ ├── basic
│ │ │ │ ├── image-viewer-basic-ex-01.tsx
│ │ │ │ ├── image-viewer-basic-ex-02.tsx
│ │ │ │ └── image-viewer-basic.tsx
│ │ │ └── motion
│ │ │ │ ├── image-viewer-motion-ex-01.tsx
│ │ │ │ └── image-viewer-motion.tsx
│ │ ├── like-rating
│ │ │ └── basic
│ │ │ │ ├── like-rating-basic.tsx
│ │ │ │ └── like-rating-ex-01.tsx
│ │ ├── price-format
│ │ │ ├── basic
│ │ │ │ ├── price-format-basic-ex-01.tsx
│ │ │ │ └── price-format-basic.tsx
│ │ │ └── sale
│ │ │ │ ├── price-format-sale-ex-01.tsx
│ │ │ │ ├── price-format-sale-ex-02.tsx
│ │ │ │ ├── price-format-sale-ex-03.tsx
│ │ │ │ └── price-format-sale.tsx
│ │ ├── quantity-input
│ │ │ └── basic
│ │ │ │ ├── quantity-input-basic.tsx
│ │ │ │ ├── quantity-input-ex-01.tsx
│ │ │ │ ├── quantity-input-ex-02.tsx
│ │ │ │ └── quantity-input-ex-03.tsx
│ │ ├── star-rating
│ │ │ ├── basic
│ │ │ │ ├── star-rating-basic-ex-01.tsx
│ │ │ │ ├── star-rating-basic-ex-02.tsx
│ │ │ │ ├── star-rating-basic-ex-03.tsx
│ │ │ │ └── star-rating-basic.tsx
│ │ │ └── fractions
│ │ │ │ ├── star-rating-fractions-ex-01.tsx
│ │ │ │ ├── star-rating-fractions-ex-02.tsx
│ │ │ │ ├── star-rating-fractions-ex-03.tsx
│ │ │ │ └── star-rating-fractions.tsx
│ │ ├── upvote-rating
│ │ │ ├── animated
│ │ │ │ ├── upvote-rating-animated-ex-01.tsx
│ │ │ │ ├── upvote-rating-animated-ex-02.tsx
│ │ │ │ └── upvote-rating-animated.tsx
│ │ │ └── basic
│ │ │ │ ├── upvote-rating-basic-ex-01.tsx
│ │ │ │ ├── upvote-rating-basic-ex-02.tsx
│ │ │ │ └── upvote-rating-basic.tsx
│ │ ├── variant-color-selector
│ │ │ ├── basic
│ │ │ │ ├── variant-color-selector-basic-ex-01.tsx
│ │ │ │ └── variant-color-selector-basic.tsx
│ │ │ ├── example.tsx
│ │ │ └── variant-color-selector-01.tsx
│ │ └── variant-selector
│ │ │ ├── animated
│ │ │ └── variant-selector-animated.tsx
│ │ │ ├── basic
│ │ │ ├── variant-selector-basic-ex-01.tsx
│ │ │ ├── variant-selector-basic-ex-02.tsx
│ │ │ ├── variant-selector-basic-ex-03.tsx
│ │ │ ├── variant-selector-basic-ex-04.tsx
│ │ │ ├── variant-selector-basic-ex-05.tsx
│ │ │ └── variant-selector-basic.tsx
│ │ │ ├── images
│ │ │ ├── variant-selector-images-ex-01.tsx
│ │ │ └── variant-selector-images.tsx
│ │ │ └── multiple
│ │ │ ├── variant-selector-multiple-ex-01.tsx
│ │ │ ├── variant-selector-multiple-ex-02.tsx
│ │ │ └── variant-selector-multiple.tsx
│ └── pages
│ │ └── product-01
│ │ ├── components
│ │ ├── product-info.tsx
│ │ ├── product.tsx
│ │ ├── store-header.tsx
│ │ └── store-navigation.tsx
│ │ └── page.tsx
├── docs
│ ├── code-renderer.tsx
│ ├── component-loader.tsx
│ ├── component-props-table.tsx
│ ├── copy-btn.tsx
│ ├── mdx-components.tsx
│ ├── preview
│ │ ├── component-base.tsx
│ │ ├── component-collapse.tsx
│ │ ├── component-preview-code.tsx
│ │ ├── component-preview.tsx
│ │ ├── component-source.tsx
│ │ ├── components-install.tsx
│ │ ├── page-preview-code.tsx
│ │ └── page-preview.tsx
│ ├── scroll-progress.tsx
│ ├── shared.tsx
│ └── sidebar.tsx
├── landing
│ ├── components-showcase.tsx
│ ├── footer.tsx
│ ├── header-custom-links.tsx
│ ├── hero.tsx
│ └── tech-stack.tsx
├── layout
│ ├── language-toggle.tsx
│ ├── nav.tsx
│ ├── root-toggle.tsx
│ ├── search-toggle.tsx
│ └── theme-toggle.tsx
├── links.tsx
├── magicui
│ ├── grid-pattern.tsx
│ ├── line-shadow-text.tsx
│ └── shimmer-button.tsx
├── notebook.client.tsx
├── notebook.tsx
├── shared.tsx
└── ui
│ ├── accordion.tsx
│ ├── badge.tsx
│ ├── breadcrumb.tsx
│ ├── button.tsx
│ ├── collapsible.tsx
│ ├── dropdown-menu.tsx
│ ├── icons.tsx
│ ├── input.tsx
│ ├── label.tsx
│ ├── page-header.tsx
│ ├── popover.tsx
│ ├── progress.tsx
│ ├── references.tsx
│ ├── resizable.tsx
│ ├── scroll-area.tsx
│ ├── separator.tsx
│ ├── sheet.tsx
│ ├── slider.tsx
│ ├── switch.tsx
│ ├── table.tsx
│ ├── tabs.tsx
│ └── tooltip.tsx
├── config
├── sidebar-badges.ts
├── sidebar-rename.ts
└── site.ts
├── content
├── blog
│ ├── blog-number-input.mdx
│ ├── create-animated-upvote-rating-component.mdx
│ ├── create-star-rating-component.mdx
│ └── create-star-rating-components-fractions.mdx
└── docs
│ ├── blocks
│ ├── banners.mdx
│ ├── carts.mdx
│ ├── meta.json
│ ├── product-card.mdx
│ ├── product-variants.mdx
│ └── reviews.mdx
│ ├── cli.mdx
│ ├── components
│ ├── image-carousel
│ │ ├── horizontal.mdx
│ │ └── meta.json
│ ├── image-viewer
│ │ ├── basic.mdx
│ │ ├── meta.json
│ │ └── motion.mdx
│ ├── price-format
│ │ ├── basic.mdx
│ │ ├── meta.json
│ │ └── sale.mdx
│ ├── quantity-input
│ │ ├── basic.mdx
│ │ └── meta.json
│ ├── rating-face
│ │ ├── basic.mdx
│ │ ├── gradient.mdx
│ │ └── meta.json
│ ├── rating-like
│ │ ├── like-rating.mdx
│ │ └── meta.json
│ ├── rating-star
│ │ ├── basic.mdx
│ │ ├── fractions.mdx
│ │ └── meta.json
│ ├── rating-upvote
│ │ ├── animated.mdx
│ │ ├── basic.mdx
│ │ └── meta.json
│ ├── variant-color-selector
│ │ ├── basic.mdx
│ │ └── meta.json
│ └── variant-selector
│ │ ├── basic.mdx
│ │ ├── images.mdx
│ │ ├── meta.json
│ │ └── mutliple.mdx
│ ├── index.mdx
│ ├── installation.mdx
│ ├── meta.json
│ ├── pages
│ ├── meta.json
│ └── products.mdx
│ └── test.mdx
├── eslint.config.mjs
├── hooks
├── use-auto-resize-textarea.ts
├── use-mobile.tsx
└── use-registry-counts.ts
├── lib
├── cn.ts
├── code.ts
├── fonts.ts
├── generateOGImage.tsx
├── is-active.ts
├── metadata.ts
├── shiki.ts
├── source.ts
└── utils.ts
├── next.config.mjs
├── package.json
├── pnpm-lock.yaml
├── postcss.config.js
├── public
├── cover.jpeg
├── fonts
│ ├── Geist-Medium.otf
│ └── Redaction_35-Regular.woff2
├── logo.svg
├── placeholders
│ ├── backpack.jpg
│ ├── bike-01.jpg
│ ├── camera-01.jpg
│ ├── cat-cyberpunk.webp
│ ├── cat-default.webp
│ ├── cat-steampunk.webp
│ ├── charger-01.jpg
│ ├── coffee-cups-01.jpg
│ ├── coffee-filter-01.jpg
│ ├── coffee-machine-01.jpg
│ ├── coffee-machine-02.jpg
│ ├── essential-oil-01.jpg
│ ├── family-01.jpg
│ ├── hand-cream-01.jpg
│ ├── hand-cream-02.jpg
│ ├── hand-cream-03.jpg
│ ├── hand-cream-04.jpg
│ ├── handcream-01.jpg
│ ├── headphone-1-thumb.jpg
│ ├── headphone-1.jpg
│ ├── headphone-2.jpg
│ ├── headphone-3.jpg
│ ├── headphone-4.jpg
│ ├── hotel-01.jpg
│ ├── hotel-02.jpg
│ ├── laurel-leaf.svg
│ ├── logo-01.png
│ ├── logo-02.png
│ ├── logo-03.png
│ ├── logo-04.png
│ ├── logo-05.png
│ ├── logo-06.png
│ ├── shoes-01.jpg
│ ├── shoes-02.jpg
│ ├── smartwatch-01.jpg
│ ├── smartwatch-02.jpg
│ ├── speaker-01.jpg
│ ├── speaker-02.jpg
│ ├── speaker-03.jpg
│ ├── speaker-04.jpg
│ ├── speaker-05.jpg
│ ├── tablet-01.jpg
│ ├── user-01.jpg
│ ├── user-02.jpg
│ ├── user-03.jpg
│ ├── user-04.jpg
│ ├── user-05.jpg
│ ├── user-06.jpg
│ └── user-07.jpg
├── r
│ ├── banner-01-block.json
│ ├── banner-02-block.json
│ ├── banner-03-block.json
│ ├── banner-04-block.json
│ ├── banner-05-block.json
│ ├── banner-06-block.json
│ ├── banner-07-block.json
│ ├── banner-08-block.json
│ ├── banner-09-block.json
│ ├── banner-10-block.json
│ ├── banner-11-block.json
│ ├── banner-12-block.json
│ ├── cart-01-block-ex.json
│ ├── cart-01-block.json
│ ├── example-block.json
│ ├── face-rating-basic-ex-01.json
│ ├── face-rating-basic-ex-02.json
│ ├── face-rating-basic-ex-03.json
│ ├── face-rating-basic.json
│ ├── face-rating-gradient-ex-01.json
│ ├── face-rating-gradient.json
│ ├── image-carousel-basic-ex-01.json
│ ├── image-carousel-basic-ex-02.json
│ ├── image-carousel-basic-ex-03.json
│ ├── image-carousel-basic-ex-04.json
│ ├── image-carousel-basic.json
│ ├── image-viewer-basic-ex-01.json
│ ├── image-viewer-basic-ex-02.json
│ ├── image-viewer-basic.json
│ ├── image-viewer-motion-ex-01.json
│ ├── image-viewer-motion.json
│ ├── like-rating-basic-ex-01.json
│ ├── like-rating-basic.json
│ ├── price-format-basic-ex-01.json
│ ├── price-format-basic.json
│ ├── price-format-sale-ex-01.json
│ ├── price-format-sale-ex-02.json
│ ├── price-format-sale-ex-03.json
│ ├── price-format-sale.json
│ ├── product-01-page.json
│ ├── product-card-01-block.json
│ ├── product-card-02-block.json
│ ├── product-card-03-block.json
│ ├── product-card-04-block.json
│ ├── product-card-05-block.json
│ ├── product-card-06-block.json
│ ├── product-card-07-block.json
│ ├── product-card-08-block.json
│ ├── product-card-09-block.json
│ ├── product-card-10-block.json
│ ├── product-card-11-block.json
│ ├── product-card-12-block.json
│ ├── product-card-13-block.json
│ ├── product-variant-01-block-ex.json
│ ├── product-variant-01-block.json
│ ├── product-variant-02-block-ex.json
│ ├── product-variant-02-block.json
│ ├── product-variant-03-block-ex.json
│ ├── product-variant-03-block.json
│ ├── product-variant-04-block-ex.json
│ ├── product-variant-04-block.json
│ ├── product-variant-05-block-ex.json
│ ├── product-variant-05-block.json
│ ├── quantity-input-basic-ex-01.json
│ ├── quantity-input-basic-ex-02.json
│ ├── quantity-input-basic-ex-03.json
│ ├── quantity-input-basic.json
│ ├── rating-upvote-animated.json
│ ├── rating-upvote-basic-ex-01.json
│ ├── rating-upvote-basic.json
│ ├── review-01-block.json
│ ├── review-02-block.json
│ ├── review-03-block.json
│ ├── review-04-block.json
│ ├── review-05-block.json
│ ├── review-06-block.json
│ ├── review-07-block.json
│ ├── review-08-block.json
│ ├── review-09-block.json
│ ├── review-10-block.json
│ ├── star-rating-basic-ex-01.json
│ ├── star-rating-basic-ex-02.json
│ ├── star-rating-basic-ex-03.json
│ ├── star-rating-basic.json
│ ├── star-rating-fractions-ex-01.json
│ ├── star-rating-fractions-ex-02.json
│ ├── star-rating-fractions-ex-03.json
│ ├── star-rating-fractions.json
│ ├── upvote-rating-animated-ex-01.json
│ ├── upvote-rating-animated-ex-02.json
│ ├── upvote-rating-animated.json
│ ├── upvote-rating-basic-ex-01.json
│ ├── upvote-rating-basic-ex-02.json
│ ├── upvote-rating-basic.json
│ ├── utils.json
│ ├── variant-color-selector-basic-ex-01.json
│ ├── variant-color-selector-basic.json
│ ├── variant-selector-basic-ex-01.json
│ ├── variant-selector-basic-ex-02.json
│ ├── variant-selector-basic-ex-03.json
│ ├── variant-selector-basic-ex-04.json
│ ├── variant-selector-basic-ex-05.json
│ ├── variant-selector-basic.json
│ ├── variant-selector-images-ex-01.json
│ ├── variant-selector-images.json
│ ├── variant-selector-multiple-ex-01.json
│ ├── variant-selector-multiple-ex-02.json
│ └── variant-selector-multiple.json
├── registry.json
└── stackzero_commerce_ui_logo.svg
├── registry
├── index.ts
├── registry-blocks.ts
├── registry-components.ts
├── registry-examples.ts
├── registry-hooks.ts
├── registry-lib.ts
├── registry-pages.ts
└── schema.ts
├── scripts
├── build-registry.ts
└── sort-registry.ts
├── source.config.ts
├── tsconfig.json
└── types
└── component.ts
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # deps
2 | /node_modules
3 |
4 | # generated content
5 | .contentlayer
6 | .content-collections
7 | .source
8 |
9 | # test & build
10 | /coverage
11 | /.next/
12 | /out/
13 | /build
14 | *.tsbuildinfo
15 |
16 | # misc
17 | .DS_Store
18 | *.pem
19 | /.pnp
20 | .pnp.js
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | # others
26 | .env*.local
27 | .vercel
28 | next-env.d.ts
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 22.13.1
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # deps
2 | /node_modules
3 |
4 | # generated content
5 | .contentlayer
6 | .content-collections
7 | .source
8 |
9 | # test & build
10 | /coverage
11 | /.next/
12 | /out/
13 | /build
14 | *.tsbuildinfo
15 |
16 | # misc
17 | .DS_Store
18 | *.pem
19 | /.pnp
20 | .pnp.js
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | # others
26 | .env*.local
27 | .vercel
28 | next-env.d.ts
29 |
30 | pnpm-lock.yaml
31 | content
32 |
33 | # registry
34 | public/r
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "semi": true,
4 | "tabWidth": 2,
5 | "singleQuote": false,
6 | "jsxSingleQuote": false,
7 | "plugins": ["prettier-plugin-tailwindcss"]
8 | }
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Stackzero Labs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/(home)/blog/page.tsx:
--------------------------------------------------------------------------------
1 | import { blog } from "@/lib/source";
2 | import Link from "next/link";
3 |
4 | export default function Page(): React.ReactElement {
5 | const posts = [...blog.getPages()].sort(
6 | (a, b) =>
7 | new Date(b.data.date ?? b.file.name).getTime() -
8 | new Date(a.data.date ?? a.file.name).getTime()
9 | );
10 |
11 | return (
12 |
13 |
14 | {posts.map((post) => (
15 |
20 |
{post.data.title}
21 |
22 | {post.data.description}
23 |
24 |
25 |
26 | {new Date(post.data.date ?? post.file.name).toDateString()}
27 |
28 |
29 |
30 | {post.data.tags?.map((tag) => (
31 |
35 | {tag}
36 |
37 | ))}
38 |
39 |
40 | ))}
41 |
42 |
43 | );
44 | }
45 |
--------------------------------------------------------------------------------
/app/(home)/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from "react";
2 | import { HomeLayout } from "fumadocs-ui/layouts/home";
3 | import { baseOptions } from "@/app/layout.config";
4 | import Footer from "@/components/landing/footer";
5 |
6 | export default function Layout({ children }: { children: ReactNode }) {
7 | return (
8 | <>
9 |
10 | {children}
11 |
12 |
13 |
14 |
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/app/(home)/page.tsx:
--------------------------------------------------------------------------------
1 | import ComponentsShowcase from "@/components/landing/components-showcase";
2 | import { HeroSection } from "@/components/landing/hero";
3 | import { GridPattern } from "@/components/magicui/grid-pattern";
4 | import { Button } from "@/components/ui/button";
5 | import { cn } from "@/lib/utils";
6 | import { ArrowRight } from "lucide-react";
7 | import Link from "next/link";
8 |
9 | export default function HomePage() {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
28 |
29 | And many more
30 |
31 |
32 |
33 |
43 |
44 |
45 | 100% free and Open Source
46 |
47 |
48 |
49 |
50 |
51 |
52 | );
53 | }
54 |
--------------------------------------------------------------------------------
/app/api/search/route.ts:
--------------------------------------------------------------------------------
1 | // import { source } from '@/lib/source';
2 | // import { createFromSource } from 'fumadocs-core/search/server';
3 |
4 | // export const { GET } = createFromSource(source);
5 |
6 | import { source } from "@/lib/source";
7 | import { createFromSource } from "fumadocs-core/search/server";
8 |
9 | // it should be cached forever
10 | export const revalidate = false;
11 |
12 | export const { staticGET: GET } = createFromSource(source);
13 |
--------------------------------------------------------------------------------
/app/blog-og/[...slug]/route.tsx:
--------------------------------------------------------------------------------
1 | // import { generateOGImage } from "fumadocs-ui/og";
2 | import { generateOGImage } from "@/lib/generateOGImage";
3 | import { metadataImage, metadataImageBlog } from "@/lib/metadata";
4 |
5 | export const GET = metadataImageBlog.createAPI(async (page) => {
6 | return generateOGImage({
7 | // description: page.data.description,
8 | site: "stackzero/commerce-ui",
9 | title: page.data.title,
10 | primaryColor: "#8940ff34",
11 | primaryTextColor: "rgb(240, 228, 247)",
12 | });
13 | });
14 |
15 | export function generateStaticParams() {
16 | return metadataImageBlog.generateParams();
17 | }
18 |
--------------------------------------------------------------------------------
/app/docs-banners.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from "@/components/ui/button";
2 | import { Banner } from "fumadocs-ui/components/banner";
3 | import Link from "next/link";
4 |
5 | export const DocsBanners = () => {
6 | return (
7 | <>
8 |
9 |
10 |
11 |
12 |
13 | +13 New Product Cards Released!
14 |
17 |
18 | >
19 | );
20 | };
21 |
--------------------------------------------------------------------------------
/app/docs-og/[...slug]/route.tsx:
--------------------------------------------------------------------------------
1 | // import { generateOGImage } from "fumadocs-ui/og";
2 | import { generateOGImage } from "@/lib/generateOGImage";
3 | import { metadataImage } from "@/lib/metadata";
4 |
5 | export const GET = metadataImage.createAPI(async (page) => {
6 | return generateOGImage({
7 | description: page.data.description,
8 | site: "stackzero/commerce-ui",
9 | title: page.data.title,
10 | primaryColor: "#8940ff34",
11 | primaryTextColor: "rgb(240, 228, 247)",
12 | });
13 | });
14 |
15 | export function generateStaticParams() {
16 | return metadataImage.generateParams();
17 | }
18 |
--------------------------------------------------------------------------------
/app/docs/layout.tsx:
--------------------------------------------------------------------------------
1 | // import { DocsLayout, type DocsLayoutProps } from "fumadocs-ui/layouts/notebook";
2 | import type { ReactNode } from "react";
3 | import { baseOptions, linkItems } from "@/app/layout.config";
4 | import { source } from "@/lib/source";
5 | import { DocsLayout, DocsLayoutProps } from "@/components/notebook";
6 |
7 | const docsOptions: DocsLayoutProps = {
8 | ...baseOptions,
9 | links: linkItems,
10 | tree: source.pageTree,
11 | i18n: false,
12 | };
13 |
14 | export default function Layout({ children }: { children: ReactNode }) {
15 | return {children};
16 | }
17 |
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/app/favicon.ico
--------------------------------------------------------------------------------
/app/fonts/GeistMonoVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/app/fonts/GeistMonoVF.woff
--------------------------------------------------------------------------------
/app/fonts/GeistVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/app/fonts/GeistVF.woff
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils";
2 | import { RootProvider } from "fumadocs-ui/provider";
3 | import { GeistSans } from "geist/font/sans";
4 | import { Metadata } from "next";
5 | import localFont from "next/font/local";
6 | import Script from "next/script";
7 | import type { ReactNode } from "react";
8 | import { DocsBanners } from "./docs-banners";
9 | import "./global.css";
10 |
11 | const geistSans = localFont({
12 | src: "./fonts/GeistVF.woff",
13 | variable: "--font-geist-sans",
14 | weight: "100 900",
15 | });
16 |
17 | export default function Layout({ children }: { children: ReactNode }) {
18 | const isDev = process.env.NODE_ENV === "development";
19 |
20 | return (
21 |
26 | {!isDev ? (
27 |
32 | ) : null}
33 |
40 |
47 |
48 | {children}
49 |
50 |
51 |
52 | );
53 | }
54 |
55 | export const metadata: Metadata = {
56 | description:
57 | "The Commerce UI is a set of components and hooks that can be used to build a custom storefront for your commerce site.",
58 | metadataBase: new URL("https://ui.stackzero.co"),
59 | title: "Commerce UI",
60 | };
61 |
--------------------------------------------------------------------------------
/app/opengraph-image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/app/opengraph-image.jpg
--------------------------------------------------------------------------------
/app/opengraph-image.txt:
--------------------------------------------------------------------------------
1 | stackzero/commerce-ui
2 | stackzero/commerce-ui is a collection of components to build e-commerce sites and commerce apps.
--------------------------------------------------------------------------------
/app/preview/[[...slug]]/page.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentLoader } from "@/components/docs/component-loader";
2 | import { registry } from "@/registry";
3 | import { notFound } from "next/navigation";
4 |
5 | export default async function PreviewPage({
6 | params,
7 | }: {
8 | params: Promise<{ slug: string[] }>;
9 | }) {
10 | const { slug } = await params;
11 | if (!slug.length) return notFound();
12 | const componentName = slug.join("/");
13 |
14 | try {
15 | const isPage = componentName.includes("page");
16 | return isPage ? (
17 |
26 | ) : (
27 |
28 |
33 |
34 | );
35 | } catch (error) {
36 | console.error("error", error);
37 | return notFound();
38 | }
39 | }
40 |
41 | export async function generateStaticParams() {
42 | const allComponents = registry.map((component) => {
43 | return { slug: [component.name] };
44 | });
45 |
46 | return allComponents;
47 | }
48 |
--------------------------------------------------------------------------------
/app/sitemap.ts:
--------------------------------------------------------------------------------
1 | import { siteConfig } from "@/config/site";
2 | import { source } from "@/lib/source";
3 | import type { MetadataRoute } from "next";
4 |
5 | export const revalidate = false;
6 |
7 | export default function sitemap(): MetadataRoute.Sitemap {
8 | const url = (path: string): string =>
9 | new URL(path, siteConfig.url).toString();
10 |
11 | return [
12 | {
13 | changeFrequency: "monthly",
14 | priority: 1,
15 | url: url("/"),
16 | },
17 | {
18 | changeFrequency: "monthly",
19 | priority: 0.8,
20 | url: url("/docs"),
21 | },
22 |
23 | ...source.getPages().map((page) => ({
24 | changeFrequency: "weekly",
25 | lastModified: page.data.lastModified
26 | ? new Date(page.data.lastModified)
27 | : undefined,
28 | priority: 0.5,
29 | url: url(page.url),
30 | })),
31 | ];
32 | }
33 |
--------------------------------------------------------------------------------
/app/twitter-image-alt.txt:
--------------------------------------------------------------------------------
1 | stackzero/commerce-ui
2 | stackzero/commerce-ui is a collection of components to build e-commerce sites and commerce apps.
--------------------------------------------------------------------------------
/app/twitter-image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/app/twitter-image.jpg
--------------------------------------------------------------------------------
/cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "aliases": {
3 | "cn": "./lib/utils.ts",
4 | "componentsDir": "./components",
5 | "uiDir": "./components/ui",
6 | "libDir": "./lib"
7 | }
8 | }
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.js",
8 | "css": "app/global.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils",
16 | "ui": "@/components/ui",
17 | "lib": "@/lib",
18 | "hooks": "@/hooks"
19 | },
20 | "iconLibrary": "lucide"
21 | }
22 |
--------------------------------------------------------------------------------
/components/commerce-ui/blocks/product-cards/product-cards-01.tsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/components/commerce-ui/blocks/product-cards/product-cards-01.tsx
--------------------------------------------------------------------------------
/components/commerce-ui/blocks/product-cards/product-cards-03.tsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/components/commerce-ui/blocks/product-cards/product-cards-03.tsx
--------------------------------------------------------------------------------
/components/commerce-ui/blocks/product-cards/product-cards-04.tsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/components/commerce-ui/blocks/product-cards/product-cards-04.tsx
--------------------------------------------------------------------------------
/components/commerce-ui/blocks/product-cards/product-cards-10.tsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/components/commerce-ui/blocks/product-cards/product-cards-10.tsx
--------------------------------------------------------------------------------
/components/commerce-ui/blocks/product-cards/product-cards-11.tsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/components/commerce-ui/blocks/product-cards/product-cards-11.tsx
--------------------------------------------------------------------------------
/components/commerce-ui/blocks/product-cards/product-cards-12.tsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/components/commerce-ui/blocks/product-cards/product-cards-12.tsx
--------------------------------------------------------------------------------
/components/commerce-ui/blocks/reviews/review-01.tsx:
--------------------------------------------------------------------------------
1 | import StarRating from "@/components/commerce-ui/components/star-rating/basic/star-rating-basic";
2 | interface Review_01Props {
3 | rating?: number;
4 | reviewDate?: string;
5 | reviewText?: string;
6 | avatarUrl?: string;
7 | reviewerName?: string;
8 | reviewerTitle?: string;
9 | }
10 |
11 | function Review_01({
12 | avatarUrl = "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/user-07.jpg",
13 | rating = 4.0,
14 | reviewDate = "Feb 12, 2025",
15 | reviewerName = "Adam Smith",
16 | reviewerTitle = "CEO ACME Inc.",
17 | reviewText = "The product is great, I'm very satisfied with the quality and the price. I would recommend it to anyone looking for a good product or service.",
18 | }: Review_01Props = {}) {
19 | return (
20 | <>
21 |
22 |
23 |
24 |
25 |
({rating}/5)
26 |
27 |
28 |
{reviewDate}
29 |
30 |
31 |
34 |
35 |
36 |

41 |
42 |
{reviewerName}
43 |
44 | {reviewerTitle}
45 |
46 |
47 |
48 |
49 | >
50 | );
51 | }
52 |
53 | export default Review_01;
54 | export type { Review_01Props };
55 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/face-rating/basic/face-rating-basic-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import FaceRatingBasic from "@/components/commerce-ui/components/face-rating/basic/face-rating-basic";
4 | import { useState } from "react";
5 |
6 | export default function FaceRating_01_Ex_01() {
7 | const [rating, setRating] = useState(3);
8 | return (
9 |
10 |
11 |
Rating: {rating}
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/face-rating/basic/face-rating-basic-ex-02.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import FaceRatingBasic from "@/components/commerce-ui/components/face-rating/basic/face-rating-basic";
4 | import { useState } from "react";
5 |
6 | export default function FaceRating_01_Ex_02() {
7 | const [rating, setRating] = useState(3);
8 | return (
9 |
10 |
How do you feel about this product?
11 |
12 |
Rating: {rating}
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/face-rating/gradient/face-rating-gradient-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import FaceRatingGradient from "@/components/commerce-ui/components/face-rating/gradient/face-rating-gradient";
4 | import { useState } from "react";
5 |
6 | export default function FaceRating_Gradient_Ex_01() {
7 | const [rating, setRating] = useState(3);
8 | return (
9 |
10 |
11 |
Rating: {rating}
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/image-carousel/basic/image-carousel-basic-ex-01.tsx:
--------------------------------------------------------------------------------
1 | import ImageCarouselBasic, {
2 | CarouselImages,
3 | } from "@/components/commerce-ui/components/image-carousel/basic/image-carousel-basic";
4 |
5 | const images: CarouselImages = [
6 | {
7 | title: "Speaker 1",
8 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-02.jpg",
9 | },
10 | {
11 | title: "Headphone 2",
12 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-03.jpg",
13 | },
14 | {
15 | title: "Headphone 3",
16 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-04.jpg",
17 | },
18 | ];
19 |
20 | export default function ImageCarousel_Basic_Ex_01() {
21 | return ;
22 | }
23 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/image-carousel/basic/image-carousel-basic-ex-02.tsx:
--------------------------------------------------------------------------------
1 | import ImageCarouselBasic, {
2 | CarouselImages,
3 | } from "@/components/commerce-ui/components/image-carousel/basic/image-carousel-basic";
4 |
5 | const images: CarouselImages = [
6 | {
7 | title: "Coffee Machine 1",
8 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/coffee-machine-01.jpg",
9 | },
10 | {
11 | title: "Coffee Machine 2",
12 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/coffee-machine-02.jpg",
13 | },
14 | {
15 | title: "Coffee Filter",
16 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/coffee-filter-01.jpg",
17 | },
18 | {
19 | title: "Coffee Cups",
20 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/coffee-cups-01.jpg",
21 | },
22 | ];
23 |
24 | export default function ImageCarousel_Basic_Ex_02() {
25 | return (
26 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/image-carousel/basic/image-carousel-basic-ex-03.tsx:
--------------------------------------------------------------------------------
1 | import ImageCarouselBasic, {
2 | CarouselImages,
3 | } from "@/components/commerce-ui/components/image-carousel/basic/image-carousel-basic";
4 |
5 | const images: CarouselImages = [
6 | {
7 | title: "Headphone 1",
8 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg",
9 | },
10 | {
11 | title: "Headphone 2",
12 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-2.jpg",
13 | },
14 | {
15 | title: "Headphone 3",
16 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-3.jpg",
17 | },
18 | ];
19 |
20 | export default function ImageCarousel_Basic_Ex_03() {
21 | return (
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/image-carousel/basic/image-carousel-basic-ex-04.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import ImageCarouselBasic, {
5 | CarouselImages,
6 | } from "@/components/commerce-ui/components/image-carousel/basic/image-carousel-basic";
7 |
8 | const images: CarouselImages = [
9 | {
10 | title: "Speaker 1",
11 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-02.jpg",
12 | },
13 | {
14 | title: "Speaker 2",
15 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-03.jpg",
16 | },
17 | {
18 | title: "Speaker 3",
19 | url: "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-04.jpg",
20 | },
21 | ];
22 |
23 | export default function ImageCarousel_Basic_Ex_04() {
24 | const [selectedIndex, setSelectedIndex] = useState(0);
25 |
26 | return (
27 |
28 |
29 |
30 |
36 | Current Slide: {selectedIndex + 1}
37 |
45 |
46 |
52 |
53 |
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/image-viewer/basic/image-viewer-basic-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import ImageViewer from "@/components/commerce-ui/components/image-viewer/basic/image-viewer-basic";
3 |
4 | const EXAMPLE_IMAGE_URL =
5 | "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg";
6 | const EXAMPLE_THUMBNAIL_URL =
7 | "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg";
8 |
9 | export default function ImageViewer_Basic_Ex_01() {
10 | return (
11 |
12 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/image-viewer/basic/image-viewer-basic-ex-02.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import ImageViewer from "@/components/commerce-ui/components/image-viewer/basic/image-viewer-basic";
3 |
4 | const EXAMPLE_IMAGE_URL =
5 | "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-01.jpg";
6 | const EXAMPLE_THUMBNAIL_URL =
7 | "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-01.jpg";
8 |
9 | export default function ImageViewer_Basic_Ex_02() {
10 | return (
11 |
12 |
13 |
14 | {/* Tall thumbnail - 300px height */}
15 |
16 |
Tall (300px)
17 |
23 |
24 |
25 | {/* Medium thumbnail - 200px height */}
26 |
27 |
Medium (200px)
28 |
34 |
35 |
36 | {/* Small thumbnail - 100px height */}
37 |
38 |
Small (100px)
39 |
45 |
46 |
47 |
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/image-viewer/motion/image-viewer-motion-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import ImageViewer from "@/components/commerce-ui/components/image-viewer/motion/image-viewer-motion";
3 |
4 | const EXAMPLE_IMAGE_URL =
5 | "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg";
6 | const EXAMPLE_THUMBNAIL_URL =
7 | "https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg";
8 |
9 | export default function ImageViewer_Basic_Ex_01() {
10 | return (
11 |
12 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/like-rating/basic/like-rating-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import LikeRatingBasic from "@/components/commerce-ui/components/like-rating/basic/like-rating-basic";
4 | import { useState } from "react";
5 |
6 | export default function LikeRating_Basic_Ex_01() {
7 | const [likes, setLikes] = useState(1100);
8 | const [dislikes, setDislikes] = useState(260);
9 | const [isLiked, setIsLiked] = useState(true);
10 | const [isDisliked, setIsDisliked] = useState(false);
11 |
12 | return (
13 |
14 | {
20 | setLikes(newState.likes);
21 | setDislikes(newState.dislikes);
22 | setIsLiked(newState.isLiked);
23 | setIsDisliked(newState.isDisliked);
24 | }}
25 | />
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/price-format/basic/price-format-basic-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import PriceFormat_Basic from "@/components/commerce-ui/components/price-format/basic/price-format-basic";
4 |
5 | export default function PriceFormat_Basic_Ex_01() {
6 | return (
7 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/price-format/basic/price-format-basic.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { NumericFormat } from "react-number-format";
5 |
6 | interface PriceFormat_BasicProps extends React.HTMLAttributes {
7 | value: number;
8 | prefix?: string;
9 | thousandSeparator?: string;
10 | decimalSeparator?: string;
11 | decimalScale?: number;
12 | }
13 |
14 | const PriceFormat_Basic: React.FC = ({
15 | className,
16 | decimalScale = 2,
17 | decimalSeparator = ",",
18 | prefix = "$",
19 | thousandSeparator = ".",
20 | value,
21 | }) => {
22 | return (
23 |
32 | );
33 | };
34 |
35 | export default PriceFormat_Basic;
36 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/price-format/sale/price-format-sale-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import PriceFormat_Sale from "@/components/commerce-ui/components/price-format/sale/price-format-sale";
4 |
5 | export default function PriceFormat_Sale_Ex_01() {
6 | return (
7 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/price-format/sale/price-format-sale-ex-02.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import PriceFormat_Sale from "@/components/commerce-ui/components/price-format/sale/price-format-sale";
4 |
5 | export default function PriceFormat_Sale_Ex_02() {
6 | return (
7 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/price-format/sale/price-format-sale-ex-03.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import PriceFormat_Sale from "@/components/commerce-ui/components/price-format/sale/price-format-sale";
4 |
5 | export default function PriceFormat_Sale_Ex_03() {
6 | return (
7 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/quantity-input/basic/quantity-input-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import QuantityInputBasic from "@/components/commerce-ui/components/quantity-input/basic/quantity-input-basic";
5 |
6 | export default function QuantityInput_Basic_Ex_01() {
7 | const [quantity, setQuantity] = useState(1);
8 |
9 | const handleQuantityChange = (newQuantity: number) => {
10 | setQuantity(newQuantity);
11 | };
12 |
13 | return (
14 | <>
15 |
16 | >
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/quantity-input/basic/quantity-input-ex-02.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import QuantityInputBasic from "@/components/commerce-ui/components/quantity-input/basic/quantity-input-basic";
5 |
6 | export default function QuantityInput_Basic_Ex_02() {
7 | const [quantity, setQuantity] = useState(1);
8 |
9 | const handleQuantityChange = (newQuantity: number) => {
10 | setQuantity(newQuantity);
11 | };
12 |
13 | return (
14 | <>
15 |
21 | >
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/quantity-input/basic/quantity-input-ex-03.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import QuantityInputBasic from "@/components/commerce-ui/components/quantity-input/basic/quantity-input-basic";
5 |
6 | export default function QuantityInput_Basic_Ex_03() {
7 | const [quantity, setQuantity] = useState(1);
8 |
9 | const handleQuantityChange = (newQuantity: number) => {
10 | setQuantity(newQuantity);
11 | };
12 |
13 | return (
14 | <>
15 |
22 | >
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/star-rating/basic/star-rating-basic-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import StarRatingBasic from "@/components/commerce-ui/components/star-rating/basic/star-rating-basic";
4 | import { useState } from "react";
5 |
6 | export default function StarRating_Basic_Ex_01() {
7 | const [rating, setRating] = useState(3);
8 | return (
9 |
10 |
11 |
({rating})
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/star-rating/basic/star-rating-basic-ex-02.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import StarRatingBasic from "@/components/commerce-ui/components/star-rating/basic/star-rating-basic";
4 | import { useState } from "react";
5 |
6 | export default function StarRating_Basic_Ex_01() {
7 | const [rating, setRating] = useState(7);
8 | return (
9 |
10 |
11 |
({rating})
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/star-rating/basic/star-rating-basic-ex-03.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import StarRatingBasic from "@/components/commerce-ui/components/star-rating/basic/star-rating-basic";
4 | import { useState } from "react";
5 |
6 | export default function StarRating_Basic_Ex_01() {
7 | const [rating, setRating] = useState(7);
8 | return (
9 |
10 |
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/star-rating/fractions/star-rating-fractions-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import StarRatingFractions from "@/components/commerce-ui/components/star-rating/fractions/star-rating-fractions";
4 | import { useState } from "react";
5 |
6 | export default function StarRating_Fractions_Ex_01() {
7 | const [rating, setRating] = useState(4.3);
8 | return (
9 |
10 |
11 |
({rating})
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/star-rating/fractions/star-rating-fractions-ex-02.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import StarRatingFractions from "@/components/commerce-ui/components/star-rating/fractions/star-rating-fractions";
4 |
5 | export default function StarRating_Fractions_Ex_02() {
6 | return (
7 |
8 |
12 |
13 |
17 |
18 |
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/star-rating/fractions/star-rating-fractions-ex-03.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import StarRatingFractions from "@/components/commerce-ui/components/star-rating/fractions/star-rating-fractions";
4 | import { useState } from "react";
5 |
6 | export default function StarRating_Fractions_Ex_02() {
7 | const [rating, setRating] = useState(4.3);
8 | return (
9 |
10 |
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/upvote-rating/animated/upvote-rating-animated-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import UpvoteRating_Animated from "@/components/commerce-ui/components/upvote-rating/animated/upvote-rating-animated";
5 |
6 | export default function UpvoteRating_Animated_Ex_01() {
7 | const [upvotes, setUpvotes] = useState(100);
8 | const [downvotes, setDownvotes] = useState(20);
9 | const [upvoted, setUpvoted] = useState(false);
10 | const [downvoted, setDownvoted] = useState(false);
11 |
12 | return (
13 |
14 | {
20 | setUpvotes(newState.upvotes);
21 | setDownvotes(newState.downvotes);
22 | setUpvoted(newState.upvoted);
23 | setDownvoted(newState.downvoted);
24 | }}
25 | />
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/upvote-rating/animated/upvote-rating-animated-ex-02.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import UpvoteRating_Animated from "@/components/commerce-ui/components/upvote-rating/animated/upvote-rating-animated";
5 |
6 | export default function UpvoteRating_Animated_Ex_02() {
7 | const [upvotes, setUpvotes] = useState(100);
8 | const [downvotes, setDownvotes] = useState(20);
9 | const [upvoted, setUpvoted] = useState(false);
10 | const [downvoted, setDownvoted] = useState(false);
11 |
12 | return (
13 |
14 | {
20 | setUpvotes(newState.upvotes);
21 | setDownvotes(newState.downvotes);
22 | setUpvoted(newState.upvoted);
23 | setDownvoted(newState.downvoted);
24 | }}
25 | upvoteIncrement={15}
26 | downvoteIncrement={15}
27 | />
28 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/upvote-rating/basic/upvote-rating-basic-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import UpvoteRating_Basic from "@/components/commerce-ui/components/upvote-rating/basic/upvote-rating-basic";
5 |
6 | export default function UpvoteRating_Basic_Ex_01() {
7 | const [upvotes, setUpvotes] = useState(100);
8 | const [downvotes, setDownvotes] = useState(20);
9 | const [upvoted, setUpvoted] = useState(false);
10 | const [downvoted, setDownvoted] = useState(false);
11 |
12 | return (
13 |
14 | {
20 | setUpvotes(newState.upvotes);
21 | setDownvotes(newState.downvotes);
22 | setUpvoted(newState.upvoted);
23 | setDownvoted(newState.downvoted);
24 | }}
25 | />
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/upvote-rating/basic/upvote-rating-basic-ex-02.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import UpvoteRating_Basic from "@/components/commerce-ui/components/upvote-rating/basic/upvote-rating-basic";
5 |
6 | export default function UpvoteRating_Basic_Ex_02() {
7 | const [upvotes, setUpvotes] = useState(100);
8 | const [downvotes, setDownvotes] = useState(20);
9 | const [upvoted, setUpvoted] = useState(false);
10 | const [downvoted, setDownvoted] = useState(false);
11 |
12 | return (
13 |
14 | {
20 | setUpvotes(newState.upvotes);
21 | setDownvotes(newState.downvotes);
22 | setUpvoted(newState.upvoted);
23 | setDownvoted(newState.downvoted);
24 | }}
25 | upvoteIncrement={15}
26 | downvoteIncrement={15}
27 | />
28 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/variant-color-selector/basic/variant-color-selector-basic-ex-01.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import VariantColorSelectorBasic, {
3 | ColorVariantItem,
4 | } from "./variant-color-selector-basic";
5 |
6 | const variants: ColorVariantItem[] = [
7 | { color: "#000000", id: "color-black", label: "Black", value: "black" },
8 | { color: "#FFFFFF", id: "color-white", label: "White", value: "white" },
9 | { color: "#FF0000", id: "color-red", label: "Red", value: "red" },
10 | { color: "#0000FF", id: "color-blue", label: "Blue", value: "blue" },
11 | { color: "#00FF00", id: "color-green", label: "Green", value: "green" },
12 | { color: "#FFFF00", id: "color-yellow", label: "Yellow", value: "yellow" },
13 | { color: "#800080", id: "color-purple", label: "Purple", value: "purple" },
14 | ];
15 |
16 | export default function VariantColorSelectorBasicExample() {
17 | const [selectedColor, setSelectedColor] = React.useState("black");
18 |
19 | return (
20 |
21 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/variant-selector/basic/variant-selector-basic-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import VariantSelectorBasic, {
5 | VariantItem,
6 | } from "@/components/commerce-ui/components/variant-selector/basic/variant-selector-basic";
7 |
8 | const variants: VariantItem[] = [
9 | { id: "variant-xxs", label: "XXS", value: "variant-xxs" },
10 | { id: "variant-xs", label: "XS", value: "variant-xs" },
11 | { id: "variant-s", label: "S", value: "variant-s" },
12 | { id: "variant-m", label: "M", value: "variant-m" },
13 | { id: "variant-l", label: "L", value: "variant-l" },
14 | { id: "variant-xl", label: "XL", value: "variant-xl" },
15 | { id: "variant-xxl", label: "XXL", value: "variant-xxl" },
16 | ];
17 |
18 | export default function VariantSelector_Basic_Ex_01() {
19 | const [selectedVariant, setSelectedVariant] = React.useState("variant-m");
20 |
21 | return (
22 |
23 |
31 |
32 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/variant-selector/basic/variant-selector-basic-ex-02.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import VariantSelectorBasic, {
5 | VariantItem,
6 | } from "@/components/commerce-ui/components/variant-selector/basic/variant-selector-basic";
7 |
8 | const variants: VariantItem[] = [
9 | { id: "variant-xxs", label: "XXS", value: "variant-xxs" },
10 | { id: "variant-xs", label: "XS", value: "variant-xs" },
11 | { id: "variant-s", label: "S", value: "variant-s" },
12 | { id: "variant-m", label: "M", value: "variant-m" },
13 | { id: "variant-l", label: "L", value: "variant-l" },
14 | { id: "variant-xl", label: "XL", value: "variant-xl" },
15 | { id: "variant-xxl", label: "XXL", value: "variant-xxl" },
16 | ];
17 |
18 | export default function VariantSelector_Basic_Ex_02() {
19 | const [selectedVariant1, setSelectedVariant1] = React.useState("variant-m");
20 | const [selectedVariant2, setSelectedVariant2] = React.useState("variant-m");
21 |
22 | return (
23 |
24 |
33 |
42 |
43 | );
44 | }
45 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/variant-selector/basic/variant-selector-basic-ex-04.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import VariantSelectorBasic, {
5 | VariantItem,
6 | } from "@/components/commerce-ui/components/variant-selector/basic/variant-selector-basic";
7 |
8 | // Example size variants
9 | const sizeVariants: VariantItem[] = [
10 | { id: "size-xs", label: "XS", value: "size-xs" },
11 | { id: "size-s", label: "S", value: "size-s" },
12 | { id: "size-m", label: "M", value: "size-m" },
13 | { id: "size-l", label: "L", value: "size-l" },
14 | { id: "size-xl", label: "XL", value: "size-xl" },
15 | ];
16 |
17 | export default function VariantSelector_Basic_Ex_04() {
18 | const [selectedSize, setSelectedSize] = React.useState("size-m");
19 |
20 | return (
21 |
22 |
23 |
24 | Pill Style
25 |
26 |
27 | Rounded pill-shaped variant buttons with custom active state using
28 | data-state
29 |
30 |
31 |
32 |
35 |
44 |
45 |
46 |
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/variant-selector/basic/variant-selector-basic.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | export interface VariantItem {
9 | id: string;
10 | value: string;
11 | label: string;
12 | disabled?: boolean;
13 | }
14 |
15 | interface VariantSelectorBasicProps {
16 | value: string;
17 | onValueChange: (value: string) => void;
18 | variants: VariantItem[];
19 | className?: string;
20 | itemClassName?: string;
21 | labelClassName?: string;
22 | // selectedClassName is being removed as redundant
23 | }
24 |
25 | const VariantSelectorBasic = ({
26 | className,
27 | itemClassName,
28 | labelClassName,
29 | onValueChange,
30 | value,
31 | variants,
32 | }: VariantSelectorBasicProps) => {
33 | return (
34 |
39 | {variants.map((variant) => (
40 |
41 |
55 |
56 | {variant.label}
57 |
58 |
59 |
60 | ))}
61 |
62 | );
63 | };
64 |
65 | export default VariantSelectorBasic;
66 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/variant-selector/images/variant-selector-images-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import VariantSelectorImages from "@/components/commerce-ui/components/variant-selector/images/variant-selector-images";
5 |
6 | const variants = [
7 | {
8 | id: "cat-default",
9 | label: "Default Cat",
10 | url: "/placeholders/cat-default.webp",
11 | value: "cat-default",
12 | },
13 | {
14 | id: "cat-steampunk",
15 | label: "Steampunk Cat",
16 | url: "/placeholders/cat-steampunk.webp",
17 | value: "cat-steampunk",
18 | },
19 | {
20 | id: "cat-cyberpunk",
21 | label: "Cyberpunk Cat",
22 | url: "/placeholders/cat-cyberpunk.webp",
23 | value: "cat-cyberpunk",
24 | },
25 | ];
26 |
27 | export default function VariantSelector_Images_Ex_01() {
28 | const [selected, setSelected] = useState("cat-default");
29 |
30 | return (
31 |
32 |
40 |
41 | Selected variant: {selected}
42 |
43 |
44 | );
45 | }
46 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/variant-selector/multiple/variant-selector-multiple-ex-01.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import VariantSelectorMultiple, {
5 | VariantItem,
6 | } from "@/components/commerce-ui/components/variant-selector/multiple/variant-selector-multiple";
7 |
8 | const variants: VariantItem[] = [
9 | {
10 | id: "damage-protection",
11 | label: "Damage Protection",
12 | value: "damage-protection",
13 | },
14 | {
15 | id: "extended-warranty",
16 | label: "Extended Warranty",
17 | value: "extended-warranty",
18 | },
19 | {
20 | id: "theft-protection",
21 | label: "Theft Protection",
22 | value: "theft-protection",
23 | },
24 | ];
25 |
26 | export default function VariantSelector_Basic_Ex_01() {
27 | const [selectedVariant, setSelectedVariant] = React.useState([
28 | "extended-warranty",
29 | ]);
30 |
31 | return (
32 |
33 |
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/components/commerce-ui/components/variant-selector/multiple/variant-selector-multiple.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import { ToggleGroup, ToggleGroupItem } from "@radix-ui/react-toggle-group";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | export interface VariantItem {
9 | id: string;
10 | value: string;
11 | label: string;
12 | disabled?: boolean;
13 | }
14 |
15 | interface VariantSelectorMultipleProps {
16 | values: string[];
17 | onValuesChange: (values: string[]) => void;
18 | variants: VariantItem[];
19 | className?: string;
20 | itemClassName?: string;
21 | labelClassName?: string;
22 | }
23 |
24 | const VariantSelectorMultiple = ({
25 | className,
26 | itemClassName,
27 | labelClassName,
28 | onValuesChange,
29 | values,
30 | variants,
31 | }: VariantSelectorMultipleProps) => {
32 | return (
33 |
39 | {variants.map((variant) => (
40 |
41 |
54 |
55 | {variant.label}
56 |
57 |
58 |
59 | ))}
60 |
61 | );
62 | };
63 |
64 | export default VariantSelectorMultiple;
65 |
--------------------------------------------------------------------------------
/components/commerce-ui/pages/product-01/components/store-navigation.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 |
3 | import {
4 | Breadcrumb,
5 | BreadcrumbEllipsis,
6 | BreadcrumbItem,
7 | BreadcrumbLink,
8 | BreadcrumbList,
9 | BreadcrumbPage,
10 | BreadcrumbSeparator,
11 | } from "@/components/ui/breadcrumb";
12 | import {
13 | DropdownMenu,
14 | DropdownMenuContent,
15 | DropdownMenuItem,
16 | DropdownMenuTrigger,
17 | } from "@/components/ui/dropdown-menu";
18 |
19 | export function StoreNavigation() {
20 | return (
21 |
22 |
23 |
24 |
25 | Home
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Toggle menu
34 |
35 |
36 | Documentation
37 | Themes
38 | GitHub
39 |
40 |
41 |
42 |
43 |
44 |
45 | Electronics
46 |
47 |
48 |
49 |
50 | Premium Noise-Cancelling Headphones
51 |
52 |
53 |
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/components/commerce-ui/pages/product-01/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import Banner_08 from "@/components/commerce-ui/blocks/banners/banner-08";
4 | import Review_04 from "@/components/commerce-ui/blocks/reviews/review-04";
5 | import Product from "@/components/commerce-ui/pages/product-01/components/product";
6 | import { ProductInfo } from "@/components/commerce-ui/pages/product-01/components/product-info";
7 | import { StoreHeader } from "@/components/commerce-ui/pages/product-01/components/store-header";
8 | import { StoreNavigation } from "@/components/commerce-ui/pages/product-01/components/store-navigation";
9 |
10 | export default function ProductPage_01() {
11 | return (
12 |
13 | {/* Header Section */}
14 |
15 |
16 |
17 |
18 |
19 | {/* Main Content */}
20 |
21 |
22 | {/* Product Section */}
23 |
24 |
25 | {" "}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/components/docs/code-renderer.tsx:
--------------------------------------------------------------------------------
1 | import type { CodePreviewProps } from "types/component";
2 | import CopyButton from "./copy-btn";
3 |
4 | export function CodeRenderer({ code, highlightedCode }: CodePreviewProps) {
5 | return (
6 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/components/docs/preview/component-collapse.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import {
4 | Collapsible,
5 | CollapsibleContent,
6 | CollapsibleTrigger,
7 | } from "@/components/ui/collapsible";
8 | import { cn } from "@/lib/utils";
9 | import { ChevronDown } from "lucide-react";
10 | import { useState } from "react";
11 | import type { ComponentPreviewProps } from "types/component";
12 | import { CodeRenderer } from "../code-renderer";
13 | import { ComponentLoader } from "../component-loader";
14 |
15 | /**
16 | * @deprecated
17 | */
18 | export function ComponentCollapse({
19 | classNameComponentContainer,
20 | hasReTrigger = false,
21 | name,
22 | source,
23 | }: ComponentPreviewProps) {
24 | const [isOpen, setIsOpen] = useState(false);
25 |
26 | return (
27 |
32 |
33 |
34 |
39 |
40 |
41 |
42 |
48 | {isOpen ? "Hide" : "Show"} code
49 |
50 |
51 |
52 |
53 |
54 |
58 |
59 |
60 |
61 | );
62 | }
63 |
--------------------------------------------------------------------------------
/components/docs/scroll-progress.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { cn } from "@/lib/utils";
4 | import { motion, MotionProps, useScroll, useSpring } from "motion/react";
5 | import React from "react";
6 | type ScrollProgressProps = Omit<
7 | React.HTMLAttributes,
8 | keyof MotionProps
9 | >;
10 |
11 | export const ScrollProgress = React.forwardRef<
12 | HTMLDivElement,
13 | ScrollProgressProps
14 | >(({ className, ...props }, ref) => {
15 | const { scrollYProgress } = useScroll();
16 |
17 | const scaleX = useSpring(scrollYProgress, {
18 | damping: 50,
19 | restDelta: 0.001,
20 | stiffness: 200,
21 | });
22 |
23 | return (
24 |
35 | );
36 | });
37 |
38 | ScrollProgress.displayName = "ScrollProgress";
39 |
--------------------------------------------------------------------------------
/components/landing/header-custom-links.tsx:
--------------------------------------------------------------------------------
1 | import { ArrowUpRight } from "lucide-react";
2 | import Link from "next/link";
3 |
4 | export async function HeaderCustomLinks() {
5 | return (
6 |
7 |
8 |
13 |
14 |
15 | Go full-stack
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Commerce API
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/components/layout/language-toggle.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { type ButtonHTMLAttributes, type HTMLAttributes } from "react";
3 | import { useI18n } from "fumadocs-ui/provider";
4 | import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
5 | import { cn } from "../../lib/cn";
6 | import { buttonVariants } from "../ui/button";
7 |
8 | export type LanguageSelectProps = ButtonHTMLAttributes;
9 |
10 | export function LanguageToggle(props: LanguageSelectProps): React.ReactElement {
11 | const context = useI18n();
12 | if (!context.locales) throw new Error("Missing ``");
13 |
14 | return (
15 |
16 |
27 | {props.children}
28 |
29 |
30 |
31 | {context.text.chooseLanguage}
32 |
33 | {context.locales.map((item) => (
34 |
49 | ))}
50 |
51 |
52 | );
53 | }
54 |
55 | export function LanguageToggleText(
56 | props: HTMLAttributes
57 | ): React.ReactElement {
58 | const context = useI18n();
59 | const text = context.locales?.find(
60 | (item) => item.locale === context.locale
61 | )?.name;
62 |
63 | return {text};
64 | }
65 |
--------------------------------------------------------------------------------
/components/layout/nav.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 | import Link, { type LinkProps } from 'fumadocs-core/link';
3 | import {
4 | createContext,
5 | type ReactNode,
6 | useContext,
7 | useEffect,
8 | useState,
9 | } from 'react';
10 | import { cn } from '../../lib/cn';
11 | import { useI18n } from 'fumadocs-ui/provider';
12 |
13 | export interface NavProviderProps {
14 | /**
15 | * Use transparent background
16 | *
17 | * @defaultValue none
18 | */
19 | transparentMode?: 'always' | 'top' | 'none';
20 | }
21 |
22 | export interface TitleProps {
23 | title?: ReactNode;
24 |
25 | /**
26 | * Redirect url of title
27 | * @defaultValue '/'
28 | */
29 | url?: string;
30 | }
31 |
32 | interface NavContextType {
33 | isTransparent: boolean;
34 | }
35 |
36 | const NavContext = createContext({
37 | isTransparent: false,
38 | });
39 |
40 | export function NavProvider({
41 | children,
42 | transparentMode = 'none',
43 | }: NavProviderProps & { children: ReactNode }) {
44 | const [transparent, setTransparent] = useState(transparentMode !== 'none');
45 |
46 | useEffect(() => {
47 | if (transparentMode !== 'top') return;
48 |
49 | const listener = () => {
50 | setTransparent(window.scrollY < 10);
51 | };
52 |
53 | listener();
54 | window.addEventListener('scroll', listener);
55 | return () => {
56 | window.removeEventListener('scroll', listener);
57 | };
58 | }, [transparentMode]);
59 |
60 | return (
61 |
62 | {children}
63 |
64 | );
65 | }
66 |
67 | export function useNav(): NavContextType {
68 | return useContext(NavContext);
69 | }
70 |
71 | export function Title({
72 | title,
73 | url,
74 | ...props
75 | }: TitleProps & Omit) {
76 | const { locale } = useI18n();
77 |
78 | return (
79 |
87 | {title}
88 |
89 | );
90 | }
91 |
--------------------------------------------------------------------------------
/components/layout/search-toggle.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { type ButtonHTMLAttributes } from "react";
3 | import { SearchIcon } from "lucide-react";
4 | import { useSearchContext } from "fumadocs-ui/provider";
5 | import { useI18n } from "fumadocs-ui/provider";
6 | import { cn } from "../../lib/cn";
7 | import { buttonVariants } from "../ui/button";
8 |
9 | export function SearchToggle({
10 | hideIfDisabled,
11 | ...props
12 | }: ButtonHTMLAttributes & {
13 | hideIfDisabled?: boolean;
14 | }) {
15 | const { enabled, setOpenSearch } = useSearchContext();
16 | if (hideIfDisabled && !enabled) return null;
17 |
18 | return (
19 |
36 | );
37 | }
38 |
39 | export function LargeSearchToggle({
40 | hideIfDisabled,
41 | ...props
42 | }: ButtonHTMLAttributes & {
43 | hideIfDisabled?: boolean;
44 | }) {
45 | const { enabled, hotKey, setOpenSearch } = useSearchContext();
46 | const { text } = useI18n();
47 | if (hideIfDisabled && !enabled) return null;
48 |
49 | return (
50 |
72 | );
73 | }
74 |
--------------------------------------------------------------------------------
/components/layout/theme-toggle.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 | import { cva } from 'class-variance-authority';
3 | import { Moon, Sun, Airplay } from 'lucide-react';
4 | import { useTheme } from 'next-themes';
5 | import { type HTMLAttributes, useLayoutEffect, useState } from 'react';
6 | import { cn } from '../../lib/cn';
7 |
8 | const itemVariants = cva('size-7 rounded-full p-1.5 text-fd-muted-foreground', {
9 | variants: {
10 | active: {
11 | false: 'text-fd-muted-foreground',
12 | true: 'bg-fd-accent text-fd-accent-foreground',
13 | },
14 | },
15 | });
16 |
17 | export function ThemeToggle({
18 | className,
19 | mode = 'light-dark',
20 | ...props
21 | }: HTMLAttributes & {
22 | mode?: 'light-dark' | 'light-dark-system';
23 | }) {
24 | const { resolvedTheme, setTheme, theme } = useTheme();
25 | const [mounted, setMounted] = useState(false);
26 |
27 | useLayoutEffect(() => {
28 | setMounted(true);
29 | }, []);
30 |
31 | const container = cn(
32 | 'inline-flex items-center rounded-full border p-[3px]',
33 | className,
34 | );
35 |
36 | if (mode === 'light-dark') {
37 | const value = mounted ? resolvedTheme : null;
38 |
39 | return (
40 |
49 | );
50 | }
51 |
52 | const value = mounted ? theme : null;
53 |
54 | return (
55 |
56 | {[
57 | ['light', Sun] as const,
58 | ['dark', Moon] as const,
59 | ['system', Airplay] as const,
60 | ].map(([key, Icon]) => (
61 |
69 | ))}
70 |
71 | );
72 | }
73 |
--------------------------------------------------------------------------------
/components/magicui/grid-pattern.tsx:
--------------------------------------------------------------------------------
1 | import { useId } from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | interface GridPatternProps extends React.SVGProps {
6 | width?: number;
7 | height?: number;
8 | x?: number;
9 | y?: number;
10 | squares?: Array<[x: number, y: number]>;
11 | strokeDasharray?: string;
12 | className?: string;
13 | [key: string]: unknown;
14 | }
15 |
16 | export function GridPattern({
17 | width = 40,
18 | height = 40,
19 | x = -1,
20 | y = -1,
21 | strokeDasharray = "0",
22 | squares,
23 | className,
24 | ...props
25 | }: GridPatternProps) {
26 | const id = useId();
27 |
28 | return (
29 |
69 | );
70 | }
71 |
--------------------------------------------------------------------------------
/components/magicui/line-shadow-text.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils";
2 | import { motion, MotionProps } from "motion/react";
3 |
4 | interface LineShadowTextProps
5 | extends Omit, keyof MotionProps>,
6 | MotionProps {
7 | shadowColor?: string;
8 | as?: React.ElementType;
9 | }
10 |
11 | export function LineShadowText({
12 | children,
13 | shadowColor = "black",
14 | className,
15 | as: Component = "span",
16 | ...props
17 | }: LineShadowTextProps) {
18 | const MotionComponent = motion.create(Component);
19 | const content = typeof children === "string" ? children : null;
20 |
21 | if (!content) {
22 | throw new Error("LineShadowText only accepts string content");
23 | }
24 |
25 | return (
26 |
39 | {content}
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/components/ui/badge.tsx:
--------------------------------------------------------------------------------
1 | import { type VariantProps, cva } from "class-variance-authority";
2 | import type * as React from "react";
3 |
4 | import { cn } from "@/lib/utils";
5 |
6 | const badgeVariants = cva(
7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2",
8 | {
9 | defaultVariants: {
10 | variant: "default",
11 | },
12 | variants: {
13 | variant: {
14 | default:
15 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
16 | destructive:
17 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
18 | outline: "text-foreground",
19 | secondary:
20 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
21 | },
22 | },
23 | }
24 | );
25 |
26 | export interface BadgeProps
27 | extends React.HTMLAttributes,
28 | VariantProps {}
29 |
30 | function Badge({ className, variant, ...props }: BadgeProps) {
31 | return (
32 |
33 | );
34 | }
35 |
36 | export { Badge, badgeVariants };
37 |
--------------------------------------------------------------------------------
/components/ui/button.tsx:
--------------------------------------------------------------------------------
1 | import { Slot } from "@radix-ui/react-slot";
2 | import { type VariantProps, cva } from "class-variance-authority";
3 | import * as React from "react";
4 |
5 | import { cn } from "@/lib/utils";
6 |
7 | const buttonVariants = cva(
8 | "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 cursor-pointer",
9 | {
10 | defaultVariants: {
11 | size: "default",
12 | variant: "default",
13 | },
14 | variants: {
15 | size: {
16 | default: "h-9 px-4 py-2",
17 | icon: "h-9 w-9",
18 | lg: "h-10 rounded-md px-8",
19 | sm: "h-8 rounded-md px-3 text-xs",
20 | },
21 | variant: {
22 | default:
23 | "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90",
24 | destructive:
25 | "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90",
26 | ghost: "hover:bg-accent hover:text-accent-foreground",
27 | link: "text-primary underline-offset-4 hover:underline",
28 | outline:
29 | "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
30 | secondary:
31 | "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
32 | },
33 | },
34 | }
35 | );
36 |
37 | export interface ButtonProps
38 | extends React.ButtonHTMLAttributes,
39 | VariantProps {
40 | asChild?: boolean;
41 | }
42 |
43 | const Button = React.forwardRef(
44 | ({ asChild = false, className, size, variant, ...props }, ref) => {
45 | const Comp = asChild ? Slot : "button";
46 | return (
47 |
52 | );
53 | }
54 | );
55 | Button.displayName = "Button";
56 |
57 | export { Button, buttonVariants };
58 |
--------------------------------------------------------------------------------
/components/ui/collapsible.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils";
2 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
3 | import { forwardRef } from "react";
4 |
5 | const Collapsible = CollapsiblePrimitive.Root;
6 |
7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
8 |
9 | const CollapsibleContent = forwardRef<
10 | React.ElementRef,
11 | React.ComponentPropsWithoutRef
12 | >(({ children, ...props }, ref) => {
13 | return (
14 |
22 | {children}
23 |
24 | );
25 | });
26 |
27 | CollapsibleContent.displayName =
28 | CollapsiblePrimitive.CollapsibleContent.displayName;
29 |
30 | export { Collapsible, CollapsibleTrigger, CollapsibleContent };
31 |
--------------------------------------------------------------------------------
/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | const Input = React.forwardRef>(
6 | ({ className, type, ...props }, ref) => {
7 | return (
8 |
17 | );
18 | }
19 | );
20 | Input.displayName = "Input";
21 |
22 | export { Input };
23 |
--------------------------------------------------------------------------------
/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as LabelPrimitive from "@radix-ui/react-label";
4 | import { type VariantProps, cva } from "class-variance-authority";
5 | import * as React from "react";
6 |
7 | import { cn } from "@/lib/utils";
8 |
9 | const labelVariants = cva(
10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
11 | );
12 |
13 | const Label = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef &
16 | VariantProps
17 | >(({ className, ...props }, ref) => (
18 |
23 | ));
24 | Label.displayName = LabelPrimitive.Root.displayName;
25 |
26 | export { Label };
27 |
--------------------------------------------------------------------------------
/components/ui/page-header.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils";
2 |
3 | function PageHeader({
4 | children,
5 | className,
6 | ...props
7 | }: React.HTMLAttributes) {
8 | return (
9 |
18 | );
19 | }
20 |
21 | function PageHeaderHeading({
22 | className,
23 | ...props
24 | }: React.HTMLAttributes) {
25 | return (
26 |
33 | );
34 | }
35 |
36 | function PageHeaderDescription({
37 | className,
38 | ...props
39 | }: React.HTMLAttributes) {
40 | return (
41 |
48 | );
49 | }
50 |
51 | function PageActions({
52 | className,
53 | ...props
54 | }: React.HTMLAttributes) {
55 | return (
56 |
63 | );
64 | }
65 |
66 | export { PageActions, PageHeader, PageHeaderDescription, PageHeaderHeading };
67 |
--------------------------------------------------------------------------------
/components/ui/popover.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as PopoverPrimitive from "@radix-ui/react-popover";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Popover = PopoverPrimitive.Root;
9 |
10 | const PopoverTrigger = PopoverPrimitive.Trigger;
11 |
12 | const PopoverAnchor = PopoverPrimitive.Anchor;
13 |
14 | const PopoverContent = React.forwardRef<
15 | React.ElementRef,
16 | React.ComponentPropsWithoutRef
17 | >(({ align = "center", className, sideOffset = 4, ...props }, ref) => (
18 |
19 |
29 |
30 | ));
31 | PopoverContent.displayName = PopoverPrimitive.Content.displayName;
32 |
33 | export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
34 |
--------------------------------------------------------------------------------
/components/ui/progress.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as ProgressPrimitive from "@radix-ui/react-progress"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | function Progress({
9 | className,
10 | value,
11 | ...props
12 | }: React.ComponentProps) {
13 | return (
14 |
22 |
27 |
28 | )
29 | }
30 |
31 | export { Progress }
32 |
--------------------------------------------------------------------------------
/components/ui/references.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils";
2 | import Link from "next/link";
3 | import type React from "react";
4 | import { badgeVariants } from "./badge";
5 | import { ExternalLinkIcon } from "./icons";
6 |
7 | interface LinkItem {
8 | link: string;
9 | label: string;
10 | }
11 |
12 | export function References({ children }: React.PropsWithChildren) {
13 | return (
14 |
15 |
Libraries used:
16 | {children}
17 |
18 | );
19 | }
20 |
21 | export function Reference({ label, link }: LinkItem) {
22 | return (
23 |
32 | {label}
33 |
34 |
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/components/ui/separator.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as SeparatorPrimitive from "@radix-ui/react-separator"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const Separator = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(
12 | (
13 | { className, decorative = true, orientation = "horizontal", ...props },
14 | ref
15 | ) => (
16 |
27 | )
28 | )
29 | Separator.displayName = SeparatorPrimitive.Root.displayName
30 |
31 | export { Separator }
32 |
--------------------------------------------------------------------------------
/components/ui/switch.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as SwitchPrimitive from "@radix-ui/react-switch"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | function Switch({
9 | className,
10 | ...props
11 | }: React.ComponentProps) {
12 | return (
13 |
21 |
27 |
28 | )
29 | }
30 |
31 | export { Switch }
32 |
--------------------------------------------------------------------------------
/components/ui/tooltip.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as TooltipPrimitive from "@radix-ui/react-tooltip";
4 | import * as React from "react";
5 |
6 | import { cn } from "@/lib/utils";
7 | const TooltipProvider = TooltipPrimitive.Provider;
8 |
9 | const Tooltip = TooltipPrimitive.Root;
10 |
11 | const TooltipTrigger = TooltipPrimitive.Trigger;
12 |
13 | const TooltipContent = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef
16 | >(({ className, sideOffset = 4, ...props }, ref) => (
17 |
26 | ));
27 | TooltipContent.displayName = TooltipPrimitive.Content.displayName;
28 |
29 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
30 |
--------------------------------------------------------------------------------
/config/sidebar-badges.ts:
--------------------------------------------------------------------------------
1 | type SidebarBadge = {
2 | page: string;
3 | alpha?: boolean;
4 | isNew?: boolean;
5 | count?: number;
6 | upcoming?: boolean;
7 | };
8 |
9 | export const sidebarBadges: SidebarBadge[] = [
10 | {
11 | count: 12,
12 | page: "Banners",
13 | },
14 | {
15 | count: 12,
16 | page: "Product Card",
17 | },
18 | {
19 | alpha: true,
20 | count: 5,
21 | page: "Product Variants",
22 | },
23 | {
24 | count: 10,
25 | page: "Reviews",
26 | },
27 | {
28 | alpha: true,
29 | count: 1,
30 | page: "Carts",
31 | },
32 | {
33 | alpha: true,
34 | isNew: true,
35 | count: 1,
36 | page: "Product Pages",
37 | },
38 | ];
39 |
--------------------------------------------------------------------------------
/config/sidebar-rename.ts:
--------------------------------------------------------------------------------
1 | export interface RenamedPage {
2 | pageName: string;
3 | newPageName: string;
4 | }
5 |
6 | export const SIDEBAR_RENAMED_PAGES: RenamedPage[] = [
7 | {
8 | newPageName: "Basic",
9 | pageName: "Image Carousel - Basic",
10 | },
11 | {
12 | newPageName: "Basic",
13 | pageName: "Image Viewer - Basic",
14 | },
15 | {
16 | newPageName: "Motion",
17 | pageName: "Image Viewer - Motion",
18 | },
19 | {
20 | newPageName: "Basic",
21 | pageName: "Price Format - Basic",
22 | },
23 |
24 | {
25 | newPageName: "Sale",
26 | pageName: "Price Format - Sale",
27 | },
28 |
29 | {
30 | newPageName: "Basic",
31 | pageName: "Face Rating - Basic",
32 | },
33 |
34 | {
35 | newPageName: "Gradient",
36 | pageName: "Face Rating - Gradient",
37 | },
38 |
39 | {
40 | newPageName: "Basic",
41 | pageName: "Like Rating - Basic",
42 | },
43 |
44 | {
45 | newPageName: "Basic",
46 | pageName: "Star Rating - Basic",
47 | },
48 |
49 | {
50 | newPageName: "Fractions",
51 | pageName: "Star Rating - Fractions",
52 | },
53 |
54 | {
55 | newPageName: "Basic",
56 | pageName: "Upvote Rating - Basic",
57 | },
58 | {
59 | newPageName: "Animated",
60 | pageName: "Upvote Rating - Animated",
61 | },
62 |
63 | {
64 | newPageName: "Animated",
65 | pageName: "Variant Selector - Animated",
66 | },
67 |
68 | {
69 | newPageName: "Basic",
70 | pageName: "Variant Selector - Basic",
71 | },
72 |
73 | {
74 | newPageName: "Images",
75 | pageName: "Variant Selector - Images",
76 | },
77 |
78 | {
79 | newPageName: "Multiple",
80 | pageName: "Variant Selector - Multiple",
81 | },
82 |
83 | {
84 | newPageName: "Basic",
85 | pageName: "Variant Color Selector - Basic",
86 | },
87 |
88 | {
89 | newPageName: "Basic",
90 | pageName: "Quantity Input - Basic",
91 | },
92 | ];
93 |
--------------------------------------------------------------------------------
/config/site.ts:
--------------------------------------------------------------------------------
1 | export const siteConfig = {
2 | name: "commerce-ui",
3 | creator: "@stackzero-labs",
4 | url: process.env.NEXT_PUBLIC_APP_URL ?? "https://ui.stackzero.co",
5 | ogImage: "https://ui.stackzero.co/opengraph-image.png",
6 | description:
7 | "stackzero/commerce-ui is a set of components and hooks that can be used to build a custom storefront for your commerce site.",
8 | keywords: [
9 | "Next.js",
10 | "React",
11 | "Tailwind CSS",
12 | "UI Library",
13 | "UI Kit",
14 | "UI Components",
15 | "UI Elements",
16 | "Open Source",
17 | "shadcn/ui",
18 | ],
19 | links: {
20 | portfolio: "https://stackzero.co",
21 | github: "https://github.com/stackzero-labs/ui",
22 | },
23 | };
24 |
25 | export type SiteConfig = typeof siteConfig;
26 |
--------------------------------------------------------------------------------
/content/docs/blocks/banners.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Banners
3 | description: Banner blocks for promotions, announcements or any other purpose.
4 | full: false
5 | ---
6 |
7 | ### Banner - 01
8 |
12 |
13 |
14 |
15 | ### Banner - 02
16 |
20 |
21 | ### Banner - 03
22 |
26 |
27 | ### Banner - 04
28 |
33 |
34 | ### Banner - 05
35 |
39 |
40 | ### Banner - 06
41 |
45 |
46 | ### Banner - 07
47 |
51 |
52 | ### Banner - 08
53 |
58 |
59 | ### Banner - 09
60 |
65 |
66 | ### Banner - 10
67 |
72 |
73 | ### Banner - 11
74 |
79 |
80 | ### Banner - 12
81 |
86 |
--------------------------------------------------------------------------------
/content/docs/blocks/carts.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Carts
3 | description: Cart blocks for shopping, checkout, and other purposes.
4 | full: false
5 | ---
6 |
7 | ### Cart - 01
8 |
13 |
--------------------------------------------------------------------------------
/content/docs/blocks/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Blocks",
3 | "pages" : [
4 | "...",
5 | "carts"
6 | ]
7 | }
8 |
9 |
10 |
--------------------------------------------------------------------------------
/content/docs/blocks/product-card.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Product Card
3 | description: A collection of product card blocks.
4 | full: false
5 | ---
6 |
7 | ### Product Card - 01
8 |
11 |
12 | ---
13 |
14 | ### Product Card - 02
15 |
19 |
20 | ### Product Card - 03
21 |
25 |
26 | ### Product Card - 04
27 |
31 |
32 | ### Product Card - 05
33 |
37 |
38 | ### Product Card - 06
39 |
43 |
44 | ### Product Card - 07
45 |
49 |
50 | ### Product Card - 08
51 |
55 |
56 | ### Product Card - 09
57 |
61 |
62 | ### Product Card - 10
63 |
67 |
68 | ### Product Card - 11
69 |
73 |
74 | ### Product Card - 12
75 |
79 |
80 | ### Product Card - 13
81 |
--------------------------------------------------------------------------------
/content/docs/blocks/product-variants.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Product Variants
3 | description: Blocks that showcase different product card variants
4 | full: false
5 | ---
6 |
7 | ### Product Variants - 01
8 |
14 |
15 | ### Product Variants - 02
16 |
22 |
23 | ### Product Variants - 03
24 |
30 |
31 | ### Product Variants - 04
32 |
38 |
39 |
40 | ### Product Variants - 05
41 |
47 |
48 |
--------------------------------------------------------------------------------
/content/docs/blocks/reviews.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Reviews
3 | description: Review blocks for your product or service.
4 | full: false
5 | ---
6 |
7 | ### Review - 01
8 |
12 |
13 | ### Review - 02
14 |
15 | Inspired by Amazon
16 |
20 |
21 |
22 | ### Review - 03
23 |
27 |
28 |
29 | ### Review - 04
30 |
33 |
34 |
35 | ### Review - 05
36 |
39 |
40 |
41 | ### Review - 06
42 |
45 |
46 |
47 | ### Review - 07
48 | Inspired by Booking
49 |
52 |
53 |
54 |
55 | ### Review - 08
56 |
57 | Inspired by Airbnb
58 |
61 |
62 |
63 | ### Review - 09
64 |
65 | Filter reviews by rating
66 |
70 |
71 |
72 | ### Review - 10
73 |
74 | Inspired by ProductHunt
75 |
79 |
--------------------------------------------------------------------------------
/content/docs/components/image-carousel/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Image Carousel",
3 | "icon": "GalleryThumbnails",
4 | "pages" : [
5 | "...",
6 | "basic"
7 | ]
8 | }
9 |
10 |
11 |
--------------------------------------------------------------------------------
/content/docs/components/image-viewer/basic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Image Viewer - Basic
3 | description: A component to display images in a modal
4 | ---
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | ## Install
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | Install the following dependencies:
33 |
34 |
35 | ```bash tab="pnpm"
36 | pnpm add @radix-ui/react-dialog react-zoom-pan-pinch
37 | ```
38 | ```bash tab="npm"
39 | npm install @radix-ui/react-dialog react-zoom-pan-pinch
40 | ```
41 | ```bash tab="bun"
42 | bun add @radix-ui/react-dialog react-zoom-pan-pinch
43 | ```
44 |
45 |
46 |
47 |
48 |
49 | Copy and paste the following code into your project:
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Update the import paths to match your project setup.
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | ## Examples
72 |
73 | ### Custom styles
74 |
75 | Control styles such as height using the `classNameThumbnailViewer` prop.
76 |
80 |
81 |
--------------------------------------------------------------------------------
/content/docs/components/image-viewer/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Image Viewer",
3 | "icon": "Image"
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/content/docs/components/price-format/basic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Price Format - Basic
3 | description: Format price numbers with currency symbol and decimal points
4 | ---
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 | ## Install
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Install the following dependencies:
31 |
32 |
33 | ```bash tab="pnpm"
34 | pnpm add react-number-format
35 | ```
36 | ```bash tab="npm"
37 | npm install react-number-format
38 | ```
39 | ```bash tab="bun"
40 | bun add react-number-format
41 | ```
42 |
43 |
44 |
45 |
46 |
47 |
48 | Copy and paste the following code into your project:
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Update the import paths to match your project setup
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/content/docs/components/price-format/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Price Format",
3 | "icon": "DollarSign"
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/content/docs/components/price-format/sale.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Price Format - Sale
3 | description: Format price numbers with sale price and original price
4 | ---
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 | ## Install
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Install the following dependencies:
31 |
32 |
33 | ```bash tab="pnpm"
34 | pnpm add react-number-format
35 | ```
36 | ```bash tab="npm"
37 | npm install react-number-format
38 | ```
39 | ```bash tab="bun"
40 | bun add react-number-format
41 | ```
42 |
43 |
44 |
45 |
46 |
47 |
48 | Copy and paste the following code into your project:
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Update the import paths to match your project setup.
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | ## Examples
70 |
71 | ### With sale price and percentage
72 |
76 |
77 | ### With just `originalPrice`
78 | If you do not specify a `salePrice` prop, the component will not display the sale price, thus defaulting to the original price.
79 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/content/docs/components/quantity-input/basic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Quantity Input - Basic
3 | description: A quantity input component with min, max validation
4 | ---
5 |
6 |
7 |
11 |
12 |
13 | ## Install
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Install the following dependencies:
27 |
28 |
29 | ```bash tab="pnpm"
30 | pnpm add react-number-format
31 | ```
32 | ```bash tab="npm"
33 | npm install react-number-format
34 | ```
35 | ```bash tab="bun"
36 | bun add react-number-format
37 | ```
38 |
39 |
40 |
41 |
42 |
43 |
44 | Copy and paste the following code into your project:
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | Update the import paths to match your project setup
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | ## Examples
65 |
66 | ### With min, max
67 |
68 | You can set a `max` and `min` value to the quantity input. The component will not allow the user to select a value outside of this range.
69 |
70 | This is usefull to limit the quantity of items a user can buy. For example, if you have a limited stock of an item, you can set the `max` value to the number of items in stock.
71 |
72 |
76 |
77 |
78 | ### With custom steps
79 |
80 | You can set a `step` value to the quantity input. The component will only allow the user to select values that are multiples of this step.
81 |
82 | This is usefull if you have a set of items that can only be bought in certain quantities.
83 |
84 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/content/docs/components/quantity-input/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Quantity Input",
3 | "icon": "ChevronsUpDown"
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/content/docs/components/rating-face/basic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Face Rating - Basic
3 | description: A face rating component
4 | ---
5 |
6 |
7 |
11 |
12 |
13 | ## Install
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Copy and paste the following code into your project
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Update the import paths to match your project setup
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ## Examples
48 |
49 | ### With custom icon size
50 |
51 |
55 |
56 | ### In a form
57 |
58 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/content/docs/components/rating-face/gradient.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Face Rating - Gradient
3 | description: A face rating component with a gradient color scheme
4 | ---
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ### Install
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Install the following dependencies:
32 |
33 |
34 | ```bash tab="pnpm"
35 | pnpm add tinycolor2
36 | ```
37 | ```bash tab="npm"
38 | npm install tinycolor2
39 | ```
40 | ```bash tab="bun"
41 | bun add tinycolor2
42 | ```
43 |
44 |
45 |
46 |
47 |
48 |
49 | Copy and paste the following code into your project
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Update the import paths to match your project setup
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/content/docs/components/rating-face/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Rating - Face",
3 | "icon": "Smile"
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/content/docs/components/rating-like/like-rating.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Like Rating - Basic
3 | description: A like dislike rating component
4 | ---
5 |
6 |
7 |
8 |
12 |
13 |
14 | ## Install
15 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Copy and paste the following code into your project
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Update the import paths to match your project setup
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/content/docs/components/rating-like/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Rating - Like",
3 | "icon": "ThumbsUp"
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/content/docs/components/rating-star/basic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Star Rating - Basic
3 | description: A star rating component
4 | ---
5 |
6 |
7 |
11 |
12 |
13 | ## Install
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Copy and paste the following code into your project:
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Update the import paths to match your project setup.
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ## Examples
48 |
49 | ### Change max rating
50 |
51 | Change how many stars are displayed
52 |
53 |
57 |
58 |
59 | ### Custom icons color
60 |
61 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/content/docs/components/rating-star/fractions.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Star Rating - Fractions
3 | description: A star rating component that allows for fractional ratings
4 | ---
5 |
6 |
7 |
11 |
12 |
13 | ## Install
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Copy and paste the following code into your project:
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Update the import paths to match your project setup.
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ## Examples
48 |
49 | ### Read only
50 |
54 |
55 | ### Custom color
56 |
60 |
61 |
--------------------------------------------------------------------------------
/content/docs/components/rating-star/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Rating - Star",
3 | "icon": "Star"
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/content/docs/components/rating-upvote/animated.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Upvote Rating - Animated
3 | description: An animated rating upvote and downvote component.
4 | ---
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 | ## Install
17 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Install the following dependencies:
30 |
31 |
32 | ```bash tab="pnpm"
33 | pnpm add @number-flow/react
34 | ```
35 | ```bash tab="npm"
36 | npm install @number-flow/react
37 | ```
38 | ```bash tab="bun"
39 | bun add @number-flow/react
40 | ```
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Copy and paste the following code into your project:
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Update the import paths to match your project setup.
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | ## Examples
70 |
71 | ### With custom increments
72 | Custom increments can be set for both upvotes and downvotes.
73 |
--------------------------------------------------------------------------------
/content/docs/components/rating-upvote/basic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Upvote Rating - Basic
3 | description: An upvote and downvote rating component. Similar to Reddit's upvote and downvote.
4 | ---
5 |
6 |
7 |
11 |
12 |
13 | ## Install
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Copy and paste the following code into your project:
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Update the import paths to match your project setup.
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ## Examples
48 |
49 | ### With custom increments
50 | Custom increments can be set for both upvotes and downvotes.
51 |
55 |
--------------------------------------------------------------------------------
/content/docs/components/rating-upvote/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Rating - Upvote",
3 | "icon": "ArrowDownUp"
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/content/docs/components/variant-color-selector/basic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Variant Color Selector - Basic
3 | description: A variant color selector component
4 | ---
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 | ## Install
17 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Install the following dependencies:
30 |
31 |
32 | ```bash tab="pnpm"
33 | pnpm add @radix-ui/react-radio-group
34 | ```
35 | ```bash tab="npm"
36 | npm install @radix-ui/react-radio-group
37 | ```
38 | ```bash tab="bun"
39 | bun add @radix-ui/react-radio-group
40 | ```
41 |
42 |
43 |
44 |
45 |
46 | Copy and paste the following code into your project
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | Update the import paths to match your project setup
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/content/docs/components/variant-color-selector/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Variant Color Selector",
3 | "icon": "Palette"
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/content/docs/components/variant-selector/images.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Variant Selector - Images
3 | description: A variant selector component with images
4 | ---
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ## Install
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Install the following dependencies:
31 |
32 |
33 | ```bash tab="pnpm"
34 | pnpm add @radix-ui/react-radio-group
35 | ```
36 | ```bash tab="npm"
37 | npm install @radix-ui/react-radio-group
38 | ```
39 | ```bash tab="bun"
40 | bun add @radix-ui/react-radio-group
41 | ```
42 |
43 |
44 |
45 |
46 |
47 | Copy and paste the following code into your project:
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | Update the import paths to match your project setup.
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | ## Examples
69 |
70 | Todo
71 |
72 |
--------------------------------------------------------------------------------
/content/docs/components/variant-selector/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Variant Selector",
3 | "icon": "CircleCheck"
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/content/docs/components/variant-selector/mutliple.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Variant Selector - Multiple
3 | description: A variant selector component with multiple selection
4 | ---
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ## Install
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Install the following dependencies:
31 |
32 |
33 | ```bash tab="pnpm"
34 | pnpm add @radix-ui/react-toggle-group
35 | ```
36 | ```bash tab="npm"
37 | npm install @radix-ui/react-toggle-group
38 | ```
39 | ```bash tab="bun"
40 | bun add @radix-ui/react-toggle-group
41 | ```
42 |
43 |
44 |
45 |
46 |
47 |
48 | Copy and paste the following code into your project
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Update the import paths to match your project setup
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | ## Examples
70 |
71 | ### Custom styles
72 |
76 |
--------------------------------------------------------------------------------
/content/docs/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "ui",
3 | "root": true,
4 | "pages": [
5 | "---Getting Started---",
6 | "index",
7 | "installation",
8 | "cli",
9 | "---Blocks---",
10 | "...blocks",
11 | "---Pages---",
12 | "...pages",
13 | "---Components---",
14 | "...components"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/content/docs/pages/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Pages",
3 | "pages" : [
4 | "...",
5 | "carts"
6 | ]
7 | }
8 |
9 |
10 |
--------------------------------------------------------------------------------
/content/docs/pages/products.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Product Pages
3 | description: Collection of product pages for showcasing products, features, and benefits.
4 | full: false
5 | ---
6 |
7 | ### Product Page - 01
8 |
13 |
14 |
--------------------------------------------------------------------------------
/content/docs/test.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Components
3 | description: Components
4 | ---
5 |
6 | ## Code Block
7 |
8 | ```js
9 | console.log('Hello World');
10 | ```
11 |
12 | ## Cards
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { dirname } from "path";
2 | import { fileURLToPath } from "url";
3 | import { FlatCompat } from "@eslint/eslintrc";
4 | import perfectionist from "eslint-plugin-perfectionist";
5 |
6 | const __filename = fileURLToPath(import.meta.url);
7 | const __dirname = dirname(__filename);
8 |
9 | const compat = new FlatCompat({
10 | baseDirectory: __dirname,
11 | });
12 |
13 | const eslintConfig = [
14 | ...compat.extends("next/core-web-vitals", "next/typescript"),
15 | {
16 | ignores: ["registry/"],
17 | },
18 | {
19 | plugins: {
20 | perfectionist,
21 | },
22 | rules: {
23 | "@typescript-eslint/no-unused-vars": "warn",
24 | "perfectionist/sort-objects": "warn",
25 | // Other rules
26 | "@next/next/no-img-element": "off"
27 | },
28 | },
29 | ];
30 |
31 | export default eslintConfig;
32 |
--------------------------------------------------------------------------------
/hooks/use-auto-resize-textarea.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useCallback } from "react";
2 |
3 | interface UseAutoResizeTextareaProps {
4 | minHeight: number;
5 | maxHeight?: number;
6 | }
7 |
8 | export function useAutoResizeTextarea({
9 | minHeight,
10 | maxHeight,
11 | }: UseAutoResizeTextareaProps) {
12 | const textareaRef = useRef(null);
13 |
14 | const adjustHeight = useCallback(
15 | (reset?: boolean) => {
16 | const textarea = textareaRef.current;
17 | if (!textarea) return;
18 |
19 | if (reset) {
20 | textarea.style.height = `${minHeight}px`;
21 | return;
22 | }
23 |
24 | // Temporarily shrink to get the right scrollHeight
25 | textarea.style.height = `${minHeight}px`;
26 |
27 | // Calculate new height
28 | const newHeight = Math.max(
29 | minHeight,
30 | Math.min(textarea.scrollHeight, maxHeight ?? Number.POSITIVE_INFINITY)
31 | );
32 |
33 | textarea.style.height = `${newHeight}px`;
34 | },
35 | [minHeight, maxHeight]
36 | );
37 |
38 | useEffect(() => {
39 | // Set initial height
40 | const textarea = textareaRef.current;
41 | if (textarea) {
42 | textarea.style.height = `${minHeight}px`;
43 | }
44 | }, [minHeight]);
45 |
46 | // Adjust height on window resize
47 | useEffect(() => {
48 | const handleResize = () => adjustHeight();
49 | window.addEventListener("resize", handleResize);
50 | return () => window.removeEventListener("resize", handleResize);
51 | }, [adjustHeight]);
52 |
53 | return { textareaRef, adjustHeight };
54 | }
55 |
--------------------------------------------------------------------------------
/hooks/use-mobile.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | const MOBILE_BREAKPOINT = 768;
4 |
5 | export function useIsMobile() {
6 | const [isMobile, setIsMobile] = React.useState(
7 | undefined
8 | );
9 |
10 | React.useEffect(() => {
11 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
12 | const onChange = () => {
13 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
14 | };
15 | mql.addEventListener("change", onChange);
16 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
17 | return () => mql.removeEventListener("change", onChange);
18 | }, []);
19 |
20 | return !!isMobile;
21 | }
22 |
--------------------------------------------------------------------------------
/hooks/use-registry-counts.ts:
--------------------------------------------------------------------------------
1 | import registryData from "@/public/registry.json";
2 | import { useMemo } from "react";
3 |
4 | export type StatCount = {
5 | components: number;
6 | blocks: number;
7 | examples: number;
8 | total: number;
9 | };
10 |
11 | /**
12 | * Custom hook to get the counts of components, blocks, and examples from the registry data.
13 | * @returns
14 | */
15 | export function useRegistryCounts(): StatCount {
16 | const counts = useMemo(() => {
17 | const initialCounts = registryData.registry.reduce(
18 | (acc: StatCount, item: { type: string }) => {
19 | if (item.type === "registry:component") {
20 | acc.components += 1;
21 | } else if (item.type === "registry:block") {
22 | acc.blocks += 1;
23 | } else if (item.type === "registry:example") {
24 | acc.examples += 1;
25 | } else if (item.type === "registry:page") {
26 | acc.examples += 1; // Treat pages as examples for counting purposes
27 | }
28 | return acc;
29 | },
30 | { blocks: 0, components: 0, examples: 0, total: 0 }
31 | );
32 |
33 | const total =
34 | initialCounts.components + initialCounts.blocks + initialCounts.examples;
35 |
36 | return { ...initialCounts, total };
37 | }, []);
38 |
39 | return counts;
40 | }
41 |
--------------------------------------------------------------------------------
/lib/cn.ts:
--------------------------------------------------------------------------------
1 | export { twMerge as cn } from 'tailwind-merge';
2 |
--------------------------------------------------------------------------------
/lib/fonts.ts:
--------------------------------------------------------------------------------
1 | import { GeistMono } from "geist/font/mono";
2 | import { GeistSans } from "geist/font/sans";
3 | import localFont from "next/font/local";
4 |
5 | export const fontSans = GeistSans;
6 |
7 | export const fontMono = GeistMono;
8 |
9 | export const fontRedaction = localFont({
10 | src: "../public/fonts/Redaction_35-Regular.woff2",
11 | variable: "--font-redaction",
12 | });
13 |
--------------------------------------------------------------------------------
/lib/is-active.ts:
--------------------------------------------------------------------------------
1 | export function isActive(
2 | url: string,
3 | pathname: string,
4 | nested = true,
5 | ): boolean {
6 | if (url.endsWith('/')) url = url.slice(0, -1);
7 | if (pathname.endsWith('/')) pathname = pathname.slice(0, -1);
8 |
9 | return url === pathname || (nested && pathname.startsWith(`${url}/`));
10 | }
11 |
--------------------------------------------------------------------------------
/lib/metadata.ts:
--------------------------------------------------------------------------------
1 | import { createMetadataImage } from "fumadocs-core/server";
2 | import { source, blog } from "@/lib/source";
3 |
4 | export const metadataImage = createMetadataImage({
5 | imageRoute: "/docs-og",
6 | source,
7 | });
8 |
9 | export const metadataImageBlog = createMetadataImage({
10 | imageRoute: "/blog-og",
11 | source: blog,
12 | });
13 |
--------------------------------------------------------------------------------
/lib/shiki.ts:
--------------------------------------------------------------------------------
1 | import {
2 | type Highlighter,
3 | bundledLanguages,
4 | createHighlighter,
5 | } from "shiki/bundle/web";
6 |
7 | // Global highlighter promise to prevent race conditions
8 | let highlighterPromise: Promise | null = null;
9 |
10 | async function getHighlighter() {
11 | if (!highlighterPromise) {
12 | highlighterPromise = createHighlighter({
13 | langs: [...Object.keys(bundledLanguages)],
14 | themes: ["github-dark-high-contrast", "github-light-high-contrast"],
15 | });
16 | }
17 | return highlighterPromise;
18 | }
19 |
20 | export async function codeToHtml({
21 | code,
22 | lang,
23 | }: {
24 | code: string;
25 | lang: string;
26 | }) {
27 | try {
28 | const highlighter = await getHighlighter();
29 |
30 | const htmlDark = highlighter.codeToHtml(code, {
31 | lang,
32 | theme: "github-dark-high-contrast",
33 | });
34 |
35 | const htmlLight = highlighter.codeToHtml(code, {
36 | lang,
37 | theme: "github-light-high-contrast",
38 | });
39 |
40 | return `
41 |
42 |
${htmlLight}
43 |
${htmlDark}
44 |
45 | `;
46 | } catch (error) {
47 | console.error("Error highlighting code:", error);
48 | return `${code}
`;
49 | }
50 | }
51 |
52 | // Optional: Cleanup function if needed
53 | export function disposeHighlighter() {
54 | if (highlighterPromise) {
55 | highlighterPromise.then((highlighter) => highlighter.dispose());
56 | highlighterPromise = null;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/lib/source.ts:
--------------------------------------------------------------------------------
1 | import { blog as blogPosts, docs, meta } from "@/.source";
2 | import { createMDXSource } from "fumadocs-mdx";
3 | import { loader } from "fumadocs-core/source";
4 | import { create } from "@/components/ui/icons";
5 | import { icons } from "lucide-react";
6 |
7 | export const source = loader({
8 | baseUrl: "/docs",
9 | icon(icon) {
10 | if (icon && icon in icons)
11 | return create({ icon: icons[icon as keyof typeof icons] });
12 | },
13 | source: createMDXSource(docs, meta),
14 | });
15 |
16 | export const blog = loader({
17 | baseUrl: "/blog",
18 | source: createMDXSource(blogPosts, []),
19 | });
20 |
--------------------------------------------------------------------------------
/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from "clsx";
2 | import { twMerge } from "tailwind-merge";
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs));
6 | }
7 |
--------------------------------------------------------------------------------
/next.config.mjs:
--------------------------------------------------------------------------------
1 | import { createMDX } from "fumadocs-mdx/next";
2 |
3 | const withMDX = createMDX();
4 |
5 | /** @type {import('next').NextConfig} */
6 | const config = {
7 | reactStrictMode: true,
8 | output: "export",
9 | };
10 |
11 | export default withMDX(config);
12 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | '@tailwindcss/postcss': {},
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/public/cover.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/cover.jpeg
--------------------------------------------------------------------------------
/public/fonts/Geist-Medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/fonts/Geist-Medium.otf
--------------------------------------------------------------------------------
/public/fonts/Redaction_35-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/fonts/Redaction_35-Regular.woff2
--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/public/placeholders/backpack.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/backpack.jpg
--------------------------------------------------------------------------------
/public/placeholders/bike-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/bike-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/camera-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/camera-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/cat-cyberpunk.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/cat-cyberpunk.webp
--------------------------------------------------------------------------------
/public/placeholders/cat-default.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/cat-default.webp
--------------------------------------------------------------------------------
/public/placeholders/cat-steampunk.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/cat-steampunk.webp
--------------------------------------------------------------------------------
/public/placeholders/charger-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/charger-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/coffee-cups-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/coffee-cups-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/coffee-filter-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/coffee-filter-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/coffee-machine-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/coffee-machine-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/coffee-machine-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/coffee-machine-02.jpg
--------------------------------------------------------------------------------
/public/placeholders/essential-oil-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/essential-oil-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/family-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/family-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/hand-cream-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/hand-cream-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/hand-cream-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/hand-cream-02.jpg
--------------------------------------------------------------------------------
/public/placeholders/hand-cream-03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/hand-cream-03.jpg
--------------------------------------------------------------------------------
/public/placeholders/hand-cream-04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/hand-cream-04.jpg
--------------------------------------------------------------------------------
/public/placeholders/handcream-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/handcream-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/headphone-1-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/headphone-1-thumb.jpg
--------------------------------------------------------------------------------
/public/placeholders/headphone-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/headphone-1.jpg
--------------------------------------------------------------------------------
/public/placeholders/headphone-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/headphone-2.jpg
--------------------------------------------------------------------------------
/public/placeholders/headphone-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/headphone-3.jpg
--------------------------------------------------------------------------------
/public/placeholders/headphone-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/headphone-4.jpg
--------------------------------------------------------------------------------
/public/placeholders/hotel-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/hotel-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/hotel-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/hotel-02.jpg
--------------------------------------------------------------------------------
/public/placeholders/logo-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/logo-01.png
--------------------------------------------------------------------------------
/public/placeholders/logo-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/logo-02.png
--------------------------------------------------------------------------------
/public/placeholders/logo-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/logo-03.png
--------------------------------------------------------------------------------
/public/placeholders/logo-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/logo-04.png
--------------------------------------------------------------------------------
/public/placeholders/logo-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/logo-05.png
--------------------------------------------------------------------------------
/public/placeholders/logo-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/logo-06.png
--------------------------------------------------------------------------------
/public/placeholders/shoes-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/shoes-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/shoes-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/shoes-02.jpg
--------------------------------------------------------------------------------
/public/placeholders/smartwatch-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/smartwatch-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/smartwatch-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/smartwatch-02.jpg
--------------------------------------------------------------------------------
/public/placeholders/speaker-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/speaker-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/speaker-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/speaker-02.jpg
--------------------------------------------------------------------------------
/public/placeholders/speaker-03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/speaker-03.jpg
--------------------------------------------------------------------------------
/public/placeholders/speaker-04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/speaker-04.jpg
--------------------------------------------------------------------------------
/public/placeholders/speaker-05.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/speaker-05.jpg
--------------------------------------------------------------------------------
/public/placeholders/tablet-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/tablet-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/user-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/user-01.jpg
--------------------------------------------------------------------------------
/public/placeholders/user-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/user-02.jpg
--------------------------------------------------------------------------------
/public/placeholders/user-03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/user-03.jpg
--------------------------------------------------------------------------------
/public/placeholders/user-04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/user-04.jpg
--------------------------------------------------------------------------------
/public/placeholders/user-05.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/user-05.jpg
--------------------------------------------------------------------------------
/public/placeholders/user-06.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/user-06.jpg
--------------------------------------------------------------------------------
/public/placeholders/user-07.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stackzero-labs/ui/7dec626f7def18a062676113bc9dbccd92c23cc4/public/placeholders/user-07.jpg
--------------------------------------------------------------------------------
/public/r/example-block.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-block",
3 | "type": "registry:block",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/star-rating-fractions.json",
9 | "https://ui.stackzero.co/r/image-carousel-horizontal.json",
10 | "https://ui.stackzero.co/r/price-format-basic.json"
11 | ],
12 | "files": [
13 | {
14 | "type": "registry:block",
15 | "content": "\"use client\";\n\nimport ImageCarousel_Horizontal from \"@/components/commerce-ui/image-carousel-horizontal\";\nimport PriceFormat_Basic from \"@/components/commerce-ui/price-format-basic\";\nimport StarRating from \"@/components/commerce-ui/star-rating-fractions\";\n\nconst images = [\n \"https://prd.place/400/600?id=37\",\n \"https://prd.place/400/600?id=38\",\n \"https://prd.place/400/600?id=39\",\n \"https://prd.place/800/1200?id=40\",\n \"https://prd.place/800/300?id=41\",\n];\n\nconst STAR_RATING_VALUE = 4.5;\nexport default function TestBlock() {\n return (\n \n
\n
\n \n
\n
\n
Product Name
\n
\n Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam,\n quos.\n
\n
\n
\n
\n
({STAR_RATING_VALUE})
\n
\n
\n
\n
\n );\n}\n",
16 | "path": "/components/commerce-ui/blocks/test-block.tsx",
17 | "target": "/components/commerce-ui/test-block.tsx"
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/public/r/face-rating-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "face-rating-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/face-rating-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport FaceRatingBasic from \"@/components/commerce-ui/face-rating-basic\";\nimport { useState } from \"react\";\n\nexport default function FaceRating_01_Ex_01() {\n const [rating, setRating] = useState(3);\n return (\n \n );\n}\n",
14 | "path": "/components/commerce-ui/components/face-rating/basic/face-rating-basic-ex-01.tsx",
15 | "target": "/components/commerce-ui/face-rating-basic-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/face-rating-basic-ex-02.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "face-rating-basic-ex-02",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/face-rating-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport FaceRatingBasic from \"@/components/commerce-ui/face-rating-basic\";\nimport { useState } from \"react\";\n\nexport default function FaceRating_01_Ex_02() {\n const [rating, setRating] = useState(3);\n return (\n \n
How do you feel about this product?
\n
\n
Rating: {rating}
\n
\n );\n}\n",
14 | "path": "/components/commerce-ui/components/face-rating/basic/face-rating-basic-ex-02.tsx",
15 | "target": "/components/commerce-ui/face-rating-basic-ex-02.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/face-rating-gradient-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "face-rating-gradient-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/face-rating-gradient.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport FaceRatingGradient from \"@/components/commerce-ui/face-rating-gradient\";\nimport { useState } from \"react\";\n\nexport default function FaceRating_Gradient_Ex_01() {\n const [rating, setRating] = useState(3);\n return (\n \n );\n}\n",
14 | "path": "/components/commerce-ui/components/face-rating/gradient/face-rating-gradient-ex-01.tsx",
15 | "target": "/components/commerce-ui/face-rating-gradient-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/image-carousel-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "image-carousel-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/image-carousel-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "import ImageCarouselBasic, {\n CarouselImages,\n} from \"@/components/commerce-ui/image-carousel-basic\";\n\nconst images: CarouselImages = [\n {\n title: \"Speaker 1\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-02.jpg\",\n },\n {\n title: \"Headphone 2\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-03.jpg\",\n },\n {\n title: \"Headphone 3\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/speaker-04.jpg\",\n },\n];\n\nexport default function ImageCarousel_Basic_Ex_01() {\n return ;\n}\n",
14 | "path": "/components/commerce-ui/components/image-carousel/basic/image-carousel-basic-ex-01.tsx",
15 | "target": "/components/commerce-ui/image-carousel-basic-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/image-carousel-basic-ex-02.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "image-carousel-basic-ex-02",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/image-carousel-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "import ImageCarouselBasic, {\n CarouselImages,\n} from \"@/components/commerce-ui/image-carousel-basic\";\n\nconst images: CarouselImages = [\n {\n title: \"Coffee Machine 1\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/coffee-machine-01.jpg\",\n },\n {\n title: \"Coffee Machine 2\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/coffee-machine-02.jpg\",\n },\n {\n title: \"Coffee Filter\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/coffee-filter-01.jpg\",\n },\n {\n title: \"Coffee Cups\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/coffee-cups-01.jpg\",\n },\n];\n\nexport default function ImageCarousel_Basic_Ex_02() {\n return (\n \n );\n}\n",
14 | "path": "/components/commerce-ui/components/image-carousel/basic/image-carousel-basic-ex-02.tsx",
15 | "target": "/components/commerce-ui/image-carousel-basic-ex-02.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/image-carousel-basic-ex-03.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "image-carousel-basic-ex-03",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/image-carousel-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "import ImageCarouselBasic, {\n CarouselImages,\n} from \"@/components/commerce-ui/image-carousel-basic\";\n\nconst images: CarouselImages = [\n {\n title: \"Headphone 1\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg\",\n },\n {\n title: \"Headphone 2\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-2.jpg\",\n },\n {\n title: \"Headphone 3\",\n url: \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-3.jpg\",\n },\n];\n\nexport default function ImageCarousel_Basic_Ex_03() {\n return (\n \n );\n}\n",
14 | "path": "/components/commerce-ui/components/image-carousel/basic/image-carousel-basic-ex-03.tsx",
15 | "target": "/components/commerce-ui/image-carousel-basic-ex-03.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/image-viewer-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "image-viewer-basic-ex-01",
3 | "type": "registry:component",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/image-viewer-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:component",
13 | "content": "\"use client\";\nimport ImageViewer from \"@/components/commerce-ui/image-viewer-basic\";\n\nconst EXAMPLE_IMAGE_URL =\n \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg\";\nconst EXAMPLE_THUMBNAIL_URL =\n \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg\";\n\nexport default function ImageViewer_Basic_Ex_01() {\n return (\n \n \n
\n );\n}\n",
14 | "path": "/components/commerce-ui/components/image-viewer/basic/image-viewer-basic-ex-01.tsx",
15 | "target": "/components/commerce-ui/image-viewer-basic-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/image-viewer-motion-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "image-viewer-motion-ex-01",
3 | "type": "registry:component",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/image-viewer-motion.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:component",
13 | "content": "\"use client\";\nimport ImageViewer from \"@/components/commerce-ui/image-viewer-motion\";\n\nconst EXAMPLE_IMAGE_URL =\n \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg\";\nconst EXAMPLE_THUMBNAIL_URL =\n \"https://raw.githubusercontent.com/stackzero-labs/ui/refs/heads/main/public/placeholders/headphone-1.jpg\";\n\nexport default function ImageViewer_Basic_Ex_01() {\n return (\n \n \n
\n );\n}\n",
14 | "path": "/components/commerce-ui/components/image-viewer/motion/image-viewer-motion-ex-01.tsx",
15 | "target": "/components/commerce-ui/image-viewer-motion-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/like-rating-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "like-rating-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/like-rating-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport LikeRatingBasic from \"@/components/commerce-ui/like-rating-basic\";\nimport { useState } from \"react\";\n\nexport default function LikeRating_Basic_Ex_01() {\n const [likes, setLikes] = useState(1100);\n const [dislikes, setDislikes] = useState(260);\n const [isLiked, setIsLiked] = useState(true);\n const [isDisliked, setIsDisliked] = useState(false);\n\n return (\n \n {\n setLikes(newState.likes);\n setDislikes(newState.dislikes);\n setIsLiked(newState.isLiked);\n setIsDisliked(newState.isDisliked);\n }}\n />\n
\n );\n}\n",
14 | "path": "/components/commerce-ui/components/like-rating/basic/like-rating-ex-01.tsx",
15 | "target": "/components/commerce-ui/like-rating-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/price-format-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "price-format-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/price-format-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport PriceFormat_Basic from \"@/components/commerce-ui/price-format-basic\";\n\nexport default function PriceFormat_Basic_Ex_01() {\n return (\n \n );\n}\n",
14 | "path": "/components/commerce-ui/components/price-format/basic/price-format-basic-ex-01.tsx",
15 | "target": "/components/commerce-ui/price-format-basic-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/price-format-basic.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "price-format-basic",
3 | "type": "registry:component",
4 | "dependencies": [
5 | "lucide-react",
6 | "react-number-format"
7 | ],
8 | "registryDependencies": [
9 | "button"
10 | ],
11 | "files": [
12 | {
13 | "type": "registry:component",
14 | "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { NumericFormat } from \"react-number-format\";\n\ninterface PriceFormat_BasicProps extends React.HTMLAttributes {\n value: number;\n prefix?: string;\n thousandSeparator?: string;\n decimalSeparator?: string;\n decimalScale?: number;\n}\n\nconst PriceFormat_Basic: React.FC = ({\n className,\n decimalScale = 2,\n decimalSeparator = \",\",\n prefix = \"$\",\n thousandSeparator = \".\",\n value,\n}) => {\n return (\n \n );\n};\n\nexport default PriceFormat_Basic;\n",
15 | "path": "/components/commerce-ui/components/price-format/basic/price-format-basic.tsx",
16 | "target": "/components/commerce-ui/price-format-basic.tsx"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/public/r/price-format-sale-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "price-format-sale-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [],
5 | "registryDependencies": [
6 | "https://ui.stackzero.co/r/price-format-sale.json"
7 | ],
8 | "files": [
9 | {
10 | "type": "registry:example",
11 | "content": "\"use client\";\n\nimport PriceFormat_Sale from \"@/components/commerce-ui/price-format-sale\";\n\nexport default function PriceFormat_Sale_Ex_01() {\n return (\n \n );\n}\n",
12 | "path": "/components/commerce-ui/components/price-format/sale/price-format-sale-ex-01.tsx",
13 | "target": "/components/commerce-ui/price-format-sale-ex-01.tsx"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/public/r/price-format-sale-ex-02.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "price-format-sale-ex-02",
3 | "type": "registry:example",
4 | "dependencies": [],
5 | "registryDependencies": [
6 | "https://ui.stackzero.co/r/price-format-sale.json"
7 | ],
8 | "files": [
9 | {
10 | "type": "registry:example",
11 | "content": "\"use client\";\n\nimport PriceFormat_Sale from \"@/components/commerce-ui/price-format-sale\";\n\nexport default function PriceFormat_Sale_Ex_02() {\n return (\n \n );\n}\n",
12 | "path": "/components/commerce-ui/components/price-format/sale/price-format-sale-ex-02.tsx",
13 | "target": "/components/commerce-ui/price-format-sale-ex-02.tsx"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/public/r/price-format-sale-ex-03.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "price-format-sale-ex-03",
3 | "type": "registry:example",
4 | "dependencies": [],
5 | "registryDependencies": [
6 | "https://ui.stackzero.co/r/price-format-sale.json"
7 | ],
8 | "files": [
9 | {
10 | "type": "registry:example",
11 | "content": "\"use client\";\n\nimport PriceFormat_Sale from \"@/components/commerce-ui/price-format-sale\";\n\nexport default function PriceFormat_Sale_Ex_03() {\n return (\n \n );\n}\n",
12 | "path": "/components/commerce-ui/components/price-format/sale/price-format-sale-ex-03.tsx",
13 | "target": "/components/commerce-ui/price-format-sale-ex-03.tsx"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/public/r/quantity-input-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "quantity-input-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/quantity-input-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport QuantityInputBasic from \"@/components/commerce-ui/quantity-input-basic\";\n\nexport default function QuantityInput_Basic_Ex_01() {\n const [quantity, setQuantity] = useState(1);\n\n const handleQuantityChange = (newQuantity: number) => {\n setQuantity(newQuantity);\n };\n\n return (\n <>\n \n >\n );\n}\n",
14 | "path": "/components/commerce-ui/components/quantity-input/basic/quantity-input-ex-01.tsx",
15 | "target": "/components/commerce-ui/quantity-input-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/quantity-input-basic-ex-02.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "quantity-input-basic-ex-02",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/quantity-input-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport QuantityInputBasic from \"@/components/commerce-ui/quantity-input-basic\";\n\nexport default function QuantityInput_Basic_Ex_02() {\n const [quantity, setQuantity] = useState(1);\n\n const handleQuantityChange = (newQuantity: number) => {\n setQuantity(newQuantity);\n };\n\n return (\n <>\n \n >\n );\n}\n",
14 | "path": "/components/commerce-ui/components/quantity-input/basic/quantity-input-ex-02.tsx",
15 | "target": "/components/commerce-ui/quantity-input-ex-02.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/quantity-input-basic-ex-03.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "quantity-input-basic-ex-03",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/quantity-input-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport QuantityInputBasic from \"@/components/commerce-ui/quantity-input-basic\";\n\nexport default function QuantityInput_Basic_Ex_03() {\n const [quantity, setQuantity] = useState(1);\n\n const handleQuantityChange = (newQuantity: number) => {\n setQuantity(newQuantity);\n };\n\n return (\n <>\n \n >\n );\n}\n",
14 | "path": "/components/commerce-ui/components/quantity-input/basic/quantity-input-ex-03.tsx",
15 | "target": "/components/commerce-ui/quantity-input-ex-03.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/rating-upvote-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rating-upvote-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "files": [
8 | {
9 | "type": "registry:example",
10 | "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport RatingUpvote_Basic from \"@/components/commerce-ui/rating-upvote-basic\";\n\nexport default function RatingUpvote_Basic_Ex_01() {\n const [upvotes, setUpvotes] = useState(100);\n const [downvotes, setDownvotes] = useState(20);\n const [upvoted, setUpvoted] = useState(false);\n const [downvoted, setDownvoted] = useState(false);\n\n return (\n \n {\n setUpvotes(newState.upvotes);\n setDownvotes(newState.downvotes);\n setUpvoted(newState.upvoted);\n setDownvoted(newState.downvoted);\n }}\n />\n
\n );\n}\n",
11 | "path": "/components/commerce-ui/rating-upvote/basic/rating-upvote-basic-ex-01.tsx",
12 | "target": "/components/commerce-ui/rating-upvote-basic-ex-01.tsx"
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/public/r/star-rating-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "star-rating-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/star-rating-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport StarRatingBasic from \"@/components/commerce-ui/star-rating-basic\";\nimport { useState } from \"react\";\n\nexport default function StarRating_Basic_Ex_01() {\n const [rating, setRating] = useState(3);\n return (\n \n );\n}\n",
14 | "path": "/components/commerce-ui/components/star-rating/basic/star-rating-basic-ex-01.tsx",
15 | "target": "/components/commerce-ui/star-rating-basic-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/star-rating-basic-ex-02.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "star-rating-basic-ex-02",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/star-rating-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport StarRatingBasic from \"@/components/commerce-ui/star-rating-basic\";\nimport { useState } from \"react\";\n\nexport default function StarRating_Basic_Ex_01() {\n const [rating, setRating] = useState(7);\n return (\n \n );\n}\n",
14 | "path": "/components/commerce-ui/components/star-rating/basic/star-rating-basic-ex-02.tsx",
15 | "target": "/components/commerce-ui/star-rating-basic-ex-02.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/star-rating-basic-ex-03.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "star-rating-basic-ex-03",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/star-rating-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport StarRatingBasic from \"@/components/commerce-ui/star-rating-basic\";\nimport { useState } from \"react\";\n\nexport default function StarRating_Basic_Ex_01() {\n const [rating, setRating] = useState(7);\n return (\n \n \n
\n );\n}\n",
14 | "path": "/components/commerce-ui/components/star-rating/basic/star-rating-basic-ex-03.tsx",
15 | "target": "/components/commerce-ui/star-rating-basic-ex-03.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/star-rating-fractions-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "star-rating-fractions-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/star-rating-fractions.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport StarRatingFractions from \"@/components/commerce-ui/star-rating-fractions\";\nimport { useState } from \"react\";\n\nexport default function StarRating_Fractions_Ex_01() {\n const [rating, setRating] = useState(4.3);\n return (\n \n );\n}\n",
14 | "path": "/components/commerce-ui/components/star-rating/fractions/star-rating-fractions-ex-01.tsx",
15 | "target": "/components/commerce-ui/star-rating-fractions-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/star-rating-fractions-ex-02.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "star-rating-fractions-ex-02",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/star-rating-fractions.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport StarRatingFractions from \"@/components/commerce-ui/star-rating-fractions\";\n\nexport default function StarRating_Fractions_Ex_02() {\n return (\n \n );\n}\n",
14 | "path": "/components/commerce-ui/components/star-rating/fractions/star-rating-fractions-ex-02.tsx",
15 | "target": "/components/commerce-ui/star-rating-fractions-ex-02.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/star-rating-fractions-ex-03.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "star-rating-fractions-ex-03",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/star-rating-fractions.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport StarRatingFractions from \"@/components/commerce-ui/star-rating-fractions\";\nimport { useState } from \"react\";\n\nexport default function StarRating_Fractions_Ex_02() {\n const [rating, setRating] = useState(4.3);\n return (\n \n \n
\n );\n}\n",
14 | "path": "/components/commerce-ui/components/star-rating/fractions/star-rating-fractions-ex-03.tsx",
15 | "target": "/components/commerce-ui/star-rating-fractions-ex-03.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/upvote-rating-animated-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "upvote-rating-animated-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react",
6 | "@number-flow/react"
7 | ],
8 | "registryDependencies": [
9 | "https://ui.stackzero.co/r/upvote-rating-animated.json"
10 | ],
11 | "files": [
12 | {
13 | "type": "registry:example",
14 | "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport UpvoteRating_Animated from \"@/components/commerce-ui/upvote-rating-animated\";\n\nexport default function UpvoteRating_Animated_Ex_01() {\n const [upvotes, setUpvotes] = useState(100);\n const [downvotes, setDownvotes] = useState(20);\n const [upvoted, setUpvoted] = useState(false);\n const [downvoted, setDownvoted] = useState(false);\n\n return (\n \n {\n setUpvotes(newState.upvotes);\n setDownvotes(newState.downvotes);\n setUpvoted(newState.upvoted);\n setDownvoted(newState.downvoted);\n }}\n />\n
\n );\n}\n",
15 | "path": "/components/commerce-ui/components/upvote-rating/animated/upvote-rating-animated-ex-01.tsx",
16 | "target": "/components/commerce-ui/upvote-rating-animated-ex-01.tsx"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/public/r/upvote-rating-animated-ex-02.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "upvote-rating-animated-ex-02",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react",
6 | "@number-flow/react"
7 | ],
8 | "registryDependencies": [
9 | "https://ui.stackzero.co/r/upvote-rating-animated.json"
10 | ],
11 | "files": [
12 | {
13 | "type": "registry:example",
14 | "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport UpvoteRating_Animated from \"@/components/commerce-ui/upvote-rating-animated\";\n\nexport default function UpvoteRating_Animated_Ex_02() {\n const [upvotes, setUpvotes] = useState(100);\n const [downvotes, setDownvotes] = useState(20);\n const [upvoted, setUpvoted] = useState(false);\n const [downvoted, setDownvoted] = useState(false);\n\n return (\n \n {\n setUpvotes(newState.upvotes);\n setDownvotes(newState.downvotes);\n setUpvoted(newState.upvoted);\n setDownvoted(newState.downvoted);\n }}\n upvoteIncrement={15}\n downvoteIncrement={15}\n />\n
\n );\n}\n",
15 | "path": "/components/commerce-ui/components/upvote-rating/animated/upvote-rating-animated-ex-02.tsx",
16 | "target": "/components/commerce-ui/upvote-rating-animated-ex-02.tsx"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/public/r/upvote-rating-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "upvote-rating-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/upvote-rating-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport UpvoteRating_Basic from \"@/components/commerce-ui/upvote-rating-basic\";\n\nexport default function UpvoteRating_Basic_Ex_01() {\n const [upvotes, setUpvotes] = useState(100);\n const [downvotes, setDownvotes] = useState(20);\n const [upvoted, setUpvoted] = useState(false);\n const [downvoted, setDownvoted] = useState(false);\n\n return (\n \n {\n setUpvotes(newState.upvotes);\n setDownvotes(newState.downvotes);\n setUpvoted(newState.upvoted);\n setDownvoted(newState.downvoted);\n }}\n />\n
\n );\n}\n",
14 | "path": "/components/commerce-ui/components/upvote-rating/basic/upvote-rating-basic-ex-01.tsx",
15 | "target": "/components/commerce-ui/upvote-rating-basic-ex-01.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/upvote-rating-basic-ex-02.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "upvote-rating-basic-ex-02",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react"
6 | ],
7 | "registryDependencies": [
8 | "https://ui.stackzero.co/r/upvote-rating-basic.json"
9 | ],
10 | "files": [
11 | {
12 | "type": "registry:example",
13 | "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport UpvoteRating_Basic from \"@/components/commerce-ui/upvote-rating-basic\";\n\nexport default function UpvoteRating_Basic_Ex_02() {\n const [upvotes, setUpvotes] = useState(100);\n const [downvotes, setDownvotes] = useState(20);\n const [upvoted, setUpvoted] = useState(false);\n const [downvoted, setDownvoted] = useState(false);\n\n return (\n \n {\n setUpvotes(newState.upvotes);\n setDownvotes(newState.downvotes);\n setUpvoted(newState.upvoted);\n setDownvoted(newState.downvoted);\n }}\n upvoteIncrement={15}\n downvoteIncrement={15}\n />\n
\n );\n}\n",
14 | "path": "/components/commerce-ui/components/upvote-rating/basic/upvote-rating-basic-ex-02.tsx",
15 | "target": "/components/commerce-ui/upvote-rating-basic-ex-02.tsx"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/public/r/utils.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "utils",
3 | "type": "registry:lib",
4 | "dependencies": [
5 | "clsx",
6 | "tailwind-merge"
7 | ],
8 | "files": [
9 | {
10 | "type": "registry:lib",
11 | "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n",
12 | "path": "/lib/utils.ts",
13 | "target": "/lib/utils.ts"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/public/r/variant-color-selector-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "variant-color-selector-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react",
6 | "@radix-ui/react-radio-group",
7 | "motion"
8 | ],
9 | "registryDependencies": [
10 | "https://ui.stackzero.co/r/variant-color-selector-basic.json"
11 | ],
12 | "files": [
13 | {
14 | "type": "registry:example",
15 | "content": "import * as React from \"react\";\nimport VariantColorSelectorBasic, {\n ColorVariantItem,\n} from \"./variant-color-selector-basic\";\n\nconst variants: ColorVariantItem[] = [\n { color: \"#000000\", id: \"color-black\", label: \"Black\", value: \"black\" },\n { color: \"#FFFFFF\", id: \"color-white\", label: \"White\", value: \"white\" },\n { color: \"#FF0000\", id: \"color-red\", label: \"Red\", value: \"red\" },\n { color: \"#0000FF\", id: \"color-blue\", label: \"Blue\", value: \"blue\" },\n { color: \"#00FF00\", id: \"color-green\", label: \"Green\", value: \"green\" },\n { color: \"#FFFF00\", id: \"color-yellow\", label: \"Yellow\", value: \"yellow\" },\n { color: \"#800080\", id: \"color-purple\", label: \"Purple\", value: \"purple\" },\n];\n\nexport default function VariantColorSelectorBasicExample() {\n const [selectedColor, setSelectedColor] = React.useState(\"black\");\n\n return (\n \n
\n \n );\n}\n",
16 | "path": "/components/commerce-ui/components/variant-color-selector/basic/variant-color-selector-basic-ex-01.tsx",
17 | "target": "/components/commerce-ui/variant-color-selector-basic-ex-01.tsx"
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/public/r/variant-selector-basic-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "variant-selector-basic-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react",
6 | "@radix-ui/react-radio-group"
7 | ],
8 | "registryDependencies": [
9 | "https://ui.stackzero.co/r/variant-selector-basic.json"
10 | ],
11 | "files": [
12 | {
13 | "type": "registry:example",
14 | "content": "\"use client\";\n\nimport * as React from \"react\";\nimport VariantSelectorBasic, {\n VariantItem,\n} from \"@/components/commerce-ui/variant-selector-basic\";\n\nconst variants: VariantItem[] = [\n { id: \"variant-xxs\", label: \"XXS\", value: \"variant-xxs\" },\n { id: \"variant-xs\", label: \"XS\", value: \"variant-xs\" },\n { id: \"variant-s\", label: \"S\", value: \"variant-s\" },\n { id: \"variant-m\", label: \"M\", value: \"variant-m\" },\n { id: \"variant-l\", label: \"L\", value: \"variant-l\" },\n { id: \"variant-xl\", label: \"XL\", value: \"variant-xl\" },\n { id: \"variant-xxl\", label: \"XXL\", value: \"variant-xxl\" },\n];\n\nexport default function VariantSelector_Basic_Ex_01() {\n const [selectedVariant, setSelectedVariant] = React.useState(\"variant-m\");\n\n return (\n \n
\n\n \n \n );\n}\n",
15 | "path": "/components/commerce-ui/components/variant-selector/basic/variant-selector-basic-ex-01.tsx",
16 | "target": "/components/commerce-ui/variant-selector-basic-ex-01.tsx"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/public/r/variant-selector-images-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "variant-selector-images-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react",
6 | "@radix-ui/react-radio-group"
7 | ],
8 | "registryDependencies": [
9 | "https://ui.stackzero.co/r/variant-selector-images.json"
10 | ],
11 | "files": [
12 | {
13 | "type": "registry:example",
14 | "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport VariantSelectorImages from \"@/components/commerce-ui/variant-selector-images\";\n\nconst variants = [\n {\n id: \"cat-default\",\n label: \"Default Cat\",\n url: \"/placeholders/cat-default.webp\",\n value: \"cat-default\",\n },\n {\n id: \"cat-steampunk\",\n label: \"Steampunk Cat\",\n url: \"/placeholders/cat-steampunk.webp\",\n value: \"cat-steampunk\",\n },\n {\n id: \"cat-cyberpunk\",\n label: \"Cyberpunk Cat\",\n url: \"/placeholders/cat-cyberpunk.webp\",\n value: \"cat-cyberpunk\",\n },\n];\n\nexport default function VariantSelector_Images_Ex_01() {\n const [selected, setSelected] = useState(\"cat-default\");\n\n return (\n \n
\n
\n Selected variant: {selected}\n
\n
\n );\n}\n",
15 | "path": "/components/commerce-ui/components/variant-selector/images/variant-selector-images-ex-01.tsx",
16 | "target": "/components/commerce-ui/variant-selector-images-ex-01.tsx"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/public/r/variant-selector-multiple-ex-01.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "variant-selector-multiple-ex-01",
3 | "type": "registry:example",
4 | "dependencies": [
5 | "lucide-react",
6 | "@radix-ui/react-toggle-group"
7 | ],
8 | "registryDependencies": [
9 | "https://ui.stackzero.co/r/variant-selector-multiple.json"
10 | ],
11 | "files": [
12 | {
13 | "type": "registry:example",
14 | "content": "\"use client\";\n\nimport * as React from \"react\";\nimport VariantSelectorMultiple, {\n VariantItem,\n} from \"@/components/commerce-ui/variant-selector-multiple\";\n\nconst variants: VariantItem[] = [\n {\n id: \"damage-protection\",\n label: \"Damage Protection\",\n value: \"damage-protection\",\n },\n {\n id: \"extended-warranty\",\n label: \"Extended Warranty\",\n value: \"extended-warranty\",\n },\n {\n id: \"theft-protection\",\n label: \"Theft Protection\",\n value: \"theft-protection\",\n },\n];\n\nexport default function VariantSelector_Basic_Ex_01() {\n const [selectedVariant, setSelectedVariant] = React.useState([\n \"extended-warranty\",\n ]);\n\n return (\n \n
\n \n );\n}\n",
15 | "path": "/components/commerce-ui/components/variant-selector/multiple/variant-selector-multiple-ex-01.tsx",
16 | "target": "/components/commerce-ui/variant-selector-multiple-ex-01.tsx"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/registry/index.ts:
--------------------------------------------------------------------------------
1 | import { lib } from "./registry-lib";
2 | import { components } from "./registry-components";
3 | import { Registry } from "./schema";
4 | import { examples } from "./registry-examples";
5 | import { blocks } from "./registry-blocks";
6 | import { pages } from "./registry-pages";
7 |
8 | // Ensure that the registry always have an array of registry items
9 | const ensureArray = (items: T | T[]): T[] =>
10 | Array.isArray(items) ? items : Object.values(items as object);
11 |
12 | // Combine all registry items into a single array
13 | export const registry: Registry = [
14 | // ...ensureArray(buttons),
15 | // ...ensureArray(input),
16 | ...ensureArray(lib),
17 | // ...ensureArray(ui),
18 | ...ensureArray(components),
19 | ...ensureArray(examples),
20 | ...ensureArray(blocks),
21 | ...ensureArray(pages),
22 | ];
23 |
24 | // Utility functions
25 | export const getComponentByName = (name: string) =>
26 | registry.find((item) => item.name === name);
27 |
28 | export const getComponentsByCategory = (category: string) => {
29 | return ensureArray(registry)
30 | .filter((item) => item.categories?.includes(category))
31 | .map((item) => item.name);
32 | };
33 |
--------------------------------------------------------------------------------
/registry/registry-hooks.ts:
--------------------------------------------------------------------------------
1 | import type { Registry } from "./schema";
2 |
3 | export const hooks: Registry = [
4 | {
5 | name: "use-auto-resize-textarea",
6 | type: "registry:hook",
7 | files: [
8 | {
9 | path: "hooks/use-auto-resize-textarea.ts",
10 | type: "registry:hook",
11 | },
12 | ],
13 | },
14 | ];
15 |
--------------------------------------------------------------------------------
/registry/registry-lib.ts:
--------------------------------------------------------------------------------
1 | import type { Registry } from "@/registry/schema";
2 |
3 | export const lib: Registry = [
4 | {
5 | name: "utils",
6 | type: "registry:lib",
7 | dependencies: ["clsx", "tailwind-merge"],
8 | files: [
9 | {
10 | path: "lib/utils.ts",
11 | type: "registry:lib",
12 | },
13 | ],
14 | },
15 | ];
16 |
--------------------------------------------------------------------------------
/registry/registry-pages.ts:
--------------------------------------------------------------------------------
1 | import type { Registry } from "@/registry/schema";
2 | import * as React from "react";
3 |
4 | export const pages: Registry = [
5 | {
6 | name: "product-01-page",
7 | type: "registry:page",
8 | dependencies: ["lucide-react"],
9 | registryDependencies: [
10 | "accordion",
11 | "breadcrumb",
12 | "button",
13 | "dropdown-menu",
14 | "input",
15 | "https://ui.stackzero.co/r/star-rating-fractions.json",
16 | "https://ui.stackzero.co/r/product-variant-01-block.json",
17 | "https://ui.stackzero.co/r/banner-08-block.json",
18 | "https://ui.stackzero.co/r/review-04-block.json",
19 | ],
20 | files: [
21 | {
22 | path: "@/components/commerce-ui/pages/product-01/page.tsx",
23 | type: "registry:page",
24 | target: "app/product/page.tsx",
25 | },
26 | {
27 | path: "@/components/commerce-ui/pages/product-01/components/product.tsx",
28 | type: "registry:component",
29 | },
30 | {
31 | path: "@/components/commerce-ui/pages/product-01/components/product-info.tsx",
32 | type: "registry:component",
33 | },
34 | {
35 | path: "@/components/commerce-ui/pages/product-01/components/store-header.tsx",
36 | type: "registry:component",
37 | },
38 | {
39 | path: "@/components/commerce-ui/pages/product-01/components/store-navigation.tsx",
40 | type: "registry:component",
41 | },
42 | ],
43 | component: React.lazy(
44 | () => import("../components/commerce-ui/pages/product-01/page")
45 | ),
46 | },
47 | ];
48 |
--------------------------------------------------------------------------------
/registry/schema.ts:
--------------------------------------------------------------------------------
1 | import * as z from "zod";
2 |
3 | export const registryItemTypeSchema = z.enum([
4 | "registry:lib",
5 | "registry:block",
6 | "registry:element",
7 | "registry:component",
8 | "registry:showcase",
9 | "registry:ui",
10 | "registry:hook",
11 | "registry:page",
12 |
13 | // Internal use only
14 | "registry:example",
15 | "registry:theme",
16 | "registry:style",
17 |
18 | "registry:internal",
19 | ]);
20 |
21 | export const registryItemFileSchema = z.object({
22 | path: z.string(),
23 | content: z.string().optional(),
24 | type: registryItemTypeSchema,
25 | target: z.string().optional(),
26 | });
27 |
28 | export const registryItemTailwindSchema = z.object({
29 | config: z.object({
30 | content: z.array(z.string()).optional(),
31 | theme: z.record(z.string(), z.any()).optional(),
32 | plugins: z.array(z.string()).optional(),
33 | }),
34 | });
35 |
36 | export const registryItemCssVarsSchema = z.object({
37 | light: z.record(z.string(), z.string()).optional(),
38 | dark: z.record(z.string(), z.string()).optional(),
39 | });
40 |
41 | export const registryItemSchema = z.object({
42 | name: z.string(),
43 | description: z.string().optional(),
44 | type: registryItemTypeSchema,
45 | dependencies: z.array(z.string()).optional(),
46 | registryDependencies: z.array(z.string()).optional(),
47 | files: z.array(registryItemFileSchema).optional(),
48 | component: z.function().args(z.any()).returns(z.any()).optional(),
49 | tailwind: registryItemTailwindSchema.optional(),
50 | cssVars: registryItemCssVarsSchema.optional(),
51 | meta: z.record(z.string(), z.any()).optional(),
52 | docs: z.string().optional(),
53 | categories: z.array(z.string()).optional(),
54 | });
55 |
56 | export const registrySchema = z.array(registryItemSchema);
57 |
58 | export type Registry = z.infer;
59 |
--------------------------------------------------------------------------------
/scripts/sort-registry.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as path from "path";
3 |
4 | const REGISTRY_FILE = path.join(
5 | process.cwd(),
6 | "registry",
7 | "registry-components.ts"
8 | );
9 |
10 | async function sortRegistry() {
11 | try {
12 | // Read the file
13 | const fileContent = fs.readFileSync(REGISTRY_FILE, "utf8");
14 |
15 | // Extract the components array content
16 | const startMarker = "export const components: Registry = [";
17 | const endMarker = "];";
18 |
19 | const startIndex = fileContent.indexOf(startMarker) + startMarker.length;
20 | const endIndex = fileContent.lastIndexOf(endMarker);
21 |
22 | const beforeComponents = fileContent.slice(0, startIndex);
23 | const afterComponents = fileContent.slice(endIndex);
24 |
25 | // Split into individual component objects
26 | const componentsString = fileContent.slice(startIndex, endIndex);
27 | const componentBlocks = componentsString
28 | .split(/},\s*{/)
29 | .map((block) => block.trim().replace(/^\[?\{?|\}?\]?$/g, ""));
30 |
31 | // Parse and sort components
32 | const components = componentBlocks.map((block) => ({
33 | content: block,
34 | name: block.match(/name:\s*"([^"]+)"/)?.[1] ?? "",
35 | }));
36 |
37 | components.sort((a, b) => a.name.localeCompare(b.name));
38 |
39 | // Rebuild the sorted content
40 | const sortedContent = components
41 | .map(({ content }, index) => {
42 | const prefix = index === 0 ? "\n {" : " {";
43 | const suffix = index === components.length - 1 ? "}" : "},";
44 | return `${prefix}${content}${suffix}\n`;
45 | })
46 | .join("\n");
47 |
48 | // Combine all parts
49 | const newContent = `${beforeComponents}${sortedContent}${afterComponents}`;
50 |
51 | // Write back to file
52 | fs.writeFileSync(REGISTRY_FILE, newContent);
53 |
54 | console.log("✅ Registry components sorted successfully!");
55 | } catch (error) {
56 | console.error("❌ Error sorting registry:", error);
57 | process.exit(1);
58 | }
59 | }
60 |
61 | sortRegistry();
62 |
--------------------------------------------------------------------------------
/source.config.ts:
--------------------------------------------------------------------------------
1 | import {
2 | defineDocs,
3 | defineConfig,
4 | defineCollections,
5 | frontmatterSchema,
6 | metaSchema,
7 | } from "fumadocs-mdx/config";
8 | import { z } from "zod";
9 |
10 | export const { docs, meta } = defineDocs({
11 | dir: "content/docs",
12 | });
13 |
14 | export const blog = defineCollections({
15 | dir: "content/blog",
16 | schema: frontmatterSchema.extend({
17 | author: z.string(),
18 | date: z.string().date().or(z.date()).optional(),
19 | tags: z.array(z.string()).optional(),
20 | }),
21 | type: "doc",
22 | });
23 |
24 | export default defineConfig();
25 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "target": "ESNext",
5 | "lib": ["dom", "dom.iterable", "esnext"],
6 | "allowJs": true,
7 | "skipLibCheck": true,
8 | "strict": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "noEmit": true,
11 | "esModuleInterop": true,
12 | "module": "esnext",
13 | "moduleResolution": "bundler",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "jsx": "preserve",
17 | "incremental": true,
18 | "paths": {
19 | "@/*": ["./*"]
20 | },
21 | "plugins": [
22 | {
23 | "name": "next"
24 | }
25 | ]
26 | },
27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
28 | "exclude": ["node_modules"]
29 | }
30 |
--------------------------------------------------------------------------------
/types/component.ts:
--------------------------------------------------------------------------------
1 | export type SourceCodes = Record<
2 | string,
3 | {
4 | code: string;
5 | highlightedCode: string;
6 | fileName?: string; // Optional file name for better context
7 | isMainFile?: boolean; // Optional flag to indicate if this is the main file
8 | }
9 | >;
10 |
11 | export type ComponentPreviewProps = {
12 | name: string;
13 | displayExampleName?: string;
14 | hasReTrigger?: boolean;
15 | classNameComponentContainer?: string;
16 | codeRendererFiles?: string[];
17 | source: SourceCodes;
18 | };
19 |
20 | export type PagePreviewProps = {
21 | name: string;
22 | hasReTrigger?: boolean;
23 | classNameComponentContainer?: string;
24 | source: SourceCodes;
25 | };
26 |
27 | export type ComponentDisplayProps = {
28 | component: React.ReactElement;
29 | hasReTrigger: boolean;
30 | className?: string;
31 | reTriggerKey: number;
32 | reTrigger: () => void;
33 | isPreview?: boolean;
34 | };
35 |
36 | export type CodePreviewProps = {
37 | code: string;
38 | highlightedCode: string;
39 | };
40 |
--------------------------------------------------------------------------------