@remodl/ui v1.0.29
@remodl/ui
Shared UI components for the Remodl ecosystem. This package provides a comprehensive set of React components optimized for Next.js applications.
Features
- šØ Modular Design: Tree-shakable component exports
- š Next.js Optimized: Built specifically for Next.js applications
- š¦ Dual Module Support: ESM and CommonJS builds
- šÆ TypeScript First: Full TypeScript support with type definitions
- šØ Tailwind CSS: Styled with Tailwind CSS and Radix UI primitives
- š§ Customizable: Built with tailwind-variants for easy theming
Compatibility
ā ļø Important: @remodl/ui is currently compatible with Next.js 14.x only.
- ā Next.js 14.x - Fully compatible
- ā Next.js 15.x - Not compatible (known issues with chart rendering)
This is due to changes in Next.js 15's server component handling and hydration behavior that affect client-side chart libraries like Recharts. We are working on Next.js 15 compatibility for a future release.
Installation
npm install @remodl/uiPeer Dependencies
This package requires the following peer dependencies:
npm install react react-dom @radix-ui/react-* lucide-react rechartsRequired Setup
1. Import Global Styles
Important: To ensure components render with the correct design language, you must import the global styles in your application:
/* In your app's global CSS file (e.g., app/globals.css) */
@import '@remodl/ui/styles/globals.css';Or in your root layout:
// app/layout.tsx
import '@remodl/ui/styles/globals.css';This provides:
- ā Inter font family
- ā Proper text colors and dark mode support
- ā Base Tailwind directives
- ā Essential design system foundation
2. Configure Tailwind CSS
Critical: You MUST add @remodl/ui to your Tailwind content configuration. Without this, the component styles will not be generated:
// tailwind.config.js or tailwind.config.ts
module.exports = {
content: [
// ... your app's content paths
'./node_modules/@remodl/ui/dist/**/*.{js,ts,jsx,tsx}',
],
// ... rest of your config
}ā ļø Why this is required: @remodl/ui components use Tailwind utility classes. If Tailwind doesn't scan the package files, it won't generate the CSS for these utilities, resulting in unstyled or broken components.
Usage
Import Everything
import { Button, Input, Card } from '@remodl/ui';Import by Category (Tree-shakable)
import { Button } from '@remodl/ui/buttons';
import { Input, Label } from '@remodl/ui/forms';
import { Card, Table } from '@remodl/ui/display';
import { Tabs, Dropdown } from '@remodl/ui/navigation';
import { Layout, Container } from '@remodl/ui/layout';
import { SparkAreaChart } from '@remodl/ui/charts';
import { cn, focusRing } from '@remodl/ui/utils';
import { colors, spacing } from '@remodl/ui/styles';Using with State Management
@remodl/ui components are designed to be state-agnostic and work seamlessly with any state management solution. While components manage their own internal UI state (animations, transitions), you can easily integrate them with external state management for business logic and persistence.
Example: Using with Zustand
Here's how to use @remodl/ui components with Zustand for persistent state management:
// store.ts - Your Zustand store
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface AppStore {
// Track which banners have been dismissed
dismissedBanners: Record<string, boolean>;
dismissBanner: (bannerId: string) => void;
// Track notification preferences
notificationSettings: {
showAlerts: boolean;
emailNotifications: boolean;
};
updateNotificationSettings: (settings: Partial<AppStore['notificationSettings']>) => void;
}
export const useAppStore = create<AppStore>()(
persist(
(set) => ({
dismissedBanners: {},
dismissBanner: (bannerId) =>
set((state) => ({
dismissedBanners: {
...state.dismissedBanners,
[bannerId]: true,
},
})),
notificationSettings: {
showAlerts: true,
emailNotifications: false,
},
updateNotificationSettings: (settings) =>
set((state) => ({
notificationSettings: {
...state.notificationSettings,
...settings,
},
})),
}),
{
name: 'app-storage', // localStorage key
}
)
);// BannerContainer.tsx - Using @remodl/ui with Zustand
import { BasicBanner } from '@remodl/ui/display';
import { useAppStore } from './store';
export function WelcomeBanner() {
const { dismissedBanners, dismissBanner } = useAppStore();
// If banner was previously dismissed (persisted in localStorage), don't render
if (dismissedBanners['welcome-banner']) {
return null;
}
return (
<BasicBanner
title="Welcome to Remodl!"
message="Get started by exploring our documentation."
onDismiss={() => {
// Update Zustand store - this persists to localStorage
dismissBanner('welcome-banner');
}}
/>
);
}Key Principles
Separation of Concerns:
- @remodl/ui components handle UI state (animations, transitions, hover states)
- Your state management handles business logic (user preferences, data persistence)
No Conflicts:
- Component internal state is completely isolated
- External state management controls whether components render
- Both can coexist without interference
Progressive Enhancement:
- Start with basic components using local state
- Add persistence later without changing component code
- Mix stateful and stateless usage as needed
Other State Management Solutions
The same pattern works with any state management solution:
// Redux Toolkit
const bannerSlice = createSlice({
name: 'banners',
initialState: { dismissed: {} },
reducers: {
dismissBanner: (state, action) => {
state.dismissed[action.payload] = true;
}
}
});
// Jotai
const dismissedBannersAtom = atomWithStorage('dismissedBanners', {});
// Valtio
const appState = proxy({
dismissedBanners: {}
});The integration pattern remains the same: use your state management to control component visibility and persistence, while letting @remodl/ui handle the presentation layer.
Component Categories
/buttons- Button components and variants/forms- Form controls (inputs, labels, selects, etc.)/charts- Chart components (spark charts, progress circles)/display- Display components (cards, tables, dialogs)/navigation- Navigation components (tabs, dropdowns, breadcrumbs)/layout- Layout components (containers, grids, sections)/patterns- Complex component patterns from admin showcase/utils- Utility functions (className merging, focus rings)/styles- Style utilities and design tokens
Development
This package follows the proven patterns established by @lexiq/types for consistency across the Remodl ecosystem.
Building
npm run build # Build both ESM and CJS
npm run build:esm # Build ESM only
npm run build:cjs # Build CJS only
npm run clean # Clean dist folderLicense
MIT License - see LICENSE file for details.
Changelog
v1.0.18
- Fixed missing className prop on SparkAreaChart linearGradient element
- Discovered and documented Next.js 14.x compatibility requirement
- Charts now render correctly in Next.js 14.x environments
v1.0.9
- Fixed SparkAreaChart SSR hydration issue
- Replaced React.useId() with stable ID generation to prevent gradient reference mismatches
- Charts now render correctly in all Next.js environments
v1.0.8
- Moved all component dependencies from peerDependencies to dependencies
- Now includes: recharts, all Radix UI packages, lucide-react, and @remixicon/react
- Only React and React DOM remain as peer dependencies
- Consuming applications no longer need to manually install component dependencies
v1.0.6
- Added missing chart colors (rose, teal, orange, green) to chartUtils
- All original colors preserved plus new additions
v1.0.5
- Fixed chart components (SparkAreaChart, SparkBarChart, SparkLineChart) not rendering by adding stroke and fill utilities to Tailwind configuration
- Extended theme to properly support SVG stroke and fill colors
v1.0.4
- Initial release with complete component set from remodl-next
- Added critical Tailwind configuration documentation
Contributing
This package is part of the internal Remodl ecosystem. Components are extracted from battle-tested implementations in the Remodl platform.
4 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago