npm.io
3.0.0-beta.1 • Published 1 week ago

@salla.sa/twilight-components-react

Licence
GPL-3.0
Version
3.0.0-beta.1
Deps
4
Size
710 kB
Vulns
0
Weekly
0

@salla.sa/twilight-components-react

React wrapper for Salla Twilight Web Components with full SSR support.

Installation

npm install @salla.sa/twilight-components-react
# or
pnpm add @salla.sa/twilight-components-react

Usage

Client-Side (CSR)
import { SallaButton, SallaModal, SallaAlert } from '@salla.sa/twilight-components-react';

function App() {
  return (
    <div>
      <SallaButton fill="solid" color="primary">
        Click Me
      </SallaButton>
      
      <SallaModal isOpen={false}>
        Modal Content
      </SallaModal>
    </div>
  );
}
Tree-Shaking (Optimized Imports)

The generated components include 'use client' directive for Next.js App Router compatibility. All imports are already optimized for tree-shaking:

// ✅ GOOD: Tree-shaking works automatically
import { SallaButton, SallaModal } from '@salla.sa/twilight-components-react';

// ❌ BAD: Imports everything (avoid this)
import * as Twilight from '@salla.sa/twilight-components-react';

Server-Side Rendering (SSR)

1. Next.js Setup
// components/SallaButton.tsx
import dynamic from 'next/dynamic';

export const SallaButton = dynamic(
  () => import('@salla.sa/twilight-components-react').then(mod => mod.SallaButton),
  { ssr: false }
);

// Usage
import { SallaButton } from '@/components/SallaButton';

export default function Page() {
  return <SallaButton>Add to Cart</SallaButton>;
}
Option B: Using 'use client' Directive (App Router)
// components/SallaProvider.tsx
'use client';

export { SallaButton, SallaModal, SallaAlert } from '@salla.sa/twilight-components-react';

// app/page.tsx (Server Component)
import { SallaButton } from '@/components/SallaProvider';

export default function Page() {
  return <SallaButton>Server Rendered Button</SallaButton>;
}
Option C: Full Hydration with Stencil Hydrate
// app/layout.tsx or pages/_document.tsx
import { hydrate } from '@salla.sa/twilight-components/hydrate';

// For App Router (layout.tsx)
export default async function RootLayout({ children }) {
  // Hydrate on server
  return (
    <html lang="en">
      <head>
        <script
          dangerouslySetInnerHTML={{
            __html: `
              import('@salla.sa/twilight-components/hydrate').then(m => m.hydrate());
            `
          }}
        />
      </head>
      <body>{children}</body>
    </html>
  );
}
2. Custom SSR Setup
// server.ts
import express from 'express';
import { hydrateToString } from '@salla.sa/twilight-components/hydrate';

const app = express();

app.get('*', async (req, res) => {
  const html = `
    <!DOCTYPE html>
    <html>
      <body>
        <salla-button>Add to Cart</salla-button>
      </body>
    </html>
  `;
  
  // Hydrate on server
  const hydratedHtml = await hydrateToString(html, '/');
  
  res.send(hydratedHtml);
});
3. Vite SSR Setup
// entry-server.ts
import { hydrateToString } from '@salla.sa/twilight-components/hydrate';

export async function render(url: string) {
  const html = `
    <div id="app">
      <salla-button>Click Me</salla-button>
    </div>
  `;
  
  return await hydrateToString(html, url);
}

Full SSR Example with Next.js

Step 1: Create Hydration Provider
// providers/SallaProvider.tsx
'use client';

import { useEffect } from 'react';

export function SallaProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    // Import and hydrate on client
    import('@salla.sa/twilight-components/hydrate').then(({ hydrate }) => {
      hydrate();
    });
  }, []);

  return <>{children}</>;
}
Step 2: Use in Layout
// app/layout.tsx
import { SallaProvider } from '@/providers/SallaProvider';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <SallaProvider>
          {children}
        </SallaProvider>
      </body>
    </html>
  );
}
Step 3: Use Components
// app/page.tsx
import { SallaButton, SallaProductCard } from '@salla.sa/twilight-components-react';

export default function Home() {
  return (
    <main>
      <SallaButton fill="solid" color="primary">
        Add to Cart
      </SallaButton>
      
      <SallaProductCard 
        product-id="123"
        show-quick-add
      />
    </main>
  );
}

Avoiding Hydration Mismatches

When using SSR with custom elements, wrap components to avoid hydration errors:

// components/SafeSalla.tsx
'use client';

import { useEffect, useState } from 'react';
import { SallaButton } from '@salla.sa/twilight-components-react';

export function SafeSallaButton(props: any) {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) {
    // Return placeholder during SSR
    return <button {...props}>{props.children}</button>;
  }

  return <SallaButton {...props} />;
}

Available Components

All components from @salla.sa/twilight-components are available as React components:

  • SallaButton - Customizable button
  • SallaModal - Modal dialog
  • SallaDrawer - Side drawer
  • SallaAlert - Alert notifications
  • SallaProductCard - Product card display
  • SallaCartSummary - Cart summary
  • SallaComments - Comments section
  • SallaReviews - Product reviews
  • And more...

Bundle Optimization

// ✅ Best - Tree-shake unused components
import { SallaButton } from '@salla.sa/twilight-components-react';
Component Groups (Bundles)

These components are bundled together for better caching:

Bundle Components
UI Core salla-button, salla-loading, salla-modal, salla-drawer, salla-accordion, salla-breadcrumb
Forms salla-file-upload, salla-datetime-picker, salla-color-picker, salla-conditional-fields, salla-tel-input, salla-quantity-input, salla-booking-field
Comments salla-comments, salla-comment-form, salla-comment-item, salla-reviews, salla-reviews-page, salla-reviews-summary, salla-rating-stars, salla-review-card
Product salla-add-product-button, salla-product-options, salla-product-availability, salla-quick-buy
Cart salla-cart-summary, salla-cart-item-offers
Alerts salla-alert, salla-bottom-alert

TypeScript Support

Full TypeScript support is included:

import type { JSX } from '@salla.sa/twilight-components';

interface ButtonProps extends JSX.SallaButton {
  onClick?: () => void;
}
  • @salla.sa/twilight-components - Native web components
  • @salla.sa/twilight-components/hydrate - SSR hydration utilities

Keywords