npm.io
0.13.27 • Published 3d ago

@lax-wp/design-system

Licence
Version
0.13.27
Deps
7
Size
49.3 MB
Vulns
0
Weekly
0

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
# 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:

npm run dev

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

Storybook

Run Storybook for interactive component documentation:

npm run storybook

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

Build

Build the library for production:

npm run build

This generates:

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

Local Development with Yalc

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
# Install yalc globally
npm install -g yalc
Setting Up the Design System for Local Development
  1. Build and publish locally:

    # In the design system directory
    npm run build
    yalc publish
  2. Watch for changes (optional):

    # 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:

    # In your React app directory
    yalc add @lax-wp/design-system
    npm install
  2. Import and use components:

    // 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:

    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:

    # 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:

# 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
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
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
// 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
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:

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
# 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:

    npm version patch  # or minor/major
  2. Build and test:

    npm run build
    npm run test
    npm run storybook:build
  3. Publish to npm:

    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
# 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
  • 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:

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 and eslint-plugin-react-dom for React-specific lint rules:

// 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...
    },
  },
]);