# Setup

## Package Dependencies

```json
{
  "@theorchard/suite-frontend": "^9.x",
  "@theorchard/suite-components": "^13.x",
  "@theorchard/suite-theming": "^4.x",
  "@theorchard/suite-icons": "^7.x"
}
```

## Vite Config

Install the SCSS glob plugin:

```
pnpm add vite-plugin-sass-glob-import
```

**`vite.config.ts`**
```ts
import { defineConfig } from 'vite'
import path from 'path'
import tailwindcss from '@tailwindcss/vite'
import react from '@vitejs/plugin-react'
import sassGlobImports from 'vite-plugin-sass-glob-import';


function figmaAssetResolver() {
  return {
    name: 'figma-asset-resolver',
    resolveId(id) {
      if (id.startsWith('figma:asset/')) {
        const filename = id.replace('figma:asset/', '')
        return path.resolve(__dirname, 'src/assets', filename)
      }
    },
  }
}

export default defineConfig({
  plugins: [
    sassGlobImports(),
    figmaAssetResolver(),
    // The React and Tailwind plugins are both required for Make, even if
    // Tailwind is not being actively used – do not remove them
    react(),
    tailwindcss(),
  ],
  resolve: {
    alias: {
      // Alias @ to the src directory
      '@': path.resolve(__dirname, './src'),
    }
  },
  css: {
    preprocessorOptions: {
      scss: {
        quietDeps: true,
        silenceDeprecations: ['import' as any],
      },
    },
  },
  // File types to support raw imports. Never add .css, .tsx, or .ts files to this.
  assetsInclude: ['**/*.svg', '**/*.csv'],
})

```

`sassGlobImports()` enables `@import '../app/components/**/*.scss'` glob patterns in SCSS files. The `quietDeps` and `silenceDeprecations` options suppress deprecation warnings from suite dependency SCSS.

## CSS Import

Suite styles MUST be imported via SCSS. Import `index.scss` from `App.tsx`:

**`src/styles/index.scss`**
```scss
@import '@theorchard/suite-frontend/styles';
@import '@theorchard/suite-components/styles';
@import '@theorchard/suite-icons/styles';

/* app component styles */
@import '../app/components/**/*.scss';
```

**`src/app/App.tsx`**
```tsx
import '../styles/index.scss';

export default function App() {
  // ...
}
```

Do NOT import individual component style files — the `styles` entry point on each package covers everything for that package.

## ThemeProvider Setup

Every app MUST wrap its root in `ThemeProvider`. Without it, brand colour tokens are not applied.

```tsx
import { ThemeProvider } from '@theorchard/suite-theming';

const config = {
  appName: 'my-app',
  brand: 'orchard',   // 'orchard' | 'awal' | 'sme' | 'knr'
  cdnUrl: 'https://cdn.example.com',
};

export default function App() {
  return (
    <ThemeProvider config={config}>
      {/* rest of the app */}
    </ThemeProvider>
  );
}
```

`config.brand` is optional — omitting it defaults to `'orchard'`.

### Available Brands

| `brand` value | Theme |
|---|---|
| `'orchard'` (default) | The Orchard — blue/midnight palette |
| `'awal'` | AWAL |
| `'sme'` | Sony Music Entertainment |
| `'knr'` | KNR |

## Component Imports

Components come from two packages depending on the component type:

```tsx
// UI components
import { Button, Alert, Select, Modal, DatePicker } from '@theorchard/suite-components';

// Page-level layout
import { Page } from '@theorchard/suite-frontend';

// Icons (GlyphIcon, AppIcon, BrandIcon, StoreIcon, NavIcon)
import { AppIcon, GlyphIcon } from '@theorchard/suite-icons';

// Theming
import { ThemeProvider, ThemeContext, useTheme, themes } from '@theorchard/suite-theming';
```

**`Page` comes from `@theorchard/suite-frontend`**, not from `@theorchard/suite-components`.

**Icons come from `@theorchard/suite-icons`** — they are also re-exported from `@theorchard/suite-components` for convenience, but the canonical import is `@theorchard/suite-icons`.

## Font

The design system uses **Rubik** as the primary typeface. Load it from your CDN before rendering:

```html
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link href="https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500&display=swap" rel="stylesheet" />
```

Without Rubik loaded, the system falls back to system sans-serif fonts.

## Tailwind CSS

The Figma Make app runs Tailwind CSS v4 alongside suite components. The two coexist — suite components use SCSS/CSS custom properties; shadcn/ui components (in `src/app/components/ui/`) use Tailwind utility classes.

**`src/styles/tailwind.css`**
```css
@import 'tailwindcss' source(none);
@source '../**/*.{js,ts,jsx,tsx}';
@import 'tw-animate-css';
```

The shadcn theme CSS (`theme.css`) is intentionally kept commented out — the Orchard suite tokens take precedence.

## Router

Components that use links (`Breadcrumb`, `Alert` with `link` prop, `MainNav`) require a router in the tree.

```tsx
import { BrowserRouter } from 'react-router-dom';

<BrowserRouter>
  <ThemeProvider config={config}>
    <App />
  </ThemeProvider>
</BrowserRouter>
```

## Reading / Setting Theme at Runtime

Two options — prefer the hook, use the context directly only when inside a non-React-hook context:

```tsx
// Option 1: hook (preferred)
import { useTheme } from '@theorchard/suite-theming';

const MyComponent = () => {
  const { theme, setTheme } = useTheme();
  return <div>Current brand: {theme}</div>;
};

// Option 2: context (e.g. class components or when hook is unavailable)
import { useContext } from 'react';
import { ThemeContext } from '@theorchard/suite-theming';

const MyComponent = () => {
  const { theme, setTheme } = useContext(ThemeContext);
  return <div>{theme}</div>;
};
```

## ThemeSwitcher Pattern

To let users switch the brand theme at runtime, use the `Select` component with the exported `themes` map:

```tsx
import { Select } from '@theorchard/suite-components';
import { ThemeContext, themes } from '@theorchard/suite-theming';
import { useContext } from 'react';

const ThemeSwitcher = () => {
  const { theme, setTheme } = useContext(ThemeContext);

  const options = Object.keys(themes).map(key => ({ label: key, value: key }));

  return (
    <Select
      options={options}
      onChange={option => setTheme(option.value)}
      selectedValue={options.find(o => o.value === theme)}
      placeholder="Select theme"
      hideFilter
      hideClearButton
    />
  );
};
```
