# Getting Started

> Install @dev-bench/gitapp-ui and wire up your first selector.

Source: https://components.n.yatsyk.com/docs/gitapp-ui/getting-started

# Getting Started

## 1. Install

```bash
pnpm add @dev-bench/gitapp-ui react react-native react-native-svg
```

For `react-native-web` apps, also ensure `react-native-web` and your bundler's
RN ↔ web aliases are in place — this package only renders RN primitives, so
the web alias is what makes it work in a browser.

## 2. Wrap the app in `ThemeProvider`

`ThemeProvider` injects design tokens (colors, fonts, radii, spacing). Every
component in this package reads from it via `useTheme()` — there are no
hardcoded colors.

```tsx
import { ThemeProvider, defaultLightTheme } from "@dev-bench/gitapp-ui";

export function Root({ children }) {
  return <ThemeProvider theme={defaultLightTheme}>{children}</ThemeProvider>;
}
```

To override a token (brand color, font), pass a partial theme through
`mergeTheme`:

```tsx
import { ThemeProvider, defaultLightTheme, mergeTheme } from "@dev-bench/gitapp-ui";

const brandTheme = mergeTheme(defaultLightTheme, {
  colors: { brand: "#7c3aed", brandBg: "#f5f3ff" },
});

<ThemeProvider theme={brandTheme}>...</ThemeProvider>
```

## 3. Drive a selector with a `Resource<T>` view-model

Every selector takes a single `model` prop. The model exposes the current
value plus a `Resource<T>` that tracks the lifecycle of the most recent action.
Use the constructors on `Resource` — they encode the four canonical states.

```ts
import { Resource } from "@dev-bench/gitapp-ui";

Resource.idle();                        // nothing happening
Resource.loading();                     // pending request
Resource.ready(undefined);              // success
Resource.error({ message: "503 from github.com" });
```

A minimal MobX view-model for `ProviderSelector`:

```ts
import { makeAutoObservable, runInAction } from "mobx";
import { Resource, type IProviderSelectorModel } from "@dev-bench/gitapp-ui";

export class ProviderModel implements IProviderSelectorModel {
  current = { provider: "github" as const, host: "github.com" };
  state = Resource.idle<void>();
  isOpen = true;

  constructor(private readonly api: { saveProvider(p, h): Promise<void> }) {
    makeAutoObservable(this);
  }

  onSelectProvider(p) { this.current = { ...this.current, provider: p }; }
  onCustomHostChange(host) { this.current = { ...this.current, host }; }
  onDismiss() { this.isOpen = false; }

  async onConfirm() {
    this.state = Resource.loading();
    try {
      await this.api.saveProvider(this.current.provider, this.current.host);
      runInAction(() => { this.state = Resource.ready(undefined); });
    } catch (e) {
      runInAction(() => {
        this.state = Resource.error({ message: e instanceof Error ? e.message : String(e) });
      });
    }
  }
}
```

## 4. Render the selector

Wrap the component in MobX's `observer` so the selector reacts to model
changes:

```tsx
import { observer } from "mobx-react-lite";
import { ProviderSelector } from "@dev-bench/gitapp-ui";

export const ProviderScreen = observer(({ model }: { model: ProviderModel }) => (
  <ProviderSelector model={model} />
));
```

You don't have to use MobX — any reactive store (Zustand, Jotai, plain React
state) that produces a fresh model object on update will work, as long as it
hands the component a model implementing the interface.

## 5. Add a repo picker

`RepoPickerSheet` follows the same shape — feed it a model with `repos`,
`selected`, and the lifecycle `state`:

```tsx
import { RepoPickerSheet, type IRepoPickerModel } from "@dev-bench/gitapp-ui";

export const RepoPickerScreen = observer(({ model }: { model: IRepoPickerModel }) => (
  <RepoPickerSheet model={model} />
));
```

See the [API reference](./api.mdx) for `ConnectionPanel`, primitives, and the
exported types.
