npm package: @lax-wp/design-system
Description: A comprehensive React + TypeScript design system built with Vite, providing reusable UI components for the LAX web portal applications. Features a complete set of form components, data display elements, and interactive controls with full TypeScript suppor
Latest version: 0.11.1

# LAX Web Portal Design System

A comprehensive React + TypeScript design system built with Vite, providing reusable UI components for the LAX web portal applications. Features a complete set of form components, data display elements, and interactive controls with full TypeScript support, accessibility features, and dark mode compatibility.

## 🎨 Features

- **📦 Comprehensive Component Library**: Form inputs, toggles, date ranges, currency fields, and more
- **📚 Storybook Documentation**: Interactive component documentation with live examples
- **🎯 TypeScript Support**: Full type safety with comprehensive interfaces and JSDoc
- **⚡ Fast Development**: Vite + HMR for lightning-fast development experience
- **🌙 Dark Mode**: Complete dark theme support across all components
- **♿ Accessibility**: ARIA attributes, keyboard navigation, and screen reader support
- **🎭 Animations**: Smooth transitions using Framer Motion
- **🔧 ESLint Configuration**: Consistent code quality and formatting
- **📱 Responsive Design**: Mobile-first responsive components
- **🎪 Interactive Stories**: Comprehensive Storybook examples with playgrounds

## 📚 Component Library

### Form Components

- **InputField**: Basic text input with validation
- **TextField**: Enhanced text input with additional features
- **CurrencyInputField**: Currency input with multi-currency support
- **PercentageInputField**: Percentage input with constraints and validation
- **DebounceInputField**: Debounced input for search and real-time scenarios
- **DateRange**: Date range picker with validation
- **Checkbox**: Customizable checkbox with multiple variants
- **Toggle**: Switch component with icons and flexible positioning
- **ColorPicker**: Color selection with multiple format support
- **CreatableSelect**: Enhanced select with creation capabilities

### Data Display

- **Typography**: Consistent text styling component

## 🚀 Getting Started

### Prerequisites

- Node.js 18+
- npm or yarn package manager

### Installation

```bash
# Clone the repository
git clone <repository-url>
cd lax-wp-design-system

# Install dependencies
npm install
```

### Development

Start the development server with hot module replacement:

```bash
npm run dev
```

This will start the Vite development server at `http://localhost:5173`

### Storybook

Run Storybook for interactive component documentation:

```bash
npm run storybook
```

Storybook will be available at `http://localhost:6006`

### Build

Build the library for production:

```bash
npm run build
```

This generates:

- `dist/` - Built library files
- Type declarations for TypeScript support

## 🔧 Local Development with Yalc

[Yalc](https://github.com/wclr/yalc) is a tool for working with npm packages locally. It's perfect for testing your design system changes in other React applications before publishing.

### Installing Yalc

```bash
# Install yalc globally
npm install -g yalc
```

### Setting Up the Design System for Local Development

1. **Build and publish locally:**

   ```bash
   # In the design system directory
   npm run build
   yalc publish
   ```

2. **Watch for changes (optional):**

   ```bash
   # Run this in a separate terminal for auto-rebuild on changes
   npm run build --watch
   ```

### Using the Design System in Another React App

1. **Add the local package:**

   ```bash
   # In your React app directory
   yalc add @lax-wp/design-system
   npm install
   ```

2. **Import and use components:**

   ```tsx
   // In your React app
   import {
     CurrencyInputField,
     Toggle,
     DateRange,
     DebounceInputField,
     PercentageInputField,
     ColorPicker,
     Checkbox,
     CreatableSelectField,
   } from "@lax-wp/design-system";

   function App() {
     const [currency, setCurrency] = useState<number | null>(null);
     const [isEnabled, setIsEnabled] = useState(false);

     return (
       <div className="p-6">
         <CurrencyInputField
           id="price"
           label="Product Price"
           value={currency}
           onChange={(value, currencyCode) => setCurrency(value)}
           allowCurrencyChange
           required
         />

         <Toggle
           id="notifications"
           label="Enable Notifications"
           checked={isEnabled}
           onChange={setIsEnabled}
         />
       </div>
     );
   }
   ```

3. **Include Tailwind CSS:**
   The design system uses Tailwind CSS. Make sure your React app has Tailwind configured with the same classes. Add to your `tailwind.config.js`:

   ```js
   module.exports = {
     content: [
       "./src/**/*.{js,jsx,ts,tsx}",
       "./node_modules/@lax-wp/design-system/dist/**/*.{js,jsx,ts,tsx}",
     ],
     theme: {
       extend: {
         colors: {
           primary: {
             50: "#eff6ff",
             500: "#3b82f6",
             600: "#2563eb",
             // ... add your color palette
           },
         },
       },
     },
   };
   ```

### Updating the Local Package

When you make changes to the design system:

1. **Rebuild and update:**

   ```bash
   # In the design system directory
   npm run build
   yalc push
   ```

2. **The changes will be automatically updated in your React app!**

### Removing the Local Package

When you're done with local development:

```bash
# In your React app directory
yalc remove @lax-wp/design-system
npm install @lax-wp/design-system  # Install from npm registry
```

## 📱 Usage Examples

### Basic Form with Validation

```tsx
import { useState } from "react";
import {
  CurrencyInputField,
  PercentageInputField,
  DateRange,
  Toggle,
  type DateRangeValue,
} from "@lax-wp/design-system";

function PricingForm() {
  const [price, setPrice] = useState<number | null>(null);
  const [discount, setDiscount] = useState<number | null>(null);
  const [dateRange, setDateRange] = useState<DateRangeValue>({
    startDate: null,
    endDate: null,
  });
  const [isActive, setIsActive] = useState(false);

  const isValid =
    price && price > 0 && dateRange.startDate && dateRange.endDate;

  return (
    <form className="space-y-4 max-w-md">
      <CurrencyInputField
        id="price"
        label="Product Price"
        value={price}
        onChange={(value) => setPrice(value)}
        currencyCode="USD"
        allowCurrencyChange
        required
        message={price === null ? "Price is required" : undefined}
        messageType={price === null ? "error" : "default"}
      />

      <PercentageInputField
        id="discount"
        label="Discount Rate"
        value={discount}
        onChange={setDiscount}
        min={0}
        max={50}
        helpText="Maximum discount allowed is 50%"
      />

      <DateRange
        id="validity"
        label="Validity Period"
        value={dateRange}
        onChange={setDateRange}
        required
        minDate={new Date()}
      />

      <Toggle
        id="active"
        label="Activate Pricing"
        checked={isActive}
        onChange={setIsActive}
        disabled={!isValid}
        message={isValid ? "Ready to activate" : "Complete all fields first"}
        messageType={isValid ? "success" : "info"}
      />

      <button
        type="submit"
        disabled={!isValid || !isActive}
        className="w-full py-2 px-4 bg-blue-600 text-white rounded disabled:opacity-50"
      >
        Save Pricing
      </button>
    </form>
  );
}
```

### Search with Debounced Input

```tsx
import { useState } from "react";
import { DebounceInputField } from "@lax-wp/design-system";

function SearchExample() {
  const [searchTerm, setSearchTerm] = useState("");
  const [results, setResults] = useState<string[]>([]);

  const handleSearch = async (term: string) => {
    if (!term.trim()) {
      setResults([]);
      return;
    }

    // Simulate API call
    const mockResults = await fetch(`/api/search?q=${term}`);
    const data = await mockResults.json();
    setResults(data);
  };

  return (
    <div>
      <DebounceInputField
        id="search"
        label="Search Products"
        type="search"
        value={searchTerm}
        onChange={(value) => {
          setSearchTerm(value);
          handleSearch(value);
        }}
        debounceTimeout={300}
        placeholder="Type to search..."
        helpText="Results appear as you type"
      />

      <div className="mt-4">
        {results.map((result, index) => (
          <div key={index} className="p-2 border-b">
            {result}
          </div>
        ))}
      </div>
    </div>
  );
}
```

## 🎨 Theming and Customization

### Using with Custom Themes

```tsx
// Add custom CSS variables for theming
:root {
  --primary-50: #eff6ff;
  --primary-500: #3b82f6;
  --primary-600: #2563eb;
  --error-500: #ef4444;
  --success-500: #10b981;
}

// Dark mode support
.dark {
  --primary-50: #1e40af;
  --primary-500: #60a5fa;
  --primary-600: #3b82f6;
}
```

### Custom Component Styling

```tsx
import { CurrencyInputField } from "@lax-wp/design-system";

function CustomStyledComponent() {
  return (
    <CurrencyInputField
      id="custom"
      label="Custom Styled Price"
      wrapperClassName="bg-gradient-to-r from-blue-50 to-purple-50 p-4 rounded-lg"
      inputClassName="border-2 border-purple-300 focus:border-purple-500"
      labelClassName="text-purple-800 font-bold"
      onChange={() => {}}
    />
  );
}
```

## 🔍 TypeScript Support

The design system is built with TypeScript and provides comprehensive type definitions:

```tsx
import type {
  CurrencyInputFieldProps,
  DateRangeValue,
  ToggleProps,
  SelectOption,
} from "@lax-wp/design-system";

// All props are fully typed
const config: CurrencyInputFieldProps = {
  id: "price",
  label: "Price",
  onChange: (value: number | null, currency: string) => {
    // TypeScript knows the exact types here
    console.log(`Price: ${value}, Currency: ${currency}`);
  },
};

// Type-safe option handling
const options: SelectOption[] = [
  { value: "option1", label: "Option 1" },
  { value: "option2", label: "Option 2" },
];
```

## 🧪 Testing

### Running Tests

```bash
# Run unit tests
npm run test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage
```

### Testing with Your Application

When using yalc for local development, you can test your changes immediately:

1. Make changes to a component
2. Run `npm run build && yalc push`
3. Test in your React application
4. Iterate quickly without publishing to npm

## 📦 Publishing

### Preparing for Release

1. **Update version:**

   ```bash
   npm version patch  # or minor/major
   ```

2. **Build and test:**

   ```bash
   npm run build
   npm run test
   npm run storybook:build
   ```

3. **Publish to npm:**

   ```bash
   npm publish
   ```

### Semantic Versioning

- **Patch (1.0.1)**: Bug fixes, small improvements
- **Minor (1.1.0)**: New components, backward-compatible features
- **Major (2.0.0)**: Breaking changes, API modifications

## 🤝 Contributing

### Development Workflow

1. **Fork and clone** the repository
2. **Create a feature branch:** `git checkout -b feature/new-component`
3. **Make your changes** following the established patterns
4. **Add tests and stories** for new components
5. **Test locally** using yalc with your application
6. **Submit a pull request** with clear description

### Component Development Guidelines

- Follow existing patterns for props and structure
- Add comprehensive TypeScript types and JSDoc
- Include Storybook stories with multiple examples
- Ensure accessibility (ARIA attributes, keyboard navigation)
- Support dark mode with proper contrast
- Add animation support where appropriate
- Test with screen readers and keyboard-only navigation

### Code Quality

```bash
# Lint your code
npm run lint

# Fix linting issues
npm run lint:fix

# Check TypeScript
npm run type-check
```

## 📄 License

MIT License - see LICENSE file for details.

## 🆘 Support

- **Issues**: Report bugs and request features via GitHub Issues
- **Documentation**: Check Storybook for component examples
- **Development**: Use yalc for local testing and development

## 🔗 Related Projects

- **LAX Web Portal**: Main application using this design system
- **LAX Activity Logger**: Secondary application with shared components
- **LAX Flow Orchestrator**: Workflow management with design system integration

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default tseslint.config([
  globalIgnores(["dist"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      // Other configs...

      // Remove tseslint.configs.recommended and replace with this
      ...tseslint.configs.recommendedTypeChecked,
      // Alternatively, use this for stricter rules
      ...tseslint.configs.strictTypeChecked,
      // Optionally, add this for stylistic rules
      ...tseslint.configs.stylisticTypeChecked,

      // Other configs...
    ],
    languageOptions: {
      parserOptions: {
        project: ["./tsconfig.node.json", "./tsconfig.app.json"],
        tsconfigRootDir: import.meta.dirname,
      },
      // other options...
    },
  },
]);
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from "eslint-plugin-react-x";
import reactDom from "eslint-plugin-react-dom";

export default tseslint.config([
  globalIgnores(["dist"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      // Other configs...
      // Enable lint rules for React
      reactX.configs["recommended-typescript"],
      // Enable lint rules for React DOM
      reactDom.configs.recommended,
    ],
    languageOptions: {
      parserOptions: {
        project: ["./tsconfig.node.json", "./tsconfig.app.json"],
        tsconfigRootDir: import.meta.dirname,
      },
      // other options...
    },
  },
]);
```