# Oranguru Integration Guide ## Overview Oranguru is a React component library that provides enhanced Mantine-based components with advanced features and state management capabilities. For WhatsHooked, we'll use it to build data grids and forms for the admin interface. ## Installation ```bash npm install @warkypublic/oranguru ``` ### Peer Dependencies ```bash npm install react zustand @mantine/core @mantine/hooks @warkypublic/artemis-kit @warkypublic/zustandsyncstore use-sync-external-store ``` ## Core Concepts ### Enhanced Context Menus Oranguru provides better menu positioning and visibility control than standard Mantine menus. ### Custom Rendering Support for custom menu item renderers and complete menu rendering. ### State Management Uses Zustand for component state management with sync capabilities. ## Basic Setup ```tsx import { MantineBetterMenusProvider } from '@warkypublic/oranguru'; import { MantineProvider } from '@mantine/core'; function App() { return ( {/* Your app content */} ); } ``` ## Using Context Menus ```tsx import { useMantineBetterMenus } from '@warkypublic/oranguru'; function DataGrid() { const { show, hide } = useMantineBetterMenus(); const handleContextMenu = (e: React.MouseEvent, record: any) => { e.preventDefault(); show('record-menu', { x: e.clientX, y: e.clientY, items: [ { label: 'Edit', onClick: () => handleEdit(record) }, { label: 'Delete', onClick: () => handleDelete(record) }, { isDivider: true }, { label: 'View Details', onClick: () => handleViewDetails(record) } ] }); }; return ( {records.map(record => ( handleContextMenu(e, record)}> ))}
{record.name}
); } ``` ## Async Actions ```tsx const asyncMenuItem = { label: 'Sync Data', onClickAsync: async () => { await fetch('/api/sync', { method: 'POST' }); // Shows loading state automatically } }; ``` ## Custom Menu Items ```tsx const customItem = { renderer: ({ loading }: any) => (
{loading ? ( ) : ( Custom Action )}
), onClickAsync: async () => { await performAction(); } }; ``` ## Integration with Data Grids While Oranguru doesn't provide a built-in data grid component yet, it works excellently with Mantine's DataTable or custom table implementations: ```tsx import { useMantineBetterMenus } from '@warkypublic/oranguru'; import { DataTable } from '@mantine/datatable'; function UserGrid() { const { show } = useMantineBetterMenus(); const [users, setUsers] = useState([]); const columns = [ { accessor: 'name', title: 'Name' }, { accessor: 'email', title: 'Email' }, { accessor: 'status', title: 'Status' } ]; const handleRowContextMenu = (e: React.MouseEvent, user: User) => { e.preventDefault(); show('user-menu', { x: e.clientX, y: e.clientY, items: [ { label: 'Edit User', onClick: () => navigate(`/users/${user.id}/edit`) }, { label: 'Deactivate', onClickAsync: async () => { await fetch(`/api/users/${user.id}/deactivate`, { method: 'POST' }); await refreshUsers(); } }, { isDivider: true }, { label: 'Delete', onClick: () => handleDelete(user.id) } ] }); }; return ( handleRowContextMenu(event, record)} /> ); } ``` ## Form Integration For forms, use Mantine's form components with Oranguru's menu system for enhanced UX: ```tsx import { useForm } from '@mantine/form'; import { TextInput, Select, Button } from '@mantine/core'; function UserForm() { const form = useForm({ initialValues: { name: '', email: '', role: '' }, validate: { email: (value) => (/^\S+@\S+$/.test(value) ? null : 'Invalid email'), name: (value) => (value.length < 2 ? 'Name too short' : null) } }); const handleSubmit = async (values: typeof form.values) => { try { await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(values) }); notifications.show({ message: 'User created successfully' }); } catch (error) { notifications.show({ message: 'Failed to create user', color: 'red' }); } }; return (