npm.io
1.0.0-beta.9 • Published 21h ago

@salla.sa/twilight-theme-engine

Licence
MIT
Version
1.0.0-beta.9
Deps
9
Size
2.3 MB
Vulns
0
Weekly
0

@salla.sa/twilight-theme-engine

Slim core engine for Salla React themes built on TanStack Start.

Installation

npm install @salla.sa/twilight-theme-engine

Features

  • Component Registry - Dynamic component resolution with override support
  • Hook System - Extension points for content injection
  • Data Contexts - Store, Theme, User providers
  • i18n - Translation and RTL support
  • Utilities - Money formatting, asset helpers, color utilities

Documentation

Quick Start

Setup Providers
import { TwilightProvider } from '@salla.sa/twilight-theme-engine';
import { I18nProvider } from '@salla.sa/twilight-theme-engine/i18n';

function App() {
  return (
    <TwilightProvider storeIdentifier="my-store" defaultLocale="ar">
      <I18nProvider locale="ar" translations={translations}>
        {children}
      </I18nProvider>
    </TwilightProvider>
  );
}
Component Registry
import { registry, Component, defineComponent } from '@salla.sa/twilight-theme-engine';

// Register components
registry.register('header', Header);
registry.register('product.card', ProductCard);

// Override in custom theme
registry.override('header', CustomHeader);

// Use dynamically
<Component name="product.card" product={product} />;
Hook System
import { defineHooks } from '@salla.sa/twilight-theme-engine/hooks/HookRegistry';
import { HookSlot } from '@salla.sa/twilight-theme-engine/hooks/HookSlot';

// Define hooks
defineHooks({
  'body:start': () => <AnnouncementBar />,
  'product:form.end': ({ product }) => <TrustBadges />,
});

// Use in pages
<HookSlot name="product:form.end" context={{ product }} />;
Use Contexts
import { useStore } from '@salla.sa/twilight-theme-engine/hooks/useStore';
import { useTheme } from '@salla.sa/twilight-theme-engine/hooks/useTheme';
import { useTwilight } from '@salla.sa/twilight-theme-engine';

function MyComponent() {
  const store = useStore();
  const theme = useTheme();
  const { user, isRTL } = useTwilight();

  const setting = theme.settings.get('header_is_sticky', true);
}
Translations
import { useI18n } from '@salla.sa/twilight-theme-engine/i18n';

function MyComponent() {
  const { t } = useI18n();

  return (
    <div>
      <h1>{t('pages.cart.title')}</h1>
      <p>{t('pages.products.sold_times', { count: 5 })}</p>
    </div>
  );
}
Utilities
import { useMoney } from '@salla.sa/twilight-theme-engine/hooks/useMoney';
import { useAsset } from '@salla.sa/twilight-theme-engine/hooks/useAsset';

function ProductCard({ product, featured }) {
  const { formatMoney } = useMoney();
  const { asset, cdn } = useAsset();

  return (
    <div className={cn('card', featured && 'card--featured')}>
      <img src={cdn(product.image.url, 400)} />
      <p>{formatMoney(product.price)}</p>
    </div>
  );
}

Import Paths

Use granular imports to avoid pulling in the entire package:

// Core
import { TwilightProvider, useTwilight } from '@salla.sa/twilight-theme-engine';

// Hooks (granular)
import { useStore } from '@salla.sa/twilight-theme-engine/hooks/useStore';
import { useTheme } from '@salla.sa/twilight-theme-engine/hooks/useTheme';
import { useMoney } from '@salla.sa/twilight-theme-engine/hooks/useMoney';
import { useAsset } from '@salla.sa/twilight-theme-engine/hooks/useAsset';

// i18n
import {
  useI18n,
  I18nProvider,
  FALLBACK_LOCALE,
  getLanguageInfo,
} from '@salla.sa/twilight-theme-engine/i18n';

// Components
import { Link } from '@salla.sa/twilight-theme-engine/common';

// Routes
import { Home } from '@salla.sa/twilight-theme-engine/routes/home';
import type { HomeLoaderData } from '@salla.sa/twilight-theme-engine/routes/home';

// API
import { store } from '@salla.sa/twilight-theme-engine/api/store';
import { translations } from '@salla.sa/twilight-theme-engine/api/translations';

// Types
import type { Store, Theme, Product } from '@salla.sa/twilight-theme-engine/types';

License

MIT

Keywords