Mezo Clay is Mezo's UI component library.
npm install @mezo-org/mezo-clayMezo Clay is Mezo's UI component library.
This project uses pnpm for package management.
To install dependencies run:
``sh`
pnpm install
This project uses Storybook to view, develop and test UI components in isolation.
`sh`
pnpm run dev
Open http://localhost:6006/ to view it in the browser.
`shell`
pnpm run format
This will lint both config files and ts/tsx/js/jsx files. See the package.json for specific linting commands.
#### Pre-commit
The project includes a pre-commit hook to automate linting when you commit. Please refer to the docs to install.
Storybook automatically runs component tests for each story (if written as a play function) and are visible in the UI under the "Component Tests" tab. We've set up the test-addon to use Vitest as the test runner. You can also run all tests in the terminal:
`shell`
pnpm run test
Make sure to export your new component from src/components/index.ts. Then either run the generate exports script to update the package.json:
`shell`
pnpm run generate-exports
or manually add it to the exports section of package.json like:
`json`
"exports": {
...
"./my-component": {
"types": "./dist/components/my-component/index.d.ts",
"default": "./dist/components/my-component/index.js"
},
}
These steps make sure the component is included in the Clay package and make it available as a subpath export.
#### Build storybook
`shell`
pnpm run build
The storybook build will be generated as the /storybook-static directory.
#### Build the library
`shell`
pnpm run build:lib
The library is output as the /dist directory.
Before you build and publish to NPM, you'll want to increment the version in package.json.
#### Build the library (same as above)
`shell`
pnpm run build:lib
#### Login to NPM
`shell`
pnpm login
#### Test the Built Package Locally
Use pnpm pack to build a .tgz file that you can link to from your test application.
#### Publish
`shell`
pnpm publish --access public
__Note__: You can use the --dry-run flag on publish if you want to preview what will be included in the release package without actually publishing.
Check out your new release on the npm page.
`shell`
pnpm add @mezo-org/mezo-clay
Add peer dependencies:
`shell`
pnpm add baseui@0.0.0-next-18f01efe0 "react@^18.3.1" "react-dom@^18.3.1" "styletron-engine-monolithic@^1.0.0"
"styletron-react@^6.1.1"
Wrap the root of your app with the ClayProvider component, like so:
`js
import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
import { ClayLightTheme, ClayProvider } from "@mezo-org/mezo-clay"
import "@mezo-org/mezo-clay/fonts.css" // Font styles
import App from "./App.tsx"
createRoot(document.getElementById('root')!).render(
,
)
`
Import the @mezo-org/mezo-clay/fonts.css to ensure that the proper fonts are included.
The Clay package supports both barrel style and subpath imports:
`js
// Import components (barrel style - backward compatible)
import { Button, Input } from "@mezo-org/mezo-clay"
import { ClayProvider, ClayLightTheme } from "@mezo-org/mezo-clay"
// Or use subpath imports (better for tree-shaking)
import { Button } from "@mezo-org/mezo-clay/button"
import { Input } from "@mezo-org/mezo-clay/input"
`
> Note: Clay currently supports the Pages Router only. Clay is built on Base UI, which uses Styletron (a runtime CSS-in-JS library). Styletron requires React Context and hooks to generate styles at runtime, making it incompatible with React Server Components used in the App Router.
#### 1. Setup SSR in _document.tsx
`tsx
import { styletronSheet } from "@mezo-org/mezo-clay/ssr"
import { DocumentContext, Head, Html, Main, NextScript } from "next/document"
import type { DocumentProps } from "next/document"
export default function Document(props: DocumentProps) {
return (
Document.getInitialProps = async (ctx: DocumentContext) => {
const engine = styletronSheet.getStyletronEngine()
const page = await ctx.renderPage({
enhanceApp: (App) => (props) =>
})
return {
...await ctx.defaultGetInitialProps(ctx),
...page,
styletronSheets: styletronSheet.getStylesheets(engine)
}
}
`
#### 2. Setup ClayProvider in _app.tsx
`tsx
import { ClayProvider, ClayLightTheme } from "@mezo-org/mezo-clay"
import { styletronSheet } from "@mezo-org/mezo-clay/ssr"
import type { AppProps } from "next/app"
import { useMemo } from "react"
import "@mezo-org/mezo-clay/fonts.css"
interface CustomAppProps extends AppProps {
styletronEngine?: any
}
export default function App({
Component,
pageProps,
styletronEngine
}: CustomAppProps) {
const engine = useMemo(
() => styletronEngine ?? styletronSheet.getStyletronEngine(),
[styletronEngine]
)
return (
)
}
`
#### 3. Use Subpath Imports (Required for SSR)
`tsx
// ✅ Use subpath imports for SSR compatibility
import { Button } from "@mezo-org/mezo-clay/button"
import { Input } from "@mezo-org/mezo-clay/input"
import { HeadingLarge } from "@mezo-org/mezo-clay/typography"
import { useStyletron } from "@mezo-org/mezo-clay/styles"
// ❌ Avoid barrel imports in SSR contexts
import { Button, Input, HeadingLarge, useStyletron } from "@mezo-org/mezo-clay"
`
Non-SSR-safe components (Modal, Snackbar, Dropdown) must use dynamic(() => import(...), { ssr: false })`.