# @gostudent/shared-ui-library

A React component library built with React 18, TypeScript, Vite, and CSS Modules. Provides reusable UI components with multi-brand theme support for GS and SK.

## Tech Stack

- **React 18** - Modern React with hooks and concurrent features
- **TypeScript** - Type-safe component development
- **Vite** - Fast build tool and dev server
- **CSS Modules** - Scoped styling
- **Storybook** - Component development and documentation
- **Style Dictionary** - Design token pipeline from Figma

## Installation

```bash
npm install @gostudent/shared-ui-library
```

## Usage

### Importing Components

```tsx
import { Button } from '@gostudent/shared-ui-library';
import '@gostudent/shared-ui-library/themes/theme-gs.css'; // or theme-sk.css
import '@gostudent/shared-ui-library/themes/style.css';
```

### Using Components

```tsx
function App() {
  return (
    <Button variant="primary" size="md" onClick={() => console.log('Clicked!')}>
      Click Me
    </Button>
  );
}
```

### Brand Themes

The library supports two brand themes — GS and SK — applied via the `data-theme` attribute:

```tsx
<div data-theme="gs">
  <Button variant="primary">GS Button</Button>
</div>

<div data-theme="sk">
  <Button variant="primary">SK Button</Button>
</div>
```

Theme CSS files:
- `@gostudent/shared-ui-library/themes/theme-gs.css` — GoStudent brand
- `@gostudent/shared-ui-library/themes/theme-sk.css` — Studienkreis brand

All component styles reference CSS custom properties generated from design tokens. No hardcoded colors.

## Design Token Pipeline

Tokens are exported from Figma and processed via Style Dictionary.

### Running the pipeline

```bash
npm run build:tokens
```

Output: `src/tokens/output/{base,gs,sk}/`

Each output directory contains:
- `variables.css` — CSS custom properties
- `tokens.ts` / `tokens.js` — JS/TS exports
- `tokens.d.ts` — TypeScript declarations

### Token categories

| Category | Scope | Examples |
|---|---|---|
| Global Colours | `base` | `--grey-700`, `--functional-white` |
| Spacing | `base` | `--spacing-xxs`, `--spacing-xl` |
| Radius | `base` | `--radius-sm`, `--radius-lg` |
| Font (primitive) | `base` | `--font-family-worksans`, `--font-size-sm`, `--font-weight-medium` |
| Semantic Font (desktop) | `base` | `--font-desktop-heading-font-size-h1`, `--font-desktop-button-primary-secondary-font-size-md` |
| Semantic Font (mobile) | `base` | `--font-mobile-heading-font-size-h1` |
| Breakpoints | `base` | `--breakpoint-desktop-full-screen`, `--breakpoint-tablet-layout-grid-width` |
| Brand colours | `gs` | `--blue-500`, `--pink-50`, `--purple-500` |
| Brand colours | `sk` | `--blue-500`, `--red-500`, `--green-300` |

### Token imports

```ts
// CSS variables
import '@gostudent/shared-ui-library/tokens/base/variables.css';
import '@gostudent/shared-ui-library/tokens/gs/variables.css';

// JS/TS token objects
import { t } from '@gostudent/shared-ui-library/tokens/base';
import { t } from '@gostudent/shared-ui-library/tokens/gs';
```

### Syncing from Figma

1. In Figma: **Plugins > Development > Export Design Tokens** — downloads `figma-tokens.zip`
2. Extract into `figma-tokens/` (clean up any stale files no longer in the export)
3. Run `npm run build:tokens`

## Development

### Prerequisites

- Node.js 20+ and npm

### Setup

```bash
npm install
npm run dev          # Vite dev server
npm run storybook    # Storybook on port 6006
```

### Building

```bash
npm run build           # Build tokens + TypeScript + Vite
npm run build-storybook # Build Storybook static site
```

### Local development against a consuming app

There are two ways to use the library locally without publishing.

#### Option 1 — `file:` dependency (recommended for Vite/React apps)

In the consuming app's `package.json`:

```json
"@gostudent/shared-ui-library": "file:../shared-ui-library"
```

Then install and build:

```bash
# in shared-ui-library
npm run build        # or: npm run build -- --watch for continuous rebuild

# in consuming app
npm install          # links node_modules entry to the source directory
```

With `--watch`, every rebuild is immediately visible in the consuming app without any extra copy step.

#### Option 2 — `dev:copy` watch scripts (for webpack/legacy apps)

```bash
npm run dev:copy               # copies to ../web-app/legacy/node_modules/...
npm run dev:copy:student-app   # copies to ../student-app/node_modules/...
```

This watches for changes, builds on each change, and copies the output directly into the consuming app's `node_modules`. Minification is automatically disabled (faster rebuilds, readable output).

> **Note:** `dev:copy` skips automatically if the destination resolves to the source directory (e.g. when a `file:` dependency is already in place) and logs a message instead of crashing.

**Web-app requirements:**

The web-app's webpack config must handle CSS from `@gostudent` packages:

```js
// webpack config
{
  test: /\.css$/,
  include: /node_modules\/@gostudent/,
  use: ['style-loader', 'css-loader'],
}
```

And the web-app entry must import both the theme and component styles:

```ts
import '@gostudent/shared-ui-library/themes/theme-gs.css'; // or theme-sk.css
import '@gostudent/shared-ui-library/themes/style.css';
```

## Testing

```bash
npm test              # Watch mode
npm run test:ci       # Run once with coverage (JUnit + default reporters)
npm run test:coverage # Coverage report
```

Tests use Vitest + React Testing Library in a jsdom environment.

## Linting & Type Checking

```bash
npm run lint          # ESLint (max-warnings: 0)
npm run lint:fix      # Auto-fix ESLint issues
npm run type-check    # TypeScript check without emitting
```

## Project Structure

```
src/
├── components/          # Component library
│   └── Button/
│       ├── Button.tsx
│       ├── Button.module.css
│       ├── Button.stories.tsx
│       ├── Button.test.tsx
│       └── index.ts
├── themes/              # Brand theme files
│   ├── theme-gs.css
│   └── theme-sk.css
├── tokens/
│   └── output/          # Generated — do not edit manually
│       ├── base/        # Shared tokens (colours, spacing, radius, fonts, breakpoints)
│       ├── gs/          # GS brand colours
│       └── sk/          # SK brand colours
└── index.ts             # Library entry point

figma-tokens/            # Figma plugin token exports (source of truth)
scripts/
└── build-tokens.mjs     # Style Dictionary build script
```

## Creating New Components

> For the full step-by-step guide (token sync, Figma import, Storybook generation), see [confluence/contributing-components.md](confluence/contributing-components.md) or the [Confluence page](https://gostudent.atlassian.net/wiki/x/BQCPYw).

1. Create a folder in `src/components/ComponentName/`
2. Add the component files:
   - `ComponentName.tsx` — implementation
   - `ComponentName.module.css` — styles using CSS Modules
   - `ComponentName.stories.tsx` — Storybook stories
   - `ComponentName.test.tsx` — Vitest tests
   - `index.ts` — barrel export
3. Reference token CSS variables in styles:
   ```css
   .myComponent {
     background-color: var(--color-primary);
     color: var(--color-text-primary);
   }
   ```
4. Export from `src/index.ts`

## Available Components

- **Button** — Versatile button component with multiple variants and sizes

## CI/CD

GitLab CI stages:
1. **check** — lint, type-check, tests, version checks
2. **prerelease** — manual deploy for feature branches (`DT-*`, `A20-*`)
3. **release** — manual deploy from `master`

Published to npm as `@gostudent/shared-ui-library` via semantic-release.

## License

MIT
