@mezo-org/mezo-clay
v0.2.0-dev.1
Published
Mezo Clay is Mezo's UI component library.
Maintainers
Keywords
Readme
Mezo Clay
Mezo Clay is Mezo's UI component library.
Development
Installation
This project uses pnpm for package management.
To install dependencies run:
pnpm installRun the development server
This project uses Storybook to view, develop and test UI components in isolation.
pnpm run devOpen http://localhost:6006/ to view it in the browser.
Linting
pnpm run formatThis 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.
Testing
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:
pnpm run testCreating new components
Make sure to export your new component from src/components/index.ts. Then either run the generate exports script to update the package.json:
pnpm run generate-exportsor manually add it to the exports section of package.json like:
"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
Build storybook
pnpm run buildThe storybook build will be generated as the /storybook-static directory.
Build the library
pnpm run build:libThe library is output as the /dist directory.
Publishing to NPM
Before you build and publish to NPM, you'll want to increment the version in package.json.
Build the library (same as above)
pnpm run build:libLogin to NPM
pnpm loginTest the Built Package Locally
Use pnpm pack to build a .tgz file that you can link to from your test application.
Publish
pnpm publish --access publicNote: 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.
Using Clay
Install
pnpm add @mezo-org/mezo-clayAdd peer dependencies:
pnpm add [email protected] "react@^18.3.1" "react-dom@^18.3.1" "styletron-engine-monolithic@^1.0.0"
"styletron-react@^6.1.1"Adding Clay to your React app
Wrap the root of your app with the ClayProvider component, like so:
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(
<StrictMode>
<ClayProvider theme={ClayLightTheme}>
<App />
</ClayProvider>
</StrictMode>
,
)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:
// 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"Adding Clay to Next.js
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
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 (
<Html>
<Head>
{/* Pass the styletron stylesheets to the <head> */}
{props.__NEXT_DATA__.props?.styletronSheets}
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
Document.getInitialProps = async (ctx: DocumentContext) => {
const engine = styletronSheet.getStyletronEngine()
const page = await ctx.renderPage({
enhanceApp: (App) => (props) => <App {...props} styletronEngine={engine} />
})
return {
...await ctx.defaultGetInitialProps(ctx),
...page,
styletronSheets: styletronSheet.getStylesheets(engine)
}
}2. Setup ClayProvider in _app.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 (
<ClayProvider theme={ClayLightTheme} engine={engine}>
<Component {...pageProps} />
</ClayProvider>
)
}3. Use Subpath Imports (Required for SSR)
// ✅ 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 }).
