Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions packages/react-native-ui-lib/install-skills.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env node

'use strict';

const fs = require('fs');
const path = require('path');

const SKILL_NAME = 'uilib-codegen';
const SOURCE_DIR = path.join(__dirname, 'skills', SKILL_NAME);
const TARGET_DIR = path.join(process.cwd(), '.claude', 'skills', SKILL_NAME);

function copyDir(src, dest) {
fs.mkdirSync(dest, {recursive: true});
for (const entry of fs.readdirSync(src, {withFileTypes: true})) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
copyDir(srcPath, destPath);
} else {
fs.copyFileSync(srcPath, destPath);
}
}
}

if (!fs.existsSync(SOURCE_DIR)) {
process.stderr.write(`Error: skill source not found at ${SOURCE_DIR}\n`);
process.exit(1);
}

console.log(`Installing ${SKILL_NAME} Claude Code skill...`);
copyDir(SOURCE_DIR, TARGET_DIR);
console.log(`Done! Skill installed at ${TARGET_DIR}`);
console.log('Restart Claude Code to activate it.');
2 changes: 2 additions & 0 deletions packages/react-native-ui-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@
"node": ">=18"
},
"files": [
"skills",
"install-skills.js",
"*.js",
"*.d.ts",
"!scripts",
Expand Down
148 changes: 148 additions & 0 deletions packages/react-native-ui-lib/skills/uilib-codegen/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
name: uilib-codegen
description: Use when building React Native screens with react-native-ui-lib. Contains component lookup via node_modules API files, layout-to-component mapping, styling conventions (modifiers, design tokens, spacing), and component intent classification. Use when creating screens, looking up component props, choosing the right component for a UI pattern, or styling with the design system.
version: 1.0.0
---

# react-native-ui-lib — React Native UI Component Library

> **When to use**: Building any React Native screen or component using react-native-ui-lib. Use when creating screens, looking up component APIs, choosing the right component for a UI pattern, styling with modifiers and design tokens, or asking how to use any `react-native-ui-lib` component.

---

## What react-native-ui-lib is

- **Package**: `react-native-ui-lib` — a comprehensive React Native UI component library with 70+ components, a design token system, spacing presets, typography modifiers, and theming support.
- **Key principle**: Always use library components instead of building custom UI from scratch. If a component exists for a UI pattern, use it.
- **Docs**: https://wix.github.io/react-native-ui-lib/
- **Figma community file**: https://www.figma.com/community/file/1379775092983284111/rnui-library

---

## How to look up any component

```bash
# Step 1 — locate the package (monorepo-aware, run once per session)
UILIB_PATH="node_modules/react-native-ui-lib"
[ ! -d "$UILIB_PATH" ] && UILIB_PATH="../../node_modules/react-native-ui-lib"

# Step 2 — batch-read ALL needed API files in ONE call (fastest approach)
cat "$UILIB_PATH/src/components/button/button.api.json" \
"$UILIB_PATH/src/components/avatar/avatar.api.json" \
"$UILIB_PATH/src/components/text/text.api.json" \
"$UILIB_PATH/src/components/listItem/listItem.api.json" \
2>/dev/null
```

**Speed rule**: Read all N API files in a **single batched `cat` call** instead of one call per component. Never look up one component at a time.

### API file path patterns

Most components follow `<dir>/<dir>.api.json`. A few use a nested `api/` or `apis/` subdirectory:

| Component | API file path |
|-----------|--------------|
| Most components | `<name>/<name>.api.json` |
| `modal` | `modal/api/modal.api.json` |
| `picker` | `picker/api/picker.api.json`, `picker/api/pickerItem.api.json` |
| `tabController` | `tabController/apis/tabController.api.json`, `tabController/apis/tabBar.api.json`, `tabController/apis/tabPage.api.json` |
| `card` | `card/card.api.json`, `card/cardSection.api.json`, `card/cardImage.api.json` |
| `dialog` | `dialog/dialog.api.json`, `dialog/dialogHeader.api.json` |
| `wizard` | `wizard/wizard.api.json`, `wizard/wizardStep.api.json` |
| `listItem` | `listItem/listItem.api.json`, `listItem/listItemPart.api.json` |

**Fallback** — when the path is unknown, find it in one command:
```bash
find "$UILIB_PATH/src/components" -name "<component>*.api.json" 2>/dev/null
```

**No `.tsx`/`.ts` in node_modules** — only `.js` and `.d.ts` are compiled into the published package.

---

## Available components

actionBar, actionSheet, animatedImage, animatedScanner, avatar, badge, baseInput, button, card, carousel, checkbox, chip, chipsInput, colorPalette, colorPicker, colorSwatch, connectionStatusBar, dash, dateTimePicker, dialog, drawer, expandableSection, fadedScrollView, fader, featureHighlight, floatingButton, gradient, gridList, gridListItem, gridView, hint, icon, image, inputs, KeyboardAwareScrollView, listItem, loaderScreen, maskedInput, modal, numberInput, overlay, pageControl, panView, picker, pieChart, progressBar, progressiveImage, radioButton, radioGroup, screenFooter, scrollBar, searchInput, sectionsWheelPicker, segmentedControl, skeletonView, slider, sortableGridList, sortableList, stackAggregator, stateScreen, stepper, svgImage, switch, tabController, text, textArea, textField, timeline, toast, touchableOpacity, view, WheelPicker, wizard

---

## Core conventions

1. **Modifiers, not StyleSheet** — Layout, spacing, colors, and typography are expressed as component props. Use `StyleSheet` only for transforms and properties without a modifier equivalent. Full reference: [styling.md](./styling.md).

2. **Design tokens, not hardcoded values** — Use semantic color tokens (`$textDefault`, `$backgroundDefault`, etc.) or palette colors (`Colors.primary`, `Colors.grey30`). Never hardcode hex values. Full reference: [styling.md](./styling.md).

3. **Import from the library** — Never import `View`, `Text`, or `Button` from `react-native`; use `react-native-ui-lib` equivalents. Use `react-native` only for primitives the library doesn't wrap (`ScrollView`, `FlatList`, `Pressable`).

4. **Read the API file before using a component** — Always batch-read `.api.json` files. Never guess props.

5. **Include testID** on all interactive elements. Pattern: `[context].[element]`.

6. **Discovery loop** — For each component: classify (Capturing / Performing / Displaying / Reporting), read the `.api.json`, extrapolate all relevant props, then triage each prop as Inject (functional necessity) or Propose (contextual enhancement). Full method: [component-intelligence.md](./component-intelligence.md).

7. **Keyboard handling** — Screens with text inputs must wrap in `KeyboardAwareScrollView` from `react-native-ui-lib`.

---

## Layout-to-component mapping

**BEFORE writing any layout code**, scan the screen for these patterns and use the mapped component. If the component's default appearance doesn't match the target design, read its API file to find customization props rather than building the layout manually.

| Layout pattern | Component | Trigger | Notes |
|---|---|---|---|
| Grid of items | `GridView` | N×M layouts, iterating items into rows | Use `numColumns` + `renderCustomItem`. Never build grids with `FlatList numColumns` + manual slicing. Wrap in `ScrollView` when content may exceed viewport. |
| Sectioned list | `SortableList` / `listItem` | Lists with sections, drag-to-reorder | Use `listItem` for rows with leading/trailing elements, subtitles, checkboxes |
| Search with results | `searchInput` | Search bar + filtered list | Has built-in clear button and keyboard handling |
| Bottom floating action | `floatingButton` | Fixed button at bottom of screen | Handles safe area automatically |
| Tabs / screen switcher | `tabController` | Multiple content pages, tab bar | Use with `TabController.TabBar` + `TabController.TabPage` |
| Overlay / bottom sheet | `modal` or `dialog` | Confirmation flows, sheets | `dialog` for simple confirm/cancel; `modal` for custom full content |
| Empty / error state | `stateScreen` | No results, error, offline | Has built-in image + title + CTA slots |
| Loading skeleton | `skeletonView` | Content loading placeholder | Renders shimmer by default |
| Swipeable row | `drawer` | Swipe-to-reveal actions on list items | Wraps any content, exposes action slots |
| Step / multi-page flow | `wizard` | Multi-step onboarding or forms | Manages step state and progress indicator |

---

## DO / DON'T

- **DO** always read `*.api.json` before using a component (batch multiple lookups in one shell call).
- **DO** use modifiers and design tokens from [styling.md](./styling.md) instead of StyleSheet.
- **DO** use `react-native-ui-lib` components instead of creating complex layouts from scratch.
- **DO** wrap screens that contain text inputs with `KeyboardAwareScrollView` from `react-native-ui-lib`.
- **DO** use `react-native` only for layout primitives the library doesn't wrap (`ScrollView`, `FlatList`, `Pressable`).
- **DON'T** import `View`, `Text`, or `Button` from `react-native` — always use the library equivalents.
- **DON'T** look for `.tsx`/`.ts` in node_modules — only `.js` and `.d.ts` exist.
- **DON'T** guess props — always read the API file.
- **DON'T** manually replicate a layout that the library already handles — check the layout-to-component mapping table first.
- **DON'T** use hardcoded hex colors, font sizes, or spacing values — use tokens and presets.

---

## Where to read more

- [styling.md](./styling.md) — Modifiers, spacing presets, color tokens, typography presets, border radius, shadows.
- [component-intelligence.md](./component-intelligence.md) — Intent classification, discovery loop, props triage (Inject vs. Propose), keyboard handling.
- [getting-started.md](./getting-started.md) — Installation, peer deps, ThemeManager setup, skill activation.
- [theming.md](./theming.md) — Custom colors, typography, spacings, per-component overrides.
- **Live demos**: Each `*.api.json` has an `"example"` URL pointing to the demo screen on GitHub.

---

## MANDATORY COMPLIANCE AUDIT (Architect's Note)

After generating code, output a short **Architect's Note** covering these three sections. If the audit reveals a violation, **fix the code before presenting**.

**1. Injected props** — For each unique component type: `[Component] ([Archetype]): [Props] — [why]`.

**2. Proposed enhancements** (max 5) — Props that improve UX/performance but aren't required. Number them so the user can say "Apply 1, 3" or "Apply all".

**3. Compliance checklist** — One line per item, skip if not applicable:
- **Discovery:** APIs verified for [components]. Flag any `⚠️ [AI_UNVERIFIED_API]`.
- **Standards:** 0 hex colors ✅ | `$` tokens preferred over palette ✅ | Modifiers over StyleSheet ✅
- **testIDs:** `[context].[element]` on all interactive elements.
- **Native imports:** [Justify each, e.g., "ScrollView as layout primitive"].
- **Keyboard:** [Wrapper used / Not applicable].

**4. UX alternatives** (skip if single clear pattern)
- **Chosen: [pattern]** — [why it's the best fit]
- Alternatives: [A] — [why not] / [B] — [why not]
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Component Intelligence — Intent Heuristics

## 1. Discovery Loop (MANDATORY)

For each component, run these steps (batch all API lookups into a single shell call — see SKILL.md):

1. **Classify** as **Capturing**, **Performing**, **Displaying**, or **Reporting** — validate against Detection Signals (Section 3).
2. **Lookup** the `.api.json` from `node_modules/react-native-ui-lib/src/components/<componentName>/<componentName>.api.json`. If not found, try `find . -maxdepth 6 -name "<component>.api.json"`. If still missing, add `// ⚠️ [AI_UNVERIFIED_API]` above the component and flag in the Architect's Note.
3. **Extrapolate** all relevant props from the API file.
4. **Triage** each prop:
- **Inject** — omitting it breaks functionality or a mandatory constraint (`testID`, keyboard handling, validation). Include in code and explain in Architect's Note.
- **Propose** — improves UX/performance but not required. List in Architect's Note (max 5).
- **Boundary rule:** If omitting could cause data loss, broken UX, or inaccessibility → Inject. Otherwise → Propose.

---

## 2. Intent Heuristic Guide

*Use these as a starting point. Always identify all relevant props from the discovered API file.*

| Archetype | Functional Goal | Example Props to Find |
|:---|:---|:---|
| **Capturing** | Data collection | `validate`, `validationMessage`, `enableErrors`, `keyboardType`, `onChangeText`, `onChangeValidity` |
| **Performing** | Action triggers | `onPress`, `disabled`, `loading`, `throttleTime`, `activeOpacity` |
| **Displaying** | Persistent content | Design tokens, typography modifiers, `source` (images), `label` |
| **Reporting** | Transient feedback | `visible`, `onDismiss`, `useSafeArea`, `message`, `preset` |

---

## 3. Detection Signals

| Signal in code | Classification |
|---|---|
| `TextField`, `Picker`, `searchInput`, `Checkbox`, variable starts with `set...`, contains `input`, `form`, `value`, `onChange` | Capturing |
| `Button`, `floatingButton`, `listItem` with `onPress`, function starts with `handle...`, `submit`, `navigate`, `toggle` | Performing |
| `Text`, `Avatar`, `Image`, `badge`, `Divider`, rendering static labels, titles, descriptions, formatted data | Displaying |
| `Toast`, `Dialog`, `modal`, `loaderScreen`, `skeletonView`, `progressBar`, variable starts with `is...`, `show...`, `loading`, `error` | Reporting |

---

## 4. Implementation Constraints

- **testID:** Every interactive element. Pattern: `[context].[element]` (e.g., `profileScreen.saveButton`).
- **Import hierarchy:** Always prefer the library. NEVER import `View`, `Text`, or `Button` from `react-native`; use `react-native` only for primitives the library doesn't wrap (`ScrollView`, `FlatList`, `Pressable`).
- **Keyboard handling:** When a screen contains **Capturing** components (text fields, pickers, search inputs), **INJECT a keyboard-aware wrapper** — omitting it breaks usability on mobile keyboards.
- Preferred: `KeyboardAwareScrollView` from `react-native-ui-lib`
- Fallback: `KeyboardAvoidingView` from `react-native` if the layout can't accommodate a scroll wrapper
- If a wrapper cannot be applied, add `// TODO: keyboard-aware wrapper needed` to flag it.
- **Design system:** Use tokens and modifiers from [styling.md](./styling.md). Never hardcode colors, spacing, or font sizes.
- **API-first:** If you haven't read the `.api.json` for a component, you are not allowed to use it. Flag missing lookups with `⚠️ [AI_UNVERIFIED_API]`.

---

## 5. UX Pattern Alternatives

**When to trigger**: Text-prompt generation only. Skip if only one valid pattern exists.

**Steps:**
1. Identify the pattern family from the screen intent.
2. Pick the best fit using available context (API files, screen type, interaction cost).
3. Report chosen pattern + alternatives in Architect's Note Section 4.

**Seed patterns:**

| Pattern family | Default choice | Alternatives |
|:---|:---|:---|
| Multi-select list | `listItem` with `checkbox` | Avatar tap, row `onPress`, trailing icon |
| Destructive action | `Dialog` confirmation | Swipe-to-delete (`drawer`), long-press, `actionSheet` |
| Search / filter | Inline `searchInput` | Header bar, `floatingButton` → modal |
| Single selection | `radioButton` in `listItem` | Row `onPress` + checkmark, `segmentedControl` |
| Form submission | Primary `Button` (bottom) | `floatingButton`, header right action |
| Loading state | `skeletonView` | `loaderScreen`, `progressBar`, spinner overlay |
| Empty state | `stateScreen` | Inline message, illustration + CTA |
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Getting Started

## Installation

```bash
npm install react-native-ui-lib
# or
yarn add react-native-ui-lib
```

### Peer dependencies

```bash
npm install react-native-gesture-handler react-native-reanimated react-native-safe-area-context
```

Follow the setup guides for each peer dependency:
- [react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/docs/fundamentals/installation)
- [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started)
- [react-native-safe-area-context](https://github.com/th3rdwave/react-native-safe-area-context#getting-started)

---

## Basic setup

Call your foundation config before rendering any component — typically in your app entry file:

```typescript
// foundationConfig.ts
import {Colors, Typography, Spacings} from 'react-native-ui-lib';

Colors.loadColors({
primary: '#2364AA',
secondary: '#81C3D7',
});

Typography.loadTypographies({
heading: {fontSize: 28, fontWeight: '700', lineHeight: 36},
body: {fontSize: 16, fontWeight: '400', lineHeight: 24},
});

Spacings.loadSpacings({
page: 20,
card: 16,
});
```

```typescript
// App.tsx
import './foundationConfig'; // must be imported before any uilib component
import React from 'react';
import {View, Text} from 'react-native-ui-lib';

export default function App() {
return (
<View flex padding-page>
<Text heading $textDefault>Hello</Text>
</View>
);
}
```

See [theming.md](./theming.md) for the full ThemeManager API.

---

## Resources

| Resource | Link |
|----------|------|
| Documentation | https://wix.github.io/react-native-ui-lib/ |
| Figma community file | https://www.figma.com/community/file/1379775092983284111/rnui-library |
| GitHub | https://github.com/wix/react-native-ui-lib |
| Discord | https://discord.gg/2eW4g6Z |
| Demo app | https://expo.dev/@vn.chemgio/rnuilib |

---

## How to activate this skill

From your project root (requires `react-native-ui-lib` to be installed):

```bash
node node_modules/react-native-ui-lib/install-skills.js
```

This copies the `uilib-codegen` skill into `.claude/skills/uilib-codegen/` in your project. Restart Claude Code to activate it.

To make it automatic for your team, add to your `package.json`:

```json
{
"scripts": {
"postinstall": "node node_modules/react-native-ui-lib/install-skills.js"
}
}
```
Loading
Loading