Usage

Import patterns

Default import (all exports)

import { Button, Input, Card, Typography } from '@wavebooking/aqua-fusion';

Scoped imports (tree-shaking)

For smaller bundle sizes, import from specific entry points:

import { Button, Input } from '@wavebooking/aqua-fusion/components';
import { FormField, DataTable } from '@wavebooking/aqua-fusion/patterns';
import { useMediaQuery } from '@wavebooking/aqua-fusion/hooks';
import { palette, spacing } from '@wavebooking/aqua-fusion/foundations';

Component composition

Aqua Fusion components are designed to compose together:

import { Card, Typography, Button, Badge } from '@wavebooking/aqua-fusion';
 
function ProductCard({ title, price, status }) {
  return (
    <Card className="p-6">
      <div className="flex items-start justify-between">
        <Typography variant="h3">{title}</Typography>
        <Badge variant={status === 'active' ? 'success' : 'warning'}>
          {status}
        </Badge>
      </div>
      <Typography variant="body2" className="mt-2 text-content-secondary">
        ${price}
      </Typography>
      <Button variant="default" className="mt-4">
        Add to Cart
      </Button>
    </Card>
  );
}

Forms

Basic form with FormField

import { FormField, Button } from '@wavebooking/aqua-fusion';
 
function LoginForm() {
  return (
    <form className="space-y-4">
      <FormField label="Email" name="email" type="email" required />
      <FormField label="Password" name="password" type="password" required />
      <Button type="submit" variant="default" className="w-full">
        Sign In
      </Button>
    </form>
  );
}

With react-hook-form

import { useForm } from 'react-hook-form';
import { FormField, Button } from '@wavebooking/aqua-fusion';
 
function ContactForm() {
  const { register, handleSubmit, formState: { errors } } = useForm();
 
  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
      <FormField
        label="Name"
        error={errors.name?.message}
        {...register('name', { required: 'Name is required' })}
      />
      <FormField
        label="Email"
        type="email"
        error={errors.email?.message}
        {...register('email', { required: 'Email is required' })}
      />
      <Button type="submit" variant="default">
        Submit
      </Button>
    </form>
  );
}

Using the className prop

All components accept a className prop for additional styling:

<Button variant="default" className="w-full mt-4">
  Full Width Button
</Button>
 
<Card className="p-8 shadow-ui-lg">
  Custom padding and shadow
</Card>

Using with Next.js

Aqua Fusion components include the "use client" directive in the built output, so they work in both Server and Client components:

// This works in a Server Component
import { Typography, Card } from '@wavebooking/aqua-fusion';
 
export default function Page() {
  return (
    <Card>
      <Typography variant="h1">Server Rendered</Typography>
    </Card>
  );
}

For interactive components (Dialog, Toast, etc.), wrap them in a Client Component:

'use client';
 
import { Button, Dialog } from '@wavebooking/aqua-fusion';
import { useState } from 'react';
 
export function MyDialog() {
  const [open, setOpen] = useState(false);
 
  return (
    <>
      <Button onClick={() => setOpen(true)}>Open Dialog</Button>
      <Dialog open={open} onOpenChange={setOpen} title="Confirm">
        <p>Are you sure?</p>
      </Dialog>
    </>
  );
}

Icons

Always use the Icon component from Aqua Fusion. Never import directly from @heroicons/react:

// Correct
import { Icon } from '@wavebooking/aqua-fusion';
<Icon name="CheckCircleIcon" className="h-5 w-5 text-green-500" />
 
// Incorrect - do not do this
import { CheckCircleIcon } from '@heroicons/react/24/outline';