docs: improve instructions to install Medusa UI in standalone projects (#13104)

This commit is contained in:
Shahed Nasser authored and GitHub committed 2025-07-31 16:04:20 +03:00
1 parent f6736d9661
commit 54d9edc1ab
3 files changed
+210 -124

No files matched your search

+103 -63
View File
@@ -83074,7 +83074,7 @@ const data = [
{ {
id: "1", id: "1",
title: "Shirt", title: "Shirt",
price: 10 price: 10,
}, },
// other data... // other data...
] ]
@@ -83113,7 +83113,7 @@ import {
Then, inside the component that will render `DataTable`, create a table instance using the `useDataTable` hook: Then, inside the component that will render `DataTable`, create a table instance using the `useDataTable` hook:
```tsx ```tsx
export default function ProductTable () { export default function ProductTable() {
const table = useDataTable({ const table = useDataTable({
columns, columns,
data, data,
@@ -83137,7 +83137,7 @@ The `useDataTable` hook accepts an object with the following properties:
Finally, render the `DataTable` component with the table instance created using the `useDataTable` hook: Finally, render the `DataTable` component with the table instance created using the `useDataTable` hook:
```tsx ```tsx
export default function ProductTable () { export default function ProductTable() {
// ... // ...
return ( return (
<DataTable instance={table}> <DataTable instance={table}>
@@ -83376,14 +83376,14 @@ const products = [
id: "1", id: "1",
title: "Shirt", title: "Shirt",
price: 10, price: 10,
is_active: true is_active: true,
}, },
{ {
id: "2", id: "2",
title: "Pants", title: "Pants",
price: 20, price: 20,
is_active: true is_active: true,
} },
] ]
const columnHelper = createDataTableColumnHelper<typeof products[0]>() const columnHelper = createDataTableColumnHelper<typeof products[0]>()
@@ -83398,7 +83398,7 @@ const columns = [
{isActive ? "Active" : "Inactive"} {isActive ? "Active" : "Inactive"}
</Badge> </Badge>
) )
} },
}), }),
// ... // ...
] ]
@@ -83483,8 +83483,8 @@ const table = useDataTable({
// ... // ...
search: { search: {
state: search, state: search,
onSearchChange: setSearch onSearchChange: setSearch,
} },
}) })
``` ```
@@ -83513,8 +83513,8 @@ const table = useDataTable({
// Pass the state and onSearchChange to the table instance. // Pass the state and onSearchChange to the table instance.
search: { search: {
state: search, state: search,
onSearchChange: setSearch onSearchChange: setSearch,
} },
}) })
``` ```
@@ -83755,7 +83755,7 @@ const table = useDataTable({
onPaginationChange: setPagination, onPaginationChange: setPagination,
}, },
isLoading: false, isLoading: false,
}); })
``` ```
Finally, render the `DataTable.Pagination` component as part of the `DataTable`'s children: Finally, render the `DataTable.Pagination` component as part of the `DataTable`'s children:
@@ -83914,8 +83914,8 @@ const filters = [
label: "Title", label: "Title",
options: products.map((product) => ({ options: products.map((product) => ({
label: product.title, label: product.title,
value: product.title.toLowerCase() value: product.title.toLowerCase(),
})) })),
}), }),
] ]
``` ```
@@ -84008,7 +84008,7 @@ const table = useDataTable({
state: filtering, state: filtering,
onFilteringChange: setFiltering, onFilteringChange: setFiltering,
}, },
filters filters,
}) })
``` ```
@@ -84196,24 +84196,24 @@ const filters = [
label: "Today", label: "Today",
value: { value: {
$gte: new Date(new Date().setHours(0, 0, 0, 0)).toString(), $gte: new Date(new Date().setHours(0, 0, 0, 0)).toString(),
$lte: new Date(new Date().setHours(23, 59, 59, 999)).toString() $lte: new Date(new Date().setHours(23, 59, 59, 999)).toString(),
} },
}, },
{ {
label: "Yesterday", label: "Yesterday",
value: { value: {
$gte: new Date(new Date().setHours(0, 0, 0, 0) - 24 * 60 * 60 * 1000).toString(), $gte: new Date(new Date().setHours(0, 0, 0, 0) - 24 * 60 * 60 * 1000).toString(),
$lte: new Date(new Date().setHours(0, 0, 0, 0)).toString() $lte: new Date(new Date().setHours(0, 0, 0, 0)).toString(),
} },
}, },
{ {
label: "Last Week", label: "Last Week",
value: { value: {
$gte: new Date(new Date().setHours(0, 0, 0, 0) - 7 * 24 * 60 * 60 * 1000).toString(), $gte: new Date(new Date().setHours(0, 0, 0, 0) - 7 * 24 * 60 * 60 * 1000).toString(),
$lte: new Date(new Date().setHours(0, 0, 0, 0)).toString() $lte: new Date(new Date().setHours(0, 0, 0, 0)).toString(),
}, },
}, },
] ],
}), }),
] ]
``` ```
@@ -84382,7 +84382,7 @@ If you want to set initial filter values, you can set the initial state of the `
```tsx ```tsx
const [filtering, setFiltering] = useState<DataTableFilteringState>({ const [filtering, setFiltering] = useState<DataTableFilteringState>({
title: ["shirt"] title: ["shirt"],
}) })
``` ```
@@ -84510,11 +84510,11 @@ Next, in the component rendering the `DataTable` component, create a state varia
```tsx ```tsx
import { import {
// ... // ...
DataTableSortingState DataTableSortingState,
} from "@medusajs/ui" } from "@medusajs/ui"
export default function ProductTable () { export default function ProductTable() {
const [sorting, setSorting] = useState<DataTableSortingState | null>(null); const [sorting, setSorting] = useState<DataTableSortingState | null>(null)
const table = useDataTable({ const table = useDataTable({
// ... // ...
@@ -84540,7 +84540,7 @@ You must also implement the sorting logic, such as sending the sorting condition
For example, when using a simple array as in the example above, this is how you sort the data based on the sorting conditions: For example, when using a simple array as in the example above, this is how you sort the data based on the sorting conditions:
```tsx ```tsx
const [sorting, setSorting] = useState<DataTableSortingState | null>(null); const [sorting, setSorting] = useState<DataTableSortingState | null>(null)
const shownProducts = useMemo(() => { const shownProducts = useMemo(() => {
if (!sorting) { if (!sorting) {
@@ -84823,8 +84823,8 @@ const useCommands = () => {
const productsToDeleteIds = Object.keys(selection) const productsToDeleteIds = Object.keys(selection)
// TODO remove products from the server // TODO remove products from the server
} },
}) }),
] ]
} }
``` ```
@@ -88429,50 +88429,60 @@ npm install @medusajs/ui
The configuration of the UI package is handled by the `@medusajs/admin` package. Therefore, you do not need to any additional configuration to use the UI package in your Admin extensions. The configuration of the UI package is handled by the `@medusajs/admin` package. Therefore, you do not need to any additional configuration to use the UI package in your Admin extensions.
# Standalone Project # Medusa UI Installation in Standalone Projects
How to install and use Medusa UI in a standalone project. Learn how to install and use Medusa UI in a standalone project.
## Installation Medusa UI is a React UI library that, while intended for usage within Medusa projects, can also be used in any React project.
The icons package is installed independently from Medusa UI. Learn how to install it in the [Icons](../icons/overview.mdx) guide.
## Medusa UI Compatibility
To use Medusa UI in your standalone project, you must have:
- React 18+ installed. Most React-based frameworks and libraries, such as Next.js and Vite, are compatible with this requirement.
- [Tailwind CSS](https://v3.tailwindcss.com/) installed. The components in Medusa UI are styled using Tailwind CSS, so you will need to install it in your project as well.
- Medusa UI was built with Tailwind CSS v3, but it may generally support v4 as well.
*** ***
Medusa UI is a React UI library and while it's intended for usage within Medusa projects, it can also be used in any React project. ## Step 1: Install Medusa UI
### Install Medusa UI In your standalone project, install the Medusa UI package with the following command:
Install the React UI library with the following command:
```bash ```bash
npm install @medusajs/ui npm install @medusajs/ui
``` ```
### Configuring Tailwind CSS ***
The components are styled using Tailwind CSS, and in order to use them, you will need to install Tailwind CSS in your project as well. ## Step 2: Install UI Presets
For more information on how to install Tailwind CSS, please refer to the [Tailwind CSS documentation](https://tailwindcss.com/docs/installation).
All of the classes used for Medusa UI are shipped as a Tailwind CSS customization. Medusa UI customizes Tailwind CSS classes to implement its design system. So, you must also install the Medusa UI preset package.
You can install it with the following command:
To install the Medusa UI preset, run the following command:
```bash ```bash
npm install @medusajs/ui-preset npm install @medusajs/ui-preset
``` ```
After you have installed Tailwind CSS and the Medusa UI preset, you need to add the following to your `tailwind.config.js`file: ***
```tsx ## Step 3: Configure Tailwind CSS
Next, you'll need to configure Tailwind CSS to use the Medusa UI preset and explicitly add the paths to the Medusa UI components as content files.
### Tailwind CSS v3 Configurations
In Tailwind CSS v3, which is the recommended version to use with Medusa UI, you need to add the following configurations to your `tailwind.config.js` or `tailwind.config.ts` file:
1. Add the Medusa UI preset to the `presets` array.
2. Ensure that the `content` field includes the path to the Medusa UI package.
```js title="tailwind.config.js"
module.exports = { module.exports = {
presets: [require("@medusajs/ui-preset")], presets: [require("@medusajs/ui-preset")],
// ...
}
```
In order for the styles to be applied correctly to the components, you will also need to ensure that
`@medusajs/ui` is included in the content field of your `tailwind.config.js` file:
```tsx
module.exports = {
content: [ content: [
// ... // ...
"./node_modules/@medusajs/ui/dist/**/*.{js,jsx,ts,tsx}", "./node_modules/@medusajs/ui/dist/**/*.{js,jsx,ts,tsx}",
@@ -88481,9 +88491,9 @@ module.exports = {
} }
``` ```
If you are working within a monorepo, you may need to add the path to the `@medusajs/ui` package in your `tailwind.config.js` like so: If your project is in a monorepo, you'll need to resolve the path to the `@medusajs/ui` package from the monorepo root:
```tsx ```tsx title="tailwind.config.js"
const path = require("path") const path = require("path")
const uiPath = path.resolve( const uiPath = path.resolve(
@@ -88493,6 +88503,7 @@ const uiPath = path.resolve(
) )
module.exports = { module.exports = {
presets: [require("@medusajs/ui-preset")],
content: [ content: [
// ... // ...
uiPath, uiPath,
@@ -88502,26 +88513,55 @@ module.exports = {
``` ```
## Start building ### Tailwind CSS v4 Configurations
*** Medusa UI isn't officially compatible with Tailwind CSS v4 yet, so use it with caution.
You are now ready to start building your application with Medusa UI. You can import the components like so: In your CSS file that imports Tailwind CSS, add the following `@config` and `@source` directives:
```tsx ```css
import { Button, Drawer } from "@medusajs/ui" @import "tailwindcss";
@source "../node_modules/@medusajs/ui";
@config "@medusajs/ui-preset";
``` ```
## Updating UI Packages This will explicitly include the Medusa UI preset and its components in your Tailwind CSS build, and will apply the preset styles to your project.
*** ***
Medusa's design-system packages, including `@medusajs/ui`, `@medusajs/ui-preset`, and `@medusajs/ui-icons`, are versioned independently. However, they're still part of the latest Medusa release. So, you can browse the [release notes](https://github.com/medusajs/medusa/releases) to see if there are any breaking changes to these packages. ## Step 4: Use Medusa UI in Standalone Projects
To update these packages, update their version in your `package.json` file and re-install dependencies. For example: You can now start building your application with Medusa UI.
```bash For example, you can use the `Button` in your custom components:
npm install @medusajs/ui
```tsx
import { Button } from "@medusajs/ui"
export function ButtonDemo() {
return <Button>Button</Button>
}
```
Refer to the documentation of each component to learn about its props and usage.
***
## Update UI Packages in Standalone Projects
Medusa's design-system packages, including `@medusajs/ui` and `@medusajs/ui-preset`, are versioned independently from other `@medusajs/*` packages. However, they're still released as part of Medusa's releases.
So, to find latest updates and breaking changes to any of these packages, refer to the [release notes in the Medusa GitHub repository](https://github.com/medusajs/medusa/releases).
To update these packages in your standalone project, update their version in your `package.json` file and re-install dependencies. For example:
```json title="package.json"
{
"dependencies": {
"@medusajs/ui": "4.0.0",
"@medusajs/ui-preset": "4.0.0"
}
}
``` ```
@@ -43,7 +43,7 @@ const data = [
{ {
id: "1", id: "1",
title: "Shirt", title: "Shirt",
price: 10 price: 10,
}, },
// other data... // other data...
] ]
@@ -82,7 +82,7 @@ import {
Then, inside the component that will render `DataTable`, create a table instance using the `useDataTable` hook: Then, inside the component that will render `DataTable`, create a table instance using the `useDataTable` hook:
```tsx ```tsx
export default function ProductTable () { export default function ProductTable() {
const table = useDataTable({ const table = useDataTable({
columns, columns,
data, data,
@@ -106,7 +106,7 @@ The `useDataTable` hook accepts an object with the following properties:
Finally, render the `DataTable` component with the table instance created using the `useDataTable` hook: Finally, render the `DataTable` component with the table instance created using the `useDataTable` hook:
```tsx ```tsx
export default function ProductTable () { export default function ProductTable() {
// ... // ...
return ( return (
<DataTable instance={table}> <DataTable instance={table}>
@@ -196,14 +196,14 @@ const products = [
id: "1", id: "1",
title: "Shirt", title: "Shirt",
price: 10, price: 10,
is_active: true is_active: true,
}, },
{ {
id: "2", id: "2",
title: "Pants", title: "Pants",
price: 20, price: 20,
is_active: true is_active: true,
} },
] ]
const columnHelper = createDataTableColumnHelper<typeof products[0]>() const columnHelper = createDataTableColumnHelper<typeof products[0]>()
@@ -218,7 +218,7 @@ const columns = [
{isActive ? "Active" : "Inactive"} {isActive ? "Active" : "Inactive"}
</Badge> </Badge>
) )
} },
}), }),
// ... // ...
] ]
@@ -242,8 +242,8 @@ const table = useDataTable({
// ... // ...
search: { search: {
state: search, state: search,
onSearchChange: setSearch onSearchChange: setSearch,
} },
}) })
``` ```
@@ -272,8 +272,8 @@ const table = useDataTable({
// Pass the state and onSearchChange to the table instance. // Pass the state and onSearchChange to the table instance.
search: { search: {
state: search, state: search,
onSearchChange: setSearch onSearchChange: setSearch,
} },
}) })
``` ```
@@ -370,7 +370,7 @@ const table = useDataTable({
onPaginationChange: setPagination, onPaginationChange: setPagination,
}, },
isLoading: false, isLoading: false,
}); })
``` ```
Finally, render the `DataTable.Pagination` component as part of the `DataTable`'s children: Finally, render the `DataTable.Pagination` component as part of the `DataTable`'s children:
@@ -427,8 +427,8 @@ const filters = [
label: "Title", label: "Title",
options: products.map((product) => ({ options: products.map((product) => ({
label: product.title, label: product.title,
value: product.title.toLowerCase() value: product.title.toLowerCase(),
})) })),
}), }),
] ]
``` ```
@@ -525,7 +525,7 @@ const table = useDataTable({
state: filtering, state: filtering,
onFilteringChange: setFiltering, onFilteringChange: setFiltering,
}, },
filters filters,
}) })
``` ```
@@ -575,24 +575,24 @@ const filters = [
label: "Today", label: "Today",
value: { value: {
$gte: new Date(new Date().setHours(0, 0, 0, 0)).toString(), $gte: new Date(new Date().setHours(0, 0, 0, 0)).toString(),
$lte: new Date(new Date().setHours(23, 59, 59, 999)).toString() $lte: new Date(new Date().setHours(23, 59, 59, 999)).toString(),
} },
}, },
{ {
label: "Yesterday", label: "Yesterday",
value: { value: {
$gte: new Date(new Date().setHours(0, 0, 0, 0) - 24 * 60 * 60 * 1000).toString(), $gte: new Date(new Date().setHours(0, 0, 0, 0) - 24 * 60 * 60 * 1000).toString(),
$lte: new Date(new Date().setHours(0, 0, 0, 0)).toString() $lte: new Date(new Date().setHours(0, 0, 0, 0)).toString(),
} },
}, },
{ {
label: "Last Week", label: "Last Week",
value: { value: {
$gte: new Date(new Date().setHours(0, 0, 0, 0) - 7 * 24 * 60 * 60 * 1000).toString(), $gte: new Date(new Date().setHours(0, 0, 0, 0) - 7 * 24 * 60 * 60 * 1000).toString(),
$lte: new Date(new Date().setHours(0, 0, 0, 0)).toString() $lte: new Date(new Date().setHours(0, 0, 0, 0)).toString(),
}, },
}, },
] ],
}), }),
] ]
``` ```
@@ -653,7 +653,7 @@ If you want to set initial filter values, you can set the initial state of the `
```tsx ```tsx
const [filtering, setFiltering] = useState<DataTableFilteringState>({ const [filtering, setFiltering] = useState<DataTableFilteringState>({
title: ["shirt"] title: ["shirt"],
}) })
``` ```
@@ -698,11 +698,11 @@ Next, in the component rendering the `DataTable` component, create a state varia
```tsx ```tsx
import { import {
// ... // ...
DataTableSortingState DataTableSortingState,
} from "@medusajs/ui" } from "@medusajs/ui"
export default function ProductTable () { export default function ProductTable() {
const [sorting, setSorting] = useState<DataTableSortingState | null>(null); const [sorting, setSorting] = useState<DataTableSortingState | null>(null)
const table = useDataTable({ const table = useDataTable({
// ... // ...
@@ -728,7 +728,7 @@ You must also implement the sorting logic, such as sending the sorting condition
For example, when using a simple array as in the example above, this is how you sort the data based on the sorting conditions: For example, when using a simple array as in the example above, this is how you sort the data based on the sorting conditions:
```tsx ```tsx
const [sorting, setSorting] = useState<DataTableSortingState | null>(null); const [sorting, setSorting] = useState<DataTableSortingState | null>(null)
const shownProducts = useMemo(() => { const shownProducts = useMemo(() => {
if (!sorting) { if (!sorting) {
@@ -852,8 +852,8 @@ const useCommands = () => {
const productsToDeleteIds = Object.keys(selection) const productsToDeleteIds = Object.keys(selection)
// TODO remove products from the server // TODO remove products from the server
} },
}) }),
] ]
} }
``` ```
@@ -1,44 +1,58 @@
--- ---
title: "Standalone Project" title: "Medusa UI Installation in Standalone Projects"
description: "How to install and use Medusa UI in a standalone project." description: "Learn how to install and use Medusa UI in a standalone project."
--- ---
## Installation Medusa UI is a React UI library that, while intended for usage within Medusa projects, can also be used in any React project.
<Note>
The icons package is installed independently from Medusa UI. Learn how to install it in the [Icons](../icons/overview.mdx) guide.
</Note>
## Medusa UI Compatibility
To use Medusa UI in your standalone project, you must have:
- React 18+ installed. Most React-based frameworks and libraries, such as Next.js and Vite, are compatible with this requirement.
- [Tailwind CSS](https://v3.tailwindcss.com/) installed. The components in Medusa UI are styled using Tailwind CSS, so you will need to install it in your project as well.
- Medusa UI was built with Tailwind CSS v3, but it may generally support v4 as well.
--- ---
Medusa UI is a React UI library and while it's intended for usage within Medusa projects, it can also be used in any React project. ## Step 1: Install Medusa UI
### Install Medusa UI In your standalone project, install the Medusa UI package with the following command:
Install the React UI library with the following command:
<PackageInstall packageName="@medusajs/ui" /> <PackageInstall packageName="@medusajs/ui" />
### Configuring Tailwind CSS ---
The components are styled using Tailwind CSS, and in order to use them, you will need to install Tailwind CSS in your project as well. ## Step 2: Install UI Presets
For more information on how to install Tailwind CSS, please refer to the [Tailwind CSS documentation](https://tailwindcss.com/docs/installation).
All of the classes used for Medusa UI are shipped as a Tailwind CSS customization. Medusa UI customizes Tailwind CSS classes to implement its design system. So, you must also install the Medusa UI preset package.
You can install it with the following command:
To install the Medusa UI preset, run the following command:
<PackageInstall packageName="@medusajs/ui-preset" devDependency /> <PackageInstall packageName="@medusajs/ui-preset" devDependency />
After you have installed Tailwind CSS and the Medusa UI preset, you need to add the following to your `tailwind.config.js`file: ---
```tsx ## Step 3: Configure Tailwind CSS
Next, you'll need to configure Tailwind CSS to use the Medusa UI preset and explicitly add the paths to the Medusa UI components as content files.
### Tailwind CSS v3 Configurations
In Tailwind CSS v3, which is the recommended version to use with Medusa UI, you need to add the following configurations to your `tailwind.config.js` or `tailwind.config.ts` file:
1. Add the Medusa UI preset to the `presets` array.
2. Ensure that the `content` field includes the path to the Medusa UI package.
```js title="tailwind.config.js"
module.exports = { module.exports = {
presets: [require("@medusajs/ui-preset")], presets: [require("@medusajs/ui-preset")],
// ...
}
```
In order for the styles to be applied correctly to the components, you will also need to ensure that
`@medusajs/ui` is included in the content field of your `tailwind.config.js` file:
```tsx
module.exports = {
content: [ content: [
// ... // ...
"./node_modules/@medusajs/ui/dist/**/*.{js,jsx,ts,tsx}", "./node_modules/@medusajs/ui/dist/**/*.{js,jsx,ts,tsx}",
@@ -47,9 +61,9 @@ module.exports = {
} }
``` ```
If you are working within a monorepo, you may need to add the path to the `@medusajs/ui` package in your `tailwind.config.js` like so: If your project is in a monorepo, you'll need to resolve the path to the `@medusajs/ui` package from the monorepo root:
```tsx ```tsx title="tailwind.config.js"
const path = require("path") const path = require("path")
const uiPath = path.resolve( const uiPath = path.resolve(
@@ -59,6 +73,7 @@ const uiPath = path.resolve(
) )
module.exports = { module.exports = {
presets: [require("@medusajs/ui-preset")],
content: [ content: [
// ... // ...
uiPath, uiPath,
@@ -68,24 +83,55 @@ module.exports = {
``` ```
## Start building ### Tailwind CSS v4 Configurations
Medusa UI isn't officially compatible with Tailwind CSS v4 yet, so use it with caution.
In your CSS file that imports Tailwind CSS, add the following `@config` and `@source` directives:
```css
@import "tailwindcss";
@source "../node_modules/@medusajs/ui";
@config "@medusajs/ui-preset";
```
This will explicitly include the Medusa UI preset and its components in your Tailwind CSS build, and will apply the preset styles to your project.
--- ---
You are now ready to start building your application with Medusa UI. You can import the components like so: ## Step 4: Use Medusa UI in Standalone Projects
You can now start building your application with Medusa UI.
For example, you can use the `Button` in your custom components:
```tsx ```tsx
import { Button, Drawer } from "@medusajs/ui" import { Button } from "@medusajs/ui"
export function ButtonDemo() {
return <Button>Button</Button>
}
``` ```
Refer to the documentation of each component to learn about its props and usage.
<Feedback title={"Install in Standalone Project"} /> <Feedback title={"Install in Standalone Project"} />
## Updating UI Packages
--- ---
Medusa's design-system packages, including `@medusajs/ui`, `@medusajs/ui-preset`, and `@medusajs/ui-icons`, are versioned independently. However, they're still part of the latest Medusa release. So, you can browse the [release notes](https://github.com/medusajs/medusa/releases) to see if there are any breaking changes to these packages. ## Update UI Packages in Standalone Projects
To update these packages, update their version in your `package.json` file and re-install dependencies. For example: Medusa's design-system packages, including `@medusajs/ui` and `@medusajs/ui-preset`, are versioned independently from other `@medusajs/*` packages. However, they're still released as part of Medusa's releases.
<PackageInstall packageName="@medusajs/ui" /> So, to find latest updates and breaking changes to any of these packages, refer to the [release notes in the Medusa GitHub repository](https://github.com/medusajs/medusa/releases).
To update these packages in your standalone project, update their version in your `package.json` file and re-install dependencies. For example:
```json title="package.json"
{
"dependencies": {
"@medusajs/ui": "4.0.0",
"@medusajs/ui-preset": "4.0.0"
}
}
```