diff --git a/.agents/skills/create-ui-components/references/component-architecture.md b/.agents/skills/create-ui-components/references/component-architecture.md new file mode 100644 index 000000000..ce76aaeed --- /dev/null +++ b/.agents/skills/create-ui-components/references/component-architecture.md @@ -0,0 +1,134 @@ + +Component architecture patterns for building composable, accessible, reusable UI in React Native. Follows the components.build specification and Radix composition pattern. + + + +Understand the hierarchy: + +1. **Primitive** - Lowest-level building block providing behavior and accessibility without styling (e.g., Radix UI Primitives) +2. **Component** - Styled, reusable UI unit that adds visual design to primitives (e.g., shadcn/ui components) +3. **Pattern** - Specific composition solving a UI/UX problem (e.g., form validation with inline errors) + + + +**Decision order when building features:** + +1. **Check existing UI components** (in order): + - [React Native Reusables](https://reactnativereusables.com/docs) - UI components + - [React Native Primitives](https://rn-primitives.vercel.app/) - Radix primitives + - [RNR Community Resources](https://github.com/founded-labs/react-native-reusables/blob/main/COMMUNITY_RESOURCES.md) + +2. **Check Expo SDK** - [Expo SDK docs](https://docs.expo.dev/versions/latest/) for native APIs + +3. **Only then** consider third-party libraries or custom components. + + + + + +- **Children** (implicit slot): JSX between opening/closing tags +- **Named slots**: Props like `icon`, `footer`, or `` subcomponents +- **Slot forwarding**: Pass DOM attributes/className/refs through to underlying element + + + +Use when parent must own data/behavior but consumer controls markup: + +```tsx + + {(item) => } + +``` + + + +Use separate component imports to compose complex UI (shadcn-style): + +```tsx +import { + Card, + CardHeader, + CardContent, + CardFooter +} from '@/components/ui/card'; + + + Title + Body + Actions +; +``` + + + +- **Controlled**: Value driven by props, emits `onChange` (source of truth is parent) +- **Uncontrolled**: Holds internal state, may expose `defaultValue` and imperative reset +- Many inputs should support both patterns + + + +Use `asChild` prop to render as a different element: + +```tsx + +``` + +Renders as `` instead of `