npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@compsych/mobile-ui

v1.0.32

Published

ComPsych React Native Design System — 19 mobile UI components with self-contained design tokens

Downloads

1,593

Readme

ComPsych Design System — React Native

A React Native component library built directly from the ComPsych Figma Design System, using the four-tier token architecture. All 17 components are pixel-accurate implementations synchronized with Figma.


Getting Started

npm install
npx expo start

Token System

All components consume sys.* tokens exclusively — never raw values.

import { sys } from '@/components/ds/tokens';
const { colorRoles: cr, dimensions: dim, typeScale: ts } = sys;

Components


Alert

Version: 1.0.0

Inline feedback banner for status, warnings, errors, and success messages. Supports a title, icon, action button, and dismiss control.

Alert

Import

import { Alert } from '@/components/ds/Alert';

Component File: components/ds/Alert.tsx

Variants

There are six alert variants covering the full range of feedback contexts.

<Alert variant="informative" description="Tips, help, or guidance." />
<Alert variant="warning"     description="Your session will expire in 5 minutes." />
<Alert variant="danger"      description="Failed to save changes." />
<Alert variant="positive"    description="Changes saved successfully." />

With Action

An optional action button prompts the user to take a next step.

<Alert
  variant="informative"
  title="New feature available"
  description="Update the app to access the latest tools."
  actionLabel="Update now"
  onAction={handleUpdate}
/>

Dismissible

Add a dismiss button by setting dismissible to true.

<Alert variant="danger" description="Failed to save." dismissible onDismiss={() => setVisible(false)} />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | variant | 'default' \| 'elevated' \| 'informative' \| 'warning' \| 'positive' \| 'danger' | 'default' | Color scheme and icon | | size | 'sm' \| 'lg' | 'lg' | lg shows a bold title; sm is compact | | description | string | — | Required. Body text | | title | string | — | Bold heading (lg size only) | | hideIcon | boolean | false | Removes the leading icon | | actionLabel | string | — | Label for the optional action button | | onAction | () => void | — | Action button handler | | dismissible | boolean | false | Shows a × dismiss button | | onDismiss | () => void | — | Dismiss button handler |


Avatar

Version: 1.0.0

Circular user representation — text initials, photo, or icon. Supports a presence badge and activity ring.

Avatar

Import

import { Avatar } from '@/components/ds/Avatar';

Component File: components/ds/Avatar.tsx

Sizes

Avatar can be rendered in seven sizes from extra-small to triple-extra-large.

<Avatar variant="text" initials="CP" size="xs" />
<Avatar variant="text" initials="CP" size="md" />
<Avatar variant="text" initials="CP" size="xl" />

Image Avatar

Display a user's photo by providing an image source.

<Avatar variant="image" source={{ uri: 'https://example.com/photo.jpg' }} size="lg" activityRing />

Letter Avatar

Render up to two initials when no photo is available.

<Avatar variant="text" initials="JD" size="md" />
<Avatar variant="text" initials="AB" size="lg" />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | variant | 'text' \| 'image' \| 'icon' | 'text' | Content type | | size | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| '3xl' | 'md' | Circle diameter | | initials | string | — | Up to 2 characters (text variant) | | source | ImageSourcePropType | — | Photo source (image variant) | | activityRing | boolean | false | Renders a coloured ring around the circle | | presenceBadge | boolean | false | Renders a shield-check badge at bottom-right |


Badge

Version: 1.0.0

Small status indicator as a pill, dot, or count. Used on icons and list items to show notification states.

Badge

Import

import { Badge } from '@/components/ds/Badge';

Component File: components/ds/Badge.tsx

Styles

Badge supports six visual styles covering neutral, semantic, and dot presentations.

<Badge label={5}   badgeStyle="filled"   />
<Badge label="New" badgeStyle="positive" />
<Badge label="99+" badgeStyle="danger"   />
<Badge label={3}   badgeStyle="tonal"    />
<Badge             badgeStyle="dot"      />

Sizes

Badge can be rendered in three sizes.

<Badge label={5} size="sm" />
<Badge label={5} size="md" />
<Badge label={5} size="lg" />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | label | number \| string | — | Text or count inside the badge | | size | 'sm' \| 'md' \| 'lg' | 'md' | Controls diameter and font size | | badgeStyle | 'filled' \| 'positive' \| 'danger' \| 'elevated' \| 'tonal' \| 'dot' | 'filled' | Color scheme and shape |


Breadcrumb

Version: 1.0.0

Horizontal scrollable navigation trail with / dividers. The last item always renders as the current page.

Breadcrumb

Import

import { Breadcrumb } from '@/components/ds/Breadcrumb';

Component File: components/ds/Breadcrumb.tsx

Basic

Provide an ordered array of items. The last item is always treated as the current page.

<Breadcrumb
  items={[
    { isHome: true, onPress: goHome },
    { label: 'Settings', onPress: goSettings },
    { label: 'Profile' },
  ]}
/>

With Overflow

Use isOverflow: true to collapse middle crumbs into an ellipsis.

<Breadcrumb
  items={[
    { isHome: true, onPress: goHome },
    { isOverflow: true, onPress: expandCrumbs },
    { label: 'Current Page' },
  ]}
/>

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | items | BreadcrumbItem[] | — | Required. Ordered crumb items | | size | 'sm' \| 'lg' | 'lg' | Font size and vertical padding |

BreadcrumbItem

| Field | Type | Description | |-------|------|-------------| | label | string | Display text | | isHome | boolean | Renders the home icon instead of text | | isOverflow | boolean | Renders for collapsed middle crumbs | | disabled | boolean | Reduces opacity; non-interactive | | onPress | () => void | Omit for the current/last crumb |


Button

Version: 1.0.0

Buttons are touchable elements used to trigger actions. They support seven visual variants, four sizes, leading and trailing icons, a loading state, and full-width layout.

Button

Import

import { Button } from '@/components/ds/Button';

Component File: components/ds/Button.tsx

Variants

There are solid, outline, text, tonal, elevated, danger, and danger-outlined button types.

<Button label="Filled"   variant="filled"   onPress={handlePress} />
<Button label="Tonal"    variant="tonal"    onPress={handlePress} />
<Button label="Outlined" variant="outlined" onPress={handlePress} />
<Button label="Text"     variant="text"     onPress={handlePress} />
<Button label="Danger"   variant="danger"   onPress={handlePress} />

Size

Button can be small, medium, large, or extra-large.

<Button label="Small"  size="sm" onPress={handlePress} />
<Button label="Medium" size="md" onPress={handlePress} />
<Button label="Large"  size="lg" onPress={handlePress} />

Disabled

Disabled buttons reduce opacity and ignore press interactions.

<Button label="Filled"   variant="filled"   disabled />
<Button label="Outlined" variant="outlined" disabled />
<Button label="Text"     variant="text"     disabled />

Icon Button

Can contain a leading or trailing icon, or be rendered as a square icon-only button.

<Button label="Delete" variant="danger" leadingIcon={<Ionicons name="trash-outline" size={16} />} onPress={handleDelete} />

Loading Spinner

Use the loading prop to replace the label with an activity indicator.

<Button label="Saving…" loading />
<Button label="Saving…" loading variant="outlined" />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | label | string | — | Required. Button text | | variant | 'filled' \| 'tonal' \| 'outlined' \| 'elevated' \| 'text' \| 'danger' \| 'danger-outlined' | 'filled' | Visual style | | size | 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Height and padding | | disabled | boolean | false | Disables interaction and reduces opacity | | loading | boolean | false | Shows ActivityIndicator in place of label | | fullWidth | boolean | false | Stretches to fill the parent | | iconOnly | boolean | false | Square layout for single icons | | leadingIcon | React.ReactNode | — | Icon before the label | | trailingIcon | React.ReactNode | — | Icon after the label | | onPress | () => void | — | Press handler |


Card

Version: 1.0.0

Surface container for grouping related content. Supports three visual variants, four padding sizes, interactive press states, and a current/selected highlight.

Import

import { Card } from '@/components/ds/Card';

Component File: components/ds/Card.tsx

Variants

There are outlined, filled, and gradient card types.

<Card variant="outlined"><Text>Outlined card</Text></Card>
<Card variant="filled"><Text>Filled card</Text></Card>
<Card variant="gradient"><Text>Gradient card</Text></Card>

Interactive

Set interactive to enable press feedback and wrap the card in a Pressable.

<Card interactive onPress={handleCardPress}><Text>Tap me</Text></Card>

Current State

The current prop applies a primary-colored border to indicate the selected card.

<Card interactive current onPress={handlePress}><Text>Selected card</Text></Card>

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | variant | 'outlined' \| 'filled' \| 'gradient' | 'outlined' | Visual treatment | | size | 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Inner padding | | interactive | boolean | false | Enables press feedback | | disabled | boolean | false | Reduces opacity | | current | boolean | false | Primary border (selected state) | | fullWidth | boolean | false | Fills parent width | | onPress | () => void | — | Press handler (requires interactive) | | children | React.ReactNode | — | Card content |


Checkbox

Version: 1.0.0

Binary or indeterminate selection control. Supports controlled and uncontrolled usage.

Checkbox

Import

import { Checkbox } from '@/components/ds/Checkbox';

Component File: components/ds/Checkbox.tsx

States

Checkbox can be unchecked, checked, indeterminate, or disabled.

<Checkbox defaultChecked={false} onValueChange={console.log} />
<Checkbox defaultChecked={true}  onValueChange={console.log} />
<Checkbox checked="indeterminate" onValueChange={handleChange} />
<Checkbox disabled />

Controlled

Use the checked prop with onValueChange for controlled usage.

const [checked, setChecked] = useState(false);
<Checkbox checked={checked} onValueChange={setChecked} />

Sizes

Checkbox supports medium (default) and small sizes.

<Checkbox size="md" defaultChecked />
<Checkbox size="sm" defaultChecked />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | checked | boolean \| 'indeterminate' | — | Controlled state | | defaultChecked | boolean | false | Initial uncontrolled state | | onValueChange | (value: boolean \| 'indeterminate') => void | — | Change handler | | size | 'sm' \| 'md' | 'md' | Hit area and box size | | disabled | boolean | false | Disables interaction | | accessibilityLabel | string | — | Screen-reader label |


Chip

Version: 1.0.0

Compact label pill for status, category, or filter display. Supports a leading icon, dismiss button, and badge count.

Chip

Import

import { Chip } from '@/components/ds/Chip';

Component File: components/ds/Chip.tsx

Colors

Chip supports neutral, informative, positive, danger, and warning semantic colors.

<Chip label="Neutral"   usage="neutral"     />
<Chip label="Info"      usage="informative" />
<Chip label="Completed" usage="positive"    />
<Chip label="Overdue"   usage="danger"      />
<Chip label="Pending"   usage="warning"     />

Sizes

Chip can be rendered in four sizes.

<Chip label="Small"  size="sm" />
<Chip label="Medium" size="md" />
<Chip label="Large"  size="lg" />

Dismissible

Add a dismiss button at the trailing end using the dismissible prop.

<Chip label="Filter" dismissible onDismiss={handleDismiss} />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | label | string | — | Required. Chip text | | size | 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Height and font | | usage | 'neutral' \| 'informative' \| 'positive' \| 'danger' \| 'warning' | 'neutral' | Semantic color | | leadingIcon | React.ReactNode | — | Icon before the label | | dismissible | boolean | false | Shows a × button | | onDismiss | () => void | — | Called when dismissed | | badge | number \| string | — | Trailing count or label |


Divider

Version: 1.0.0

Decorative separator — horizontal or vertical, thin or thick, solid or dashed.

Divider

Import

import { Divider } from '@/components/ds/Divider';

Component File: components/ds/Divider.tsx

Horizontal

A horizontal divider stretches to fill its parent width and is the default orientation.

<Divider />
<Divider weight="thick" />

Vertical

A vertical divider fills its parent height and is used as a separator inside a row layout.

<View style={{ flexDirection: 'row', height: 40 }}>
  <Text>Left</Text>
  <Divider variant="vertical" />
  <Text>Right</Text>
</View>

Dashed

The dashed style is used for section breaks or to indicate optional content areas.

<Divider dashed />
<Divider weight="thick" dashed />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | variant | 'horizontal' \| 'vertical' | 'horizontal' | Orientation | | weight | 'thin' \| 'thick' | 'thin' | 1px or 2px line | | dashed | boolean | false | Dashed line pattern |


EmptyState

Version: 1.0.0

Full-panel placeholder for empty screens. Supports an icon circle or illustrated card-collage graphic with an optional action button.

EmptyState

Import

import { EmptyState } from '@/components/ds/EmptyState';

Component File: components/ds/EmptyState.tsx

Icon Style

The default style renders an icon inside a circular container above the title and description.

<EmptyState
  title="No messages"
  description="When you receive messages they will appear here."
/>

Illustration Style

The illustration style renders a pure-View card collage — no image assets required.

<EmptyState style="illustration" title="Nothing here yet" description="Get started by creating your first item." />

With Action

An optional action button prompts the user to take a next step.

<EmptyState title="No results" description="Try adjusting your filters." actionLabel="Clear filters" onAction={clearFilters} />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | style | 'icon' \| 'illustration' | 'icon' | Graphic treatment | | viewport | 'desktop' \| 'mobile' | 'mobile' | Token set for type scale and sizing | | title | string | 'No results' | Heading text | | description | string | 'Description if needed' | Body copy | | showDescription | boolean | true | Hides description when false | | icon | React.ReactNode | — | Custom icon in the circle | | actionLabel | string | — | Action button label | | onAction | () => void | — | Action press handler |


Input

Version: 1.0.0

Single-line text field with floating label, helper/error text, and leading/trailing icon slots.

Input

Import

import { Input } from '@/components/ds/Input';

Component File: components/ds/Input.tsx

Basic

A simple text field with a floating label and placeholder.

<Input label="Email" placeholder="[email protected]" />

Sizes

Input supports three sizes that control height, padding, and font scale.

<Input size="sm" label="Small"  placeholder="Small field"  />
<Input size="md" label="Medium" placeholder="Medium field" />
<Input size="lg" label="Large"  placeholder="Large field"  />

Error State

Use invalid and errorText to communicate a validation error.

<Input label="Username" invalid={!!errors.username} errorText={errors.username} />

With Icons

Leading and trailing icons can be placed inside the field.

<Input label="Search" leadingIcon={<Ionicons name="search" size={20} />} />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | size | 'sm' \| 'md' \| 'lg' | 'md' | Height, padding, and font | | label | string | — | Floating label | | helperText | string | — | Hint text below the field | | errorText | string | — | Error message; replaces helperText | | invalid | boolean | false | Red border and error color | | leadingIcon | React.ReactNode | — | Icon at the leading edge | | trailingIcon | React.ReactNode | — | Icon at the trailing edge |


Pagination

Version: 1.0.0

Page navigation with smart truncation. Supports numbered layout or compact prev/next-only mode.

Pagination

Import

import { Pagination } from '@/components/ds/Pagination';

Component File: components/ds/Pagination.tsx

Standard

The default layout renders numbered page buttons with prev and next arrows inside a pill container.

const [page, setPage] = useState(1);
<Pagination totalPages={12} currentPage={page} onPageChange={setPage} />

Compact

Compact mode renders only prev/next arrows — ideal for narrow mobile screens.

<Pagination compact totalPages={20} currentPage={page} onPageChange={setPage} />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | totalPages | number | — | Required. Total pages | | currentPage | number | — | Required. Active page (1-based) | | onPageChange | (page: number) => void | — | Required. Page change handler | | size | 'sm' \| 'lg' | 'lg' | lg inside a pill; sm bare | | siblingCount | number | 1 | Pages shown on each side before | | compact | boolean | false | Prev/next only — no page numbers |


ProgressTracker

Version: 1.0.0

Multi-step progress indicator with labelled steps and per-step progress bars.

ProgressTracker

Import

import { ProgressTracker } from '@/components/ds/ProgressTracker';

Component File: components/ds/ProgressTracker.tsx

Basic

Provide an array of steps with a label and state for each.

<ProgressTracker
  steps={[
    { label: 'Personal info', state: 'completed' },
    { label: 'Address',       state: 'completed' },
    { label: 'Review',        state: 'active'    },
    { label: 'Submit',        state: 'pending'   },
  ]}
/>

Without Labels

Set showLabels to false for a compact bar-only indicator.

<ProgressTracker showLabels={false} steps={steps} />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | steps | TrackerStep[] | — | Required. Step descriptors | | size | 'sm' \| 'lg' | 'lg' | Label font size | | showLabels | boolean | true | Show step labels below bars |

TrackerStep

| Field | Type | Description | |-------|------|-------------| | label | string | Step display name | | state | 'completed' \| 'active' \| 'pending' | 100% / 25% / 0% fill |


RadioButton

Version: 1.0.0

Single-selection control. Use within a group where only one option can be selected at a time.

RadioButton

Import

import { RadioButton } from '@/components/ds/RadioButton';

Component File: components/ds/RadioButton.tsx

States

RadioButton can be unselected, selected, or disabled.

<RadioButton defaultSelected={false} />
<RadioButton defaultSelected={true}  />
<RadioButton disabled />

In a Group

Manage selection state externally and pass selected and onValueChange to each option.

const [selected, setSelected] = useState<string>('a');

<RadioButton selected={selected === 'a'} onValueChange={() => setSelected('a')} accessibilityLabel="Option A" />
<RadioButton selected={selected === 'b'} onValueChange={() => setSelected('b')} accessibilityLabel="Option B" />
<RadioButton selected={selected === 'c'} onValueChange={() => setSelected('c')} disabled />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | selected | boolean | — | Controlled state | | defaultSelected | boolean | false | Initial uncontrolled state | | onValueChange | (value: boolean) => void | — | Change handler | | size | 'sm' \| 'md' | 'md' | Hit area and ring size | | disabled | boolean | false | Disables interaction | | accessibilityLabel | string | — | Screen-reader label |


Slider

Version: 1.0.0

Continuous value selector with a draggable thumb. Tap anywhere on the track to jump; drag to adjust. Resists gesture theft from parent ScrollView.

Slider

Import

import { Slider } from '@/components/ds/Slider';

Component File: components/ds/Slider.tsx

Basic

A simple uncontrolled slider with default min (0) and max (100).

<Slider onSlidingComplete={(v) => console.log(v)} />

With Label

Use the label prop to render a descriptor above the track.

const [volume, setVolume] = useState(50);
<Slider label="Volume" value={volume} onValueChange={setVolume} />

Step

Use the step prop to snap the thumb to fixed intervals.

<Slider defaultValue={0} min={0} max={100} step={10} showMinMax />

Disabled

A disabled slider reduces opacity and ignores interaction.

<Slider value={40} disabled label="Locked setting" />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | value | number | — | Controlled value | | defaultValue | number | min | Initial uncontrolled value | | min | number | 0 | Minimum | | max | number | 100 | Maximum | | step | number | 1 | Snap interval | | onValueChange | (value: number) => void | — | Called while dragging | | onSlidingComplete | (value: number) => void | — | Called on release | | label | string | — | Label above the track | | showMinMax | boolean | true | Min/max labels on each side | | disabled | boolean | false | Disables interaction |


Switch

Version: 1.0.0

Animated binary toggle with 150ms thumb slide and background color transition. Supports controlled and uncontrolled usage.

Switch

Import

import { Switch } from '@/components/ds/Switch';

Component File: components/ds/Switch.tsx

On and Off

Switch can be toggled between on and off states.

<Switch defaultValue={false} onValueChange={console.log} />
<Switch defaultValue={true}  onValueChange={console.log} />

Controlled

Use the value prop with onValueChange for controlled usage.

const [enabled, setEnabled] = useState(false);
<Switch value={enabled} onValueChange={setEnabled} accessibilityLabel="Notifications" />

Disabled

Disabled switches reduce opacity and ignore press interactions.

<Switch value={false} disabled />
<Switch value={true}  disabled />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | value | boolean | — | Controlled value | | defaultValue | boolean | false | Initial uncontrolled value | | onValueChange | (value: boolean) => void | — | Toggle handler | | disabled | boolean | false | Disables interaction | | accessibilityLabel | string | — | Screen-reader label |


Tooltip

Version: 1.0.0

Short contextual label with a directional arrow. Use to clarify icon buttons, abbreviations, or truncated text.

Tooltip

Import

import { Tooltip } from '@/components/ds/Tooltip';

Component File: components/ds/Tooltip.tsx

Filled

The filled variant uses a dark inverse surface — the default and most common style.

<Tooltip text="More options" />
<Tooltip text="Delete item" direction="bottom" />

Elevated

The elevated variant uses a white surface with a border and shadow — for use on dark backgrounds.

<Tooltip text="Save your work" variant="elevated" direction="bottom" />

Directions

The direction prop describes where the target is relative to the bubble, which determines where the arrow is drawn.

<Tooltip text="No arrow"    direction="none"   />
<Tooltip text="Arrow up"    direction="top"    />
<Tooltip text="Arrow down"  direction="bottom" />
<Tooltip text="Arrow left"  direction="left"   />
<Tooltip text="Arrow right" direction="right"  />

Props

| Name | Type | Default | Description | |------|------|---------|-------------| | text | string | — | Required. Tooltip content | | variant | 'filled' \| 'elevated' | 'filled' | Dark inverse or white elevated | | direction | 'none' \| 'top' \| 'bottom' \| 'left' \| 'right' | 'none' | Where the target is relative to the bubble |


Token System

All components reference only sys.* tokens via:

import { sys } from '@/components/ds/tokens';
const { colorRoles: cr, dimensions: dim, typeScale: ts } = sys;

Never apply core.*, product.*, or brand.* tokens directly in UI — they are internal plumbing and will not respond to theme or brand changes.


Project Structure

components/ds/          All 17 DS component implementations
components/ds/tokens.ts sys.* token bridge from @javierkonpo/design-system
app/(tabs)/index.tsx    Component gallery / showcase screen
docs/
  components.md         Full component API reference (RNEUI-style)
  Components.docx       Word document with Figma screenshots
  components.pdf        PDF reference with Figma screenshots
  images/               Figma component screenshots